什么是JDBC
Java Database Connectivity
- 让Java程序操作关系型数据库
- JDBC基于驱动程序实现与数据库的连接与操作
- 驱动程序实现了JDBC API,所以Java程序可以调用JABC API(也就是调用底层的MySQL驱动程序的实现)来对数据库进行访问
JDBC的优点
- 统一的API,提供一指的开发过程
- 易于学习,容易上手,代码结构稳定
- 功能强大,执行效率高,可处理大量数据
JDBC开发流程
- 加载并注册JDBC驱动
- 创建数据库链接
- 创建Statement对象
- 遍历查询结果
- 关闭链接,释放资源
Class.forName的作用
- 用于加载指定的JDBC驱动类
- 本质是通知JDBC注册这个驱动类
DriverManager
- 用于注册,管理JDBC驱动程序
DriverManager.getConnection()
- 返回值Connection对象,对应数据库的物理网络连接
Connection对象
- Connection对象用于JDBC与数据库的网络通信对象
java.sql.Connection
是一个接口,具体实现由驱动厂商负责- 所有数据库的操作都建立在Connection基础上
链接字符串
jdbc:mysql://localhost:port_number/database_name
- 之后可以添加额外参数
- 参数列表采用URL格式:name=value&name2=value2&…
MySQL连接字符串常用参数
参数名 | 建议参数值 | 说明 |
---|---|---|
useSSL | true/false | 是否禁用SSL |
useUnicode | true | 启用unicode编码传输数据 |
characterEncoding | UTF-8 | 使用UTF-8编码 |
serverTimezone | Australia/Sydney | timezone |
allowPublicKeyRetrieval | true | 允许从客户端获取公钥加密传输 |
- 如果数据库的设置已经是使用澳洲时区,那么连接字符串的参数可以省略
SQL注入攻击
'
单引号没有被特殊处理,被当成SQL query的一部分- 利用SQL漏洞越权获取数据的黑客行为
- 根源是未对原始SQL中的敏感字符做特殊处理 (转译escape)
- 解决方法:放弃Statement改用PreparedStatement处理SQL
PrepareStatement
- 是Statement的子接口
- 对SQL进行参数化,预防SQL注入攻击
- 比Statement执行效率更好
错误的使用方式
select * from employee where ? = 'abc';
select * from employee where salary = ? + 100;
select * from employee where ename = ?;
封装数据库连接
- 每次对数据库操作时都需要打开和关闭,我们可以将这个重复的步骤封装到一个Class中,需要时直接调用
1 | /** |
JDBC执行INSERT, UPDATE, DELETE语句
- statement.executeUpdate()
- 返回受影响得行数
JDBC事务管理
- 事务依赖于数据库的实现,MySQL通过事务区作为数据缓冲地带
- 全部成功或者全部失败
自动提交事务模式
- 没执行一次写操作SQL,自动提交事务
conn.setAutoCommit(true)
- 默认的事务模式
- 无法保证多数据一致性
手动提交事务模式
- 显示调用
commit()
与rollback()
方法管理事务 conn.setAutoCommit(false)
- 可保证数据一致性,但必须手动调用提交、回滚方法
JDBC中Date日期对象的处理
- JDBC获取日期使用
java.sql.Date
,它继承自java.util.Date
- 所以当获取MySQL中的日期时,两者互相兼容
Date日期的提取
- 因为sql.Date继承自util.Date所以可以直接提取
Date日期的插入
- 需要先将用户输入String转换成java.util.Date
String -> java.util.Date
- 再将java.util.Date转换成java.sql.Date
java.util.Date -> java.sql.Date
1 | // 1.string -> java.util.Date |
JDBC批处理
1 | String sql = "insert into employee (eno, ename, salary, dname) values (?, ?, ?, ?);"; |
连接池与JDBC进阶
- 建立数据库链接比较费时间
- 当我们知道应用的大概人数后,可以在应用启动时,提前创建好大概的连接并存放到连接池中
- 当有用户需要连接数据库时,直接从连接池中获取一个可用的连接,用完之后再放入到连接池中以供其他用户使用
- 管理,分配,连接
- 程序只负责取用和归还
Druid连接池
- Druid是阿里巴巴开源连接池组件
- 连接池配置文件
1 | driverClassName=com.mysql.cj.jdbc.Driver |
- 连接的步骤
- 加载属性文件
1 | Properties properties = new Properties(); |
- 获取dataSource数据源对象,指代数据库
1 | dataSource = DruidDataSourceFactory.createDataSource(properties); |
- 不使用连接池: conn.close()的作用是关闭连接
- 使用连接池: conn.close()的作用是将连接回收到连接池
- 当用户连接数量超过连接池设置的最大数量时,新的用户将会等待连接被其他用户关闭
- Tips:可以将初始连接数量和最大连接数保持一致
扩展知识:C3P0连接池
- C3P0连接池
- C3P0会自动找到名为c3p0-config.xml的配置文件
DataSource dataSource = new ComboPooledDataSource();
Apache Commons DBUtils
- Apache提供的JDBC工具类库
- 它是对JDBC的简单封装,学习成本低
- 简化JDBC编码工作量
1 | Properties properties = new Properties(); |