简介
当我们学习了java语言和数据库之后,一定会想到如何使用java去操作数据库,而数据库之间在语法方面又有些许不同,这样就需要编写不同的java语言去操作不同的数据库,由此造成了程序员学习困难的问题,并且当项目需要迁移数据库时,需要更改大量的java代码会造成维护困难问题,为了解决这些问题,便引入了JDBC。
JDBC是java语言操作关系型数据库的API,是java(sun公司)提供的一套操作关系型数据库的规则,即接口。
接口是java语言书写的规范,但真正执行的代码是需要由各个数据库厂商编写的驱动jar包,通过JDBC可以提高各个关系型数据库的兼容性,从而实现用同一套java代码控制不同的关系型数据库。
1、编程步骤(以MySQL为例)
1.导入jar包
可在MySQL官网获取MySQL的驱动jar包,官网地址如下:
通常在我们的java项目下会有一个lib目录用来存放jar包,如果没有则创建一个lib目录,把驱动jar包放进去,后如图所示,右键单击jar包选择Add as Library...,将jar包导入到项目中。
如果是maven项目,也可不导入jar包,在pom.xml中添加mysql的依赖即可
2.加载注册驱动
加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名
Class.forName(“com.mysql.jdbc.Driver”);
使用DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动
因为Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver() 方法来注册自身的一个实例。所以不需要我们自己去注册驱动。
3.获取连接
通过调用DriverManger的getConnection静态方法可以获取到Connection对象
其中getConnection方法需要传入三个参数:
url:用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
user:数据库用户名
password:密码
4.定义SQL语句
定义将要执行的SQL语句,建议采用PreparedStatement去执行SQL,所以定义SQL时采用PreparedStatement的方法区定义:将需要传入的参数定义为“?”。
5.获取执行SQL对象
可以使用Statement去执行SQL,也可以使用PreparedStatement去执行SQL,但推荐使用PreparedStatement,不仅能有效预防SQL注入问题,还可以进行操作blob类型数据,开启预编译后在需要重复使用同一条SQL时不需要查询编译,可以提高执行效率。
6.执行SQL
使用executeUpdate(sql)执行更改操作(增加、删除、修改),返回值为整型,表示影响的行数。
使用executeQuery(sql)执行查找操作,返回值为ResultSet类型的结果集。
7.释放资源
使用close发放来释放调用的Connection、PreparedStatement、ResultSet等资源。
整体代码如下:
public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1.导入jar包
// 2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 3.获取数据库连接对象
Connection connection =
DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf-8","root", "root");
// 4.定义sql
String sql="update student set stuname= '张三',age=18,classname='计算机科学1班' where id=1";
String sql1="INSERT INTO student VALUES(null,'唐僧',1000,'大唐');";
// 5.获取执行SQL的对象
Statement statement = connection.createStatement();
// 6.执行sql语句,接收返回结果
// int i = statement.executeUpdate(sql);
int j = statement.executeUpdate(sql1);
// 7.处理结果
// System.out.println("更新了"+i+"条数据!");
System.out.println("插入了"+j+"条数据!");
// 8.释放资源
statement.close();
connection.close();
}
}
2、java中的事务
java中使用Connection的setAutoCommit(boolean autoCommit)方法来选择是否自动提交事务。
Connection conn = getConnectionDruid();//获取连接
conn.setAutoCommit(false); // 关闭自动提交事务功能
conn.commit(); // 提交事务
conn.rollback(); // 回滚事务
conn.getTransaction(); // 查看当前隔离级别
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); // 更改隔离级别
conn.close(); // 关闭连接
在java中有三种情况会自动提交事务
- DDL操作
- DML操作,可使用set autocommit = false取消DML的自动提交
- 关闭数据库
3、数据库连接池
数据库连接池是一个容器,负责分配、管理数据库连接(connection)。
作用(好处):
- 允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个(资源重用、提升系统响应速度)
- 可以释放空闲的数据库连接(避免数据库连接遗漏)
java提供了一个标准接口DataSource,需要由第三方实现此接口,并重写其 getConnection()方法
DBCP 是Apache提供的数据库连接池。tomcat 服务器自带dbcp数据库连接池。速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持。
C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以。hibernate官方推荐使用
Proxool 是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
BoneCP 是一个开源组织提供的数据库连接池,速度快
Druid 是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池,但是速度不确定是否有BoneCP快
市面上有很多的数据库连接池,推荐使用Druid(德鲁伊)他是阿里巴巴开源的数据库连接池,功能强大,性能优秀,是java语言最好的数据库连接池之一。
特别注意:
- 数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。
- 当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但conn.close()并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。
4、DBUtils
DBUtils是Apache 组织提供的一个开源 JDBC工具类库,极大简化jdbc编码的工作量,提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的,导包之后可以直接调用。
QueryRunner类
该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
ResultSetHandler接口及实现类
该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
接口的主要实现类:
-
ArrayHandler:把结果集中的第一行数据转成对象数组。
-
ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
-
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
-
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
-
ColumnListHandler:将结果集中某一列的数据存放到List中。
-
KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
-
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
-
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
-
ScalarHandler:查询单个值对象