阶篇_迈向标准开发
自己编写dbutils工具( QueryRunner 、TxQueryRunner和JdbcUtils) (本文核心)
封装成jar包后的标准开发--common-dbutisl和itcast-tools (本文核心)
数据库使用MySQL数据库,使用的表结构 :
tab_bin
t_user
account
t_customer
JDBC基础代码回顾
JDBC四大核心对象: 全部来自 java.sql 包下
DriverManager | 注册驱动,获取Connection对象 |
Connection | 连接对象,获取preparedStatement |
PreparedStatement | sql语句发送器,执行更新、查询操作 |
ResultSet | 结果集,通过next()获取结果 |
项目src文件下编写dbconfig.properties配置文件:
name | value |
driverClassName | com.mysql.jdbc.Driver |
url | jdbc:mysql://localhost:3306/jdbc_test01 |
username | root |
password | 123456 |
@演示
JdbcUtils类_简化代码小工具
Dao类_操作/测试数据库
c3p0数据库连接池的使用
c3p0数据库连接池 : 数据库的很多连接对象都放在池中被管理着,谁用谁去租,用完归还就行了。 c3p0就是一个比较不错的池子 。
DataSource对象也在 java.sql 包下
项目src文件下编写c3p0-config.xml配置文件(文件中也给出了oracle的配置模版):(@注意:配置文件的名称c3p0-config.xml是一个官方给定的标准,不是随意起的名字)
@演示
c3p0-config.xml
JdbcUtis工具类_c3p0版本
Test类_查看获取的连接
大数据的插入(使用c3p0+JdbcUtls简化代码)
@解决的问题 如何向mysql中插入一部10M左右的.mp3文件 ???
MySQL中提供存储大数据的类型如下:(@注意 标准SQL中提供的类型并非如下类型,请自行百度)
类型 | 长度 |
tinytext | 28-1 B(256B) |
text | 216-1B(64K) |
mediumtext | 224-1B(16M) |
longtext | 232-1B(4G) |
待插入文件地址 : D:\十年.mp3
待下载文件地址: E:\十年.mp3
@使用 c3p0数据库连接池的使用 中的c3p0-config.xml 和JdbcUtils工具
@演示
BigData类_操作大数据
@可能出现错误 如果出现以下错误提示,请打开MySQL对于插入数据大小的限制。具体操作 : 在MySQL\MySQL Server 5.5\my.ini 文件中添加 max_allowed_packet = 16M
1 java.lang.RuntimeException: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (8498624 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
批处理操作(使用c3p0+JdbcUtls简化代码)
批处理的意思是: PreparedStatement对象可以成批的发送SQL语句给服务器执行,对象中有集合。 特别是在向数据库中插入很多数据时,开启了批处理后,1万记录只需要不到半秒,如果没有开启,则需要7分钟。
MySQL中开启批处理需要在url上添加参数,即: jdbc:mysql://localhost:3306/jdbc_test01?rewriteBatchedStatements=true
@演示
批处理的JDBC代码
数据库中的事务(使用c3p0+JdbcUtls简化代码)
转账功能: A向B转账100元,数据库操作是 : 1. A减少100元,2. B增加100。 若A减少100元,硬件崩溃,则B并没有增 加100元,这是不行的,应该回滚到A还没有减少100的时候 。 这就需要事务。
同一个事务中的多个操作,要么完全成功提交,要么完全失败回滚到原点,不可能存在成功一半的情况,具有原子性、一致性、隔离性、持久性。 所以可以将以上的两步操作放到一个事务中。
JDBC中与事务相关的对象是Connection 对象,该对象有三个方法来操作事务:
setAutoCommit(boolean) | false表示开启事务 |
commit() | 提交事务 |
rollback() | 回滚事务 |
@注意 同一事务的所有操作,使用的是同一个Connection对象
@使用 c3p0数据库连接池的使用 中的c3p0-config.xml 和JdbcUtils工具
@演示
AccountService类_转账业务/测试
AccountDao_sql操作
@事务并发的缺陷 多个事务并发执行时,因为同时调用Connection对象而引发严重问题,造成脏读、不可重复读、虚读的严重问题。 需要进行多线程并发控制
多线程并发控制的操作
@java中的并发问题 如果多个线程同时访问同一个数据的时候,线程争夺临界资源数据引发问题 。 多个线程可描述为多个任务,例如: 同一个帐号在不同ATM机上取钱,这是两个任务(也是两个线程),两个线程都要调用 Class 取钱{ private String 帐号 ; public void fun1() {} public void fun2() {} .... } 中的帐号变量(成员变量),就会出现读写问题。 一般来说,l临界资源都是类中的成员变量,而非方法中的局部变量 。
JDBC操作中,因为多个事务同时调用Connection对象,会引起并发问题。
@解决问题 解决的方法可以用synchrozined{}同步块 , 但是此法耗时严重。采用效率能提高150倍的ThreadLocal比较好。ThreadLocal类是一个泛型类,@思想 将临界资源给每个线程都分配一份,来解决多个线程争夺同一个资源而引发的难题。
ThreadLocal类java.lang包下已经写好的封装类,直接调用即可 。 有三个方法: 分别是set()、get()和remove() 。 以下是自己编写的模拟类,为了更好的理解该类的底层是怎么实现的
ThreadLocal类 核心功能
@演示 使用内部类模拟多线程并发争夺临界资源来演示ThreadLocal的作用
ThreadLocal的测试
用ThreadLocal类解决JDBC中事务的并发问题放到TxQueryRunner类中解决
QueryRunner、TxQueryRunner和JdbcUtils(重点、本文核心)
QueryRunner的思想是: 把java中对数据库的处理代码写到单独的类QueryRunner中,Dao层只提供SQL模版和sql参数,而TxQueryRunner负责继承QueryRunner类辅助事务的处理 。JdbcUtils起到了真正的工具作 用,负责连接,事务等
@演示
@使用 c3p0数据库连接池的使用 中的c3p0-config.xml
Customer
CustomerService
CustomerDao
JdbcUtils_工具类
QueryRunner_工具类
TxQueryRunner_工具类
ResultSetHandler_工具类
@download 项目下载http://files.cnblogs.com/files/zyuqiang/jdbcStudy_finalSummary.rar
封装后的标准开发-------common-dbutils.jar和itcast-tools.jar(重点、本文核心)
commons-dbutils 是 Apache 组织提供的一个开源 JDBC 工具类库,上述自己写的QueryRunner工具类也是我对此官方的工具类库做了一个简单的核心功能的抽出,当然官方的工具类库功能更加丰富 。 从此以后,我们开发不需要自己编写工具类,而是导入common-dbutils.jar 来直接使用即可 . @注意 官网提供的 工具类库 不包含TxQueryRunner和JdbcUtils工具,这两个工具依然还需要我们自己动手实现,不过也有非官方提供的封装包,如传智的itcast-tools.jar 。 可以拿来直接使用
@结果集处理器 common-dbutils包中提供了各种各样的结果集处理器,可以处理查询到的结果集,如封装成实体类对象等。有如下的五种结果集处理器
BeanHandler | 结果集为单行 | 构造器需要一个Class类型的参数,用来把查询到的一行结果集转换成指定类型的javaBean对象 | 常用 |
BeanListHandler | 结果集为多行 | 构造器也是需要一个Class类型的参数,用来把查询到的多行记录一个记录转成一个javaBean对象,多个JavaBean构成转List对象 | 常用 |
MapHandler | 结果集为单行 | 把一行结果集转换Map对象 | 不常用 |
MapListHandler | 结果集为多行 | 把一行记录转换成一个Map,多行就是多个Map | 不常用 |
ScalarHandler | 结果集是单行单列 | 它返回一个Object,多用在求一共有多少个记录上 | 常用 |
@演示 导入common-dbutils.jar 和 itcast-tools.jar(jar包在项目中,可以下载该项目找到),仍然@使用 c3p0数据库连接池的使用 中的c3p0-config.xml
Customer
CustomerService
CustomerDao
TestDemo
也可以批量添加数据
1 private QueryRunner qr = new TxQueryRunner(); 2 /** 3 * 添加新客户 4 * 批处理 5 * @param cstm,num是批量插入记录的行数 6 * @throws SQLException 7 */ 8 public void add(Customer cstm , int num) throws SQLException { 9 /*10 * 1. 创建TxQueryRunner对象 11 * 2. 准备SQL模版 12 * 3. 将参数存入参数数组 13 * 4. 调用TxQueryRunner类中batch方法 进行插入操作14 */15 String sql ="insert into t_customer values(?,?,?)";16 Object[][] params = new Object[num][];17 for(int i=0;i<params.length;i++){18 params[i]=new Object[]{cstm.getUsername()+i,19 cstm.getAge()+i,20 cstm.getBalance()};21 }22 // Object[] params = {cstm.getUsername(),23 // cstm.getAge(),24 // cstm.getBalance()};25 qr.batch(sql, params); 26 }
@download 项目下载http://files.cnblogs.com/files/zyuqiang/jdbcStudy_finalSummary_Commons.rar
http://www.cnblogs.com/zyuqiang/p/7218083.html