Java操作数据库
1. JDBC 编程六部
- 注册驱动
- 获取数据库连接
- 获取数据库操作对象
- 执行 SQL 语句
- 处理查询结果集
- 释放资源
注意:连接数据库时的URL:
示例:
1 | public static void main(String[] args) { |
2. 功能类详解
2.1 DriverManager
DriverManager 驱动管理对象
2.1.1 注册驱动
方法一:注册给定地驱动程序
1 | Driver driver = new com.mysql.jdbc.Driver(); |
方法二:直接使用com.mysql.cj.jdbc.Driver类中的静态代码块
1 | Class.forName("com.mysql.cj.jdbc.Driver"); |
源代码:
1 | package com.mysql.cj.jdbc; |
注意:
- 一般情况下不需要调用DriverManager的静态方法registerDriver(),因为只要静态类被使用,就会自动调用其中的静态代码块完成注册驱动
- mysql5 之后可以省略注册驱动的步骤
2.1.2 获取数据库连接
获取数据库连接对象:
1 | static Connection getConnection(String url, String username, String password); |
2.2 Connection
Connection 数据库连接对象
2.2.1 获取执行者对象
- 获取普通执行者对象:
1 | Statement createStatement(); |
- 获取预编译执行者对象
1 | PreparedStatement prepareStatement(String sql); |
2.2.2 管理事务
手动管理事务:
1 | setAutoCommit(boolean autoCommit); |
jdbc 默认是自动提交事务,通过将参数设置为 false 可以开启手动提交事务
提交事务:
1 | commit(); |
回滚事务:
1 | rollback(); |
2.2.3 释放资源
立即将数据库连接对象释放:
1 | void close(); |
2.3 Statement
Statement 执行 sql 语句
2.3.1 执行 DML 语句(增、删、改 操作)
1 | int executeUpdate(String sql); |
返回值:int 类型,指影响的行数
参数:insert、update、delete 语句
2.3.2 执行 DQL 语句(查询操作)
1 | ResultSet executeQuery(String sql); |
返回值:ResultSet 类型,封装查询结果
参数:select 语句
2.3.3 释放资源
1 | void close(); |
2.4 ResultSet
ResultSet 结果集对象
2.4.1 判断结果集中是否还有数据
1 | boolean next(); |
返回值:有数据则返回 true,并将索引向下移动一行。没有数据则返回 false
2.4.2 获取结果集中的数据
1 | XXX getXxx("数据库列名"); |
XXX:java 数据类型
如:
1 | String getString("name"); |
2.4.3 释放资源
1 | void close(); |
2.5 PrepareStatement
PrepareStatement 预编译执行者对象
原理:
- 在执行 sql 语句之前,将 sql 语句进行提前编译。明确 sql 语句的格式后,就不会改变了,剩下的内容都只会被认为是参数
- sql 语句中的参数使用 ?做占位符
2.5.1 为 ?占位符赋值的方法
1 | setXxx(参数1, 参数2); |
Xxx:数据类型
参数1:?的位置编号(编号从1开始)
参数2:?的实际参数
1 | String sql = "select * from book where id=?"; |
2.5.2 执行 sql 语句
- 执行 insert、update、delete 语句
1 | int executeUpdate(); |
- 执行 select 语句
1 | ResultSet executeQuery(); |
2.5.3 释放资源
1 | void close(); |
3. 数据库连接池
3.1 自定义数据库连接池
3.1.1 实现步骤
- 定义一个类,实现 DataSource 接口
- 定义一个容器,用于保存多个 Connection 连接对象
- 定义静态代码块,通过 JDBC 工具类获取 10 个连接对象并保存到容器中
- 重写 getConnection 方法,从容器中获取一个连接并返回
- 定义 getSize 方法,用于获取容器的大小并返回
3.1.2 归还连接
归还数据库连接的方式:
- 继承方式
思想:
- 通过打印连接对象,发现 DriverManager 获取的连接实现类是 JDBC4Connection
- 那么就可以自己定义一个类,继承 JDBC4Connection这个类,重写close() 方法,完成连接对象的归还
问题:
- 我们虽然定义了一个子类完成了连接归还的操作,但是DriverManager获取的还是 JDBC4Connection这个对象,并不是我们自己定义的子类对象。多态允许把一个子类对象指向父类引用,但是这里强转相当于把一个父类对象指向子类引用,会报语法错误。所以此方法行不通
- 装饰设计模式
思想:
- 可以自己定义一个类,实现 Connection 接口。这样就具备了和 JDBC4Connection相同的行为了
- 重写close() 方法,完成连接的归还,其余的功能还调用 mysql 驱动包实现类原有的方法即可
问题:
- 实现 Connection 接口后,有大量的方法需要在自定义类中进行重写,非常麻烦
- 适配器设计模式
思想:
- 我们可以自己定义一个适配器类,实现 Connection 接口,将除 close 外的所有方法进行实现
- 自定义连接类只需要继承这个适配器类,重写需要改进的 close 方法即可
问题:
- 虽然自定义连接类比较简洁,但是适配器类和上个方法一样麻烦
- 动态代理方式
思想:
- 通过 Proxy 来完成对 Connection 实现类对象的代理
- 代理过程中判断如果执行的是 close 方法,就将连接归还到连接池中,如果是其他的方法就继续调用原来的功能即可
3.2 第三方连接池
3.2.1 c3p0 连接池
1 | public static void main(String[] args) throws Exception { |
3.2.2 Druid 连接池
1 | public static void main(String[] args) throws Exception { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 葡萄的个人博客!
评论
GitalkWaline