Java JDBC基本使用方法详解

本文实例讲述了Java JDBC基本使用方法。分享给大家供大家参考,具体如下:

本文内容:

  • 什么是JDBC
  • JDBC的使用
  • 事务
  • 连接池
  • DbUtils

首发日期:2018-05-27

修改:

  1. 2018-07-19:增加了事务、连接池、DBUtils
  2. 2018-07-27:对特别情况下的事务进行了描述。对DBUtils增加了关闭资源、关闭流。连接池发现漏了释放连接。

什么是JDBC:

  • JDBC全称Java Database Connectivity
  • JDBC可以通过载入不同的数据库的“驱动程序”而与不同的数据库进行连接。

JDBC的优点:

  • 使用的驱动不同,即可连接不同的数据库。
  • 使用同一套操作来操作不同的数据库
  • 如果每一个数据库java都制订一套连接方式,那么当不同的数据库更新的时候,java也需要更新自己的代码,而使用jdbc,使用同一套代码来操作,使用不同的驱动程序(驱动程序由数据库厂商提供)来连接,这使得可以连接不同的数据库。

JDBC的使用:

导入对应数据库的驱动类:

  • 1.在对应的数据库厂商网站获取对应的jar包
  • 2.将对应的jar包添加到引用。
    • 在eclipse中可以将jar包导入一个文件夹后,右键Build Path -> add to path就可以将jar包添加到当前项目引用的库里面。

加载驱动:

PS:

  • 在上面的forName中,执行了注册驱动,注册驱动这个代码被定义在驱动类的静态代码块中。
  • 对于一些新手,使用的方法可能是,对于这种情况,那么他可以使用driver或DriverManager.getConnection来获取数据库连接对象;而对于另外一些新手,他们可能会使用,然后再通过DriverManager.getConnection来获取数据库连接对象。但本质上,这是一种浪费,因为静态代码块中已经静态生成了一个驱动对象并使用DriverManager.registerDriver注册了,所以上面两种都是浪费。使用forName后,可以使用DriverManager.getConnection来获取数据库连接对象。

获取连接:

  • 在考虑使用forName节省资源后,下面介绍的获取连接的方法使用的是DriverManager.getConnection
  • getConnection需要参数
    • url:定义了连接的数据库的路径

      • jdbc协议:数据库子协议:主机[:端口][/连接的数据库]  【[]代表可选的】
      • 例如:jdbc:mysql://localhost:3306/test
    • 配置流Properties:定义了连接数据库的方式,一般至少包含user和password
    • 不使用配置流时,传入user和password
    • 如果使用匿名登录,则只传入url

执行SQL语句:

JDBC执行SQL语句的方式主要有三种:

1.使用Statement执行sql语句

2.使用PreparedStatement执行sql语句

3.使用CallableStatement执行sql语句

上面的Statement、PerPareStatement、Callalestatement都可以使用连接对象来获取。

  • 使用Statement执行语句

    • Statement对象的获取可以使用createStatement()来获取
    • 获取Statement对象后,对于查询类的sql语句使用:executeQuery(sql),sql是一个字符串sql语句,返回结果是一个结果集【如果获取结果看下面的结果部分】
    • 对于更新类(插入、修改、删除、更新)的语句使用:executeUpdate(sql),sql是一个字符串sql语句,返回结果是一个整数(受影响的行数)

  • 使用PreparedStatement执行语句

    • PreparedStatement对象的获取可以使用prepareStatement(sql)来获取,注意的是需要传入一条sql语句
    • PreparedStatement的功能类似Statement,但不同的是PreparedStatement可以使用占位符,它是由占位符标识需要输入数据的位置,然后再逐一填入数据。当然,PreparedStatement也可以执行没有占位符的sql语句
      • 使用占位符后,使用setStringsetInt等方法来设置每一位的数据。【有各种对应数据类型的设置方法,比如还有setFloat

        • setXXX方法中,第一个参数是位置,第二个是数据
    • 获取Statement对象后,对于查询类的sql语句使用:executeQuery(),返回结果是一个结果集【如果获取结果看下面的结果部分】
    • 对于更新类(插入、修改、删除、更新)的语句使用:executeUpdate(),返回结果是一个整数(受影响的行数)
    • 补充:
      • 对于有sql缓存池的数据库,PreparedStatement的效率要高于Statement【有兴趣的自查】

  • 使用CallableStatement执行语句

    • CallableStatement主要用来调用存储过程
    • 对于输出参数,需要使用registerOutParameter注册,第一个参数是位置,第二个参数是参数类型(使用Types.xxx)
    • 注册之后,想要获取输出参数,可以使用CallableStatement对象自身的getXXX方法来获取

定义的存储过程示例:

使用:

获取返回:

  • 返回结果是一个结果集,它有一个光标指向结果的每一行,最开始它不指向结果,第一次执行next()后,它指向第一行结果,继续执行next(),他会继续指向下一行。next的返回结果是布尔值,它可以用来判断是否有下一行。

    • 对于每一行结果,可以使用getXXX方法(参照下面)来获取某一列的结果,getXXX方法的参数可以为字段名,也可以为索引号(从1开始)

关闭连接:

  • 后开启的需要先关闭,Statement、Connection、ResultSet都是需要关闭的
  • 注意:关闭之前需要留心检查是否为null


事务

不了解事务是什么的,可以看一下我的另外一篇博文:mysql之事务管理

设置事务管理:

连接对象.setAutoCommit(boolean)【当参数为true时,代表允许自动提交(事务管理是关闭的,每一条命令都会自动提交);当为false时,代表不允许自动提交,命令会在执行commit之后再统一提交(开启事务管理的)】

提交事务:

连接对象.commit()

回滚事务:

连接对象.rollback()

例子:

以银行转账为例,张三转给李四100元,执行事务后,如果运行出错将不会提交数据到数据库:

补充:

  • 有些时候,在开发中是不会把两个操作放到一个地方的(在Javaweb中开发中存在service层和dao层。可以这么说,servlet是饭店前台,service层就是包厢里点菜的服务员(客户需要什么菜,他负责告诉后厨),dao层就是真正做菜的后厨(dao层通常是数据库方面的操作)。服务员一次性把需要的菜告诉后厨),这样耦合性较高,通常需要把它们放到单独的地方去(就好比一个大厨做好几样菜会很忙,通常都会分工好),比如加钱是一个函数,减钱是一个函数。把他们分开后,两个函数之间的Connection不同的话,就会无法统一进行事务管理。通常有两个解决方法:1.把同一个Connection对象传给这两个参数。2.利用Threadlocal类,把Connection对象存进去,两个要用的时候再取,取的是同一个对象。【这里可能不容易理解,只是做个提醒,可以不理解。】

数据库连接池

  • 连接池的意义就是提前创建连接,避免需要使用时再申请连接造成的重复申请资源造成的浪费。
  • 连接池负责在需要的时候分发连接,使用者释放连接时需要放回到连接池中。

连接池可以自定义,当然常用的一般都是选择采用第三方开源的连接池,想了解如何自定义连接池的可以自查,下面给出的是两个常用的连接池的用法。

DBCP:

首先,使用DBCP连接池需要导入包:commons-dbcp.jar和commons-pool.jar【如果需要日志功能,还需要commons-logging-1.2.jar ,这里不讲述】

DBCP根据配置方式,下面给出两种使用方法:

1.手动配置法:

  1. 创建BasicDataSource对象: BasicDataSource dataSource = new BasicDataSource();
  2. 配置BasicDataSource对象:(少用)调用对应函数配置,例如dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  3. 得到连接对象:Connection conn = ds.getConnection();
  4. 操作数据库。(得到数据库连接对象后,就可以像以前一样去操作数据库了)

2.配置文件配置法:

  1. 创建BasicDataSourceFactory对象:BasicDataSourceFactory factory = new BasicDataSourceFactory();
  2. 利用BasicDataSourceFactory对象的createDataSource函数读取配置文件配置DataSource对象:DataSource dataSource = factory.createDataSource(properties);【配置文件能用哪些参数可以参考这个文档:http://commons.apache.org/proper/commons-dbcp/configuration.html
  3. 得到连接对象:Connection conn = ds.getConnection();
  4. 操作数据库。(得到数据库连接对象后,就可以像以前一样去操作数据库了)

当使用完毕后,像往常一样调用close关闭连接即可【这里通过连接池获取的Connection对象已经封装过了,使用close函数相当于放回连接池中】

常用的dbcp.properties的配置信息:

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000

#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

C3P0:

首先,使用C3P0连接池需要导入包:c3p0-0.9.1.2.jar【还有扩展包如c3p0-oracle-thin-extras-0.9.1.2.jar,这里不讲】

手动配置法:

  1. 创建ComboPooledDataSource对象:ComboPooledDataSource dataSource = new ComboPooledDataSource();
  2. 调用对应函数配置对应属性

配置文件配置法:

  1. 创建配置文件,c3p0的配置文件名字是固定的,必须是c3p0.properties或c3p0-config.xml,否则识别不了。配置文件的写法看下面【配置文件存储的位置:1.能在classpath中获取到的目录(比如工程的src目录)、2.WEB-INF/classes、3.某些类似功能的路径】
  2. 创建ComboPooledDataSource对象【如果有配置文件,那么会读取配置文件来配置ComboPooledDataSource对象】
  3. 获取连接
  4. 执行sql语句

当你使用完后,Connection对象调用close函数,就会把连接释放会连接池中【这里通过连接池获取的Connection对象已经封装过了,使用close函数相当于放回连接池中】

配置文件c3p0-config.xml的写法:

<c3p0-config>
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/bank</property>
    <property name="user">root</property>
    <property name="password">123456</property>
    <!-- 下面的是额外的配置,如最大连接数,连接池大小。。
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property> <property name="maxStatements">200</property>
    -->

  </default-config>
  <!-- 上面是默认的,如果不给参数,默认是上面的; -->
  <!-- 下面的是单独的,在创建对象时把下面name中的那个值赋给对象的构造函数,那么将使用下面的配置 -->
  <named-config name="student">
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/student</property>
    <property name="user">root</property>
    <property name="password">123456</property>
  </named-config>

</c3p0-config>

配置文件c3p0.properties的写法:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost/bank
c3p0.user=root
c3p0.password=123456

想更详细的了解c3p0,可以参考官方文档:https://www.mchange.com/projects/c3p0/index.html

怎样去配置c3p0连接池,什么英语代表什么意思,具体请参考:https://www.mchange.com/projects/c3p0/index.html

补充:

  • 事实上DBCP和c3p0还有不少使用方法,上面只讲解了常用的。

DbUtils

  • DbUtils是apache旗下的一个操作数据库的工具
  • DbUtils可以简化我们对数据库的CRUD操作,一个常用功能是能把查询到的数据自动封装起来,而不再需要我们操作ResultSet。

要想使用DBUtils,首先要导入包:commons-dbutils-1.4.jar

增、删、改:

  • DbUtils的写操作是一类,读操作是一类
  • 写操作主要是调用update函数

1.新建QueryRunner对象【如果传入一个连接池对象,那么后续操作的数据库连接就是这个连接池的连接;如果不设置,那么执行update时要给一个连接对象】

2.调用update函数.

update()有多个重构函数,可以依据情况来选择使用:

查:

  • 写操作主要是调用query函数
  • 查询操作的同时,可以配合javabean把数据封装起来(数据返回的数据在ResultSet中,传入一个ResultSetHandler对象以操作ResultSet中的数据)。
  • 如下图所示,ResultSetHandler对象是必须的参数,所以说,查出数据但不处理的操作不要使用DBUtils。

自定义操作数据:调用ResultSetHandler的匿名实现类中的handle方法处理resultset的数据

手动封装:调用ResultSetHandler的实现类中的handle方法来讲resultset的数据封装到对象中

自动封装数据:根据传入的ResultSetHandler对象来处理数据

常见ResultSetHandler实现类:

  • BeanHandler :把数据库中的一行数据根据变量名自动封装到对象中;如果查询语句返回多条结果,将ResultSet中第一行的数据根据变量名自动封装到对象中
  • BeanListHandler:把数据库中的多行数据根据变量名自动封装到对象中,并存储到List中返回。所以返回结果是一个含有多个bean对象的list
  • ScalarHandler :将ResultSet中一条记录的某一列的数据存成Object,返回值是一个Object。不给参数时默认是第一列的值,参数可以给列数,也可以给字段名 【可以用于统计函数等返回一个值的情况】
  • ArrayHandler :把一条记录的所有数据存储到一个数组中,第一列的数据在数组的第一个位置。
  • ArrayListHandler:与ArrayHandler功能类似,但可以返回包含多个数组的list了。

补充:对于封装成对象的,需要提供一个bean类.class参数,这是为了能创建对象

关闭流、释放资源:

DbUtils中提供了可以关闭各种资源的静态方法

补充:

  • 由于DbUtils支持传入一个Connection对象,所以在一些比如转账的事务管理中,若是加钱和减钱在不同函数中,DbUtils可以借助传入同一个Connection对象来实现事务管理。

更多关于java相关内容感兴趣的读者可查看本站专题:《Java使用JDBC操作数据库技巧总结》、《Java+MySQL数据库程序设计总结》、《Java数据结构与算法教程》、《Java文件与目录操作技巧汇总》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • JAVA使用JDBC技术操作SqlServer数据库实例代码

    JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序. JDBC并不能直接访问数据库,需要借助于数据库厂商提供的JDBC驱动程序. 数据库连接 如果要在Java访问数据库,首先要加载一个数据库驱动,数据库驱动只需要在第一次访问时加载一次.然后再每次访问

  • 基于Java回顾之JDBC的使用详解

    尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访问的基础,掌握它对于我们理解Java的数据操作流程很有帮助. JDBC的全称是Java Database Connectivity. JDBC对数据库进行操作的流程:•连接数据库•发送数据请求,即传统的CRUD指令•返回操作结果集JDBC中常用的对象包括:•ConnectionManager•Connection•Statement•CallableStat

  • Java开发Oracle数据库连接JDBC Thin Driver 的三种方法

    Oracle的jdbc驱动三种主要分类: 1.JDBC OCI: oci是oracle call interface的缩写,此驱动类似于传统的ODBC 驱动.因为它需要Oracle Call Interface and Net8,所以它需要在运行使用此驱动的JAVA程序的机器上安装客户端软件,其实主要是用到orcale客户端里以dll方式提供的oci和服务器配置. 2.JDBC Thin: thin是for thin client的意思,这种驱动一般用在运行在WEB浏览器中的JAVA程序.它不是

  • Java加载JDBC驱动程序实例详解

    本文实例说明了Java加载JDBC驱动程序的方法,运行本文实例代码后,如果连接成功就会显示如下一条语句:sun.jdbc.odbc.JdbcOdbcDriver@6ec12,如果连接不成功,则显示加载数据库驱动程序出现异常. Java加载JDBC的实现方法: 通过调用Class.forName()方法可以显式地加载一个驱动程序.该方法的入口参数为要加载的驱动程序.例如:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")语句加载了SUN 公司开发的

  • Java使用JDBC连接数据库的实现方法

    本文实例讲述了Java使用JDBC连接数据库的实现方法,是Java数据库程序设计里非常实用的重要技巧.分享给大家供大家参考.具体如下: JDBC(Java Data Base Connectivity)数据库连接,通常我们在编写web应用或java应用程序要连接数据库时就要使用JDBC.使用JDBC连接数据库一般步骤有: 1.加载驱动程序 Class.forName(driver); 2.创建连接对象 Connection con = DriverManager.getConnection(ur

  • java jdbc连接mysql数据库实现增删改查操作

    jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打交道非常基础的一个知识,也是比较接近底层的,在实际的工作中大家用得更多的其实还是比较成熟的框架,例如Hibernate.Mybatis. 但是作为这些成熟框架的底层的jdbc却也是我们应该去掌握的,只有了解了jdbc的增删改查,这样在以后如果有兴趣去研究Hibernate或者Mybatis的源代码的时候才能更好的去理解这些成熟的框架是如何去实现增删改查

  • java使用JDBC动态创建数据表及SQL预处理的方法

    本文实例讲述了java使用JDBC动态创建数据表及SQL预处理的方法.分享给大家供大家参考,具体如下: 这两天由于公司的需求,客户需要自定义数据表的字段,导致每张表的字段都不是固定的而且很难有一个通用的模板去维护,所以就使用JDBC动态去创建数据表,然后通过表的字段动态添加数据,数据的来源主要是用户提供的Excel直接导入到数据库中. 如果考虑到字段的类型,可以通过反射的机制去获取,现在主要用户需求就是将数据导入到数据库提供查询功能,不能修改,所以就直接都使用String类型来处理数据更加便捷.

  • java实现jdbc批量插入数据

    首先介绍三种JDBC批量插入编程方法,进行比较,具体内容如下 JDBC批量插入主要用于数据导入和日志记录因为日志一般都是先写在文件下的等. 我用Mysql 5.1.5的JDBC driver 分别对三种比较常用的方法做了测试 方法一:使用PreparedStatement加批量的方法 try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(o_url, userName, pass

  • java使用jdbc连接数据库工具类和jdbc连接mysql数据示例

    这个工具类使用简单,实例化直接调用就可以了,大家还可以方便的根据自己的需要在里面增加自己的功能 复制代码 代码如下: package com.lanp.ajax.db; import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException; /** * 连接数据库的工具类,被定

  • 完整java开发中JDBC连接数据库代码和步骤

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)实现. 例如: try{ //加载MySql的驱动类 Class.forName("com.mysql.jdbc.Driver") ; }catch(ClassNotFoundException e){ Sys

  • java中JDBC实现往MySQL插入百万级数据的实例代码

    想往某个表中插入几百万条数据做下测试,原先的想法,直接写个循环10W次随便插入点数据试试吧,好吧,我真的很天真.... DROP PROCEDURE IF EXISTS proc_initData;--如果存在此存储过程则删掉 DELIMITER $ CREATE PROCEDURE proc_initData() BEGIN DECLARE i INT DEFAULT 1; WHILE i<=100000 DO INSERT INTO text VALUES(i,CONCAT('姓名',i),

  • java实现jdbc查询结果集result转换成对应list集合

    代码非常的简单,这里就不多废话了,直接奉上 public static <T> List<T> convertToList(ResultSet rs,Class<T> t) throws SQLException { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); ResultSetMetaData md = (ResultSet

随机推荐