1.JDBC代码的初步优化
(1)web层和Dao的实现层耦合
CustomerDao dao = new CustomerDaoImpl();
如果Dao的实现类没有写,我就得不到dao,web层就写不了
我们用工厂来把他们解耦,web层和Dao实现,他俩中间加一个工厂,
让工厂横插一杠子,工厂有一个方法,用来获得Dao的具体实现类
(2)获得具体的Dao,我们用配置文件+反射,得到具体Dao的实现类,
同时通过配置文件,而不通过硬编码的形式,我们以后改了Dao的实现类,
如Hibernate,我们只用改配置文件,而不用动程序
(3)web层调用 new 工厂().getDao(),我们就想每次得到Dao的实现类的时候都要new
一个工厂,不好!我们把它设计成单例的,让工厂的实例只有一个
(4)加载配置文件只要一次,我们就将加载的代码放到静态代码块中
(5)同样,JDBCUtils的得到连接那块,通过配置文件
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, password);
这样更换数据库,用Oracle的时候,就只要该配置文件中的驱动,而不用动程序
(6)同样加载配置文件放到静态代码块中,只加载一次
(7)JDBCUtils的得到连接要改一下,用连接池
连接池开始创建很多连接,这些连接用LinkedList装(增加,删除用的多)
取得连接了就将LinkedList中删除,关闭(返回)连接了就将它添加到LinkedList中
(8)动态代理的测试程序
(9)动态代理 DataSource 连接池
写一个类实现DataSource接口,我们关注的是getConnection方法
静态代码块:通过配置文件注册驱动
初始化的时候:创建一批连接,并把他们加到LinkedList中
得到连接:LinkedList中removeFirst,将第一个元素中容器中拿出
得到的是一个假连接,当Dao调用任何方法时会调用InvocationHandler.invoke方法
在invoke方法中,判断调用的方法名,
若为close的话,我们就做点手脚,把连接返回到容器中,addFirst,返回null
若不为close的话,原样执行method.invoke
这个类是得到数据库连接的,不用每次都new,我们用单例设计模式
2.用动态代理 优化 连接池
a.动态代理的例子程序
b.用动态代理优化
3.其他开源的,用来得到DataSource
a.DBCP
b.Tomcat , JNDI
4.事务
a.ACID
b.JDBC来管理事务
5.事务的隔离级别
a.四种隔离级别
b.在MySQL中实验
----------------------------------------------------------------------------------------
1.JDBC优化
1)使用DAO工厂隔离DAO层
简单工厂,配置文件,反射
2)用配置文件优化JDBCUtils
3)连接池:
个人认为:连接池就像妓院,连接就像妓女,使用连接的就嫖客
嫖客干完了妓女,不是把她杀掉,而是把她放回妓院,好然其他嫖客干
用动态代理实现
2.常用数据库连接池:
1)DBCP
BasicDataSourceFactory DataSource
2)C3P0
3)Tomcat数据源
JNDI
3.数据库事务
1)是逻辑上的一组操作,要么都成功,要么都不成功
2)start transaction 开启事务
commit; 提交事务
rollback 回滚
3)事务的特性(ACID):
原子性:(XXX,YYY)被包在一起,像原子一样,不能分割,
要么都成功,要么都失败,他们是一个逻辑单元
一致性:两个人转账,两个人的总钱要和转账前一致
隔离性:多个用户并发访问数据库
持久性:事务一旦提交,对数据库的改变的永久的
4)用JDBC管理事务:
Connection.setAutoCommit(false);
Connection.rollback();
Connection.commit();
Connection conn = null;
try{
...update.1...
...update.2...
conn.commit();
} catch(Exception e){
conn.rollback();
}
设置事务回滚点
SavePonit sp = conn.setSavePoint();
conn.rollback(sp);
conn.commit();
可以设置多个回滚点
5)事务的隔离级别:
脏读:指一个事务读取了另外一个事务未提交的数据。
不可重复读:在一个事物内读取表中的某一行数据,多次读取结果不同。
虚读:是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。