JDBC 阶段总结二
问题清单:
(1)PreparedStatement与Statement的区别
(2)事务
(3)DAO及其子类
(4)数据库连接池
(5)使用DBUtils提供方法进行CRUD
1-PreparedStatement与Statement
(1)PreparedStatement(PS)与Statement的关系?
PS继承自Statement,二者都是接口;
(2)PreparedStatement如何提高了性能?
PreparedStatement在执行具体的SQL语句之前,会预先编译SQL语句,编译后的SQL语句被缓存下来,若下次有相同的SQL语句需要被执行,只需要将参数传入编译过的SQL语句当中即可,实现了一次编译,多次执行的效果,而Statement则没有预编译的功能;
(3)PreparedStatement可以防止SQL注入
PS的预编译功能能够保留SQL语句的自身逻辑,防止攻击者注入SQL;
2-事务
(1)事务属性ACID
原子性:将所有对于数据库的操作都作为一个不可分割的工作单位,要么都执行,要么都不执行;
一致性:要求数据库的状态必须从一个一致性状态变换到另一个一致性状态;
隔离性:一个事务的执行不能影响其他事务,即事务的内部的操作与使用到的数据对其它正在发生的事情来说,是 隔离的,并发执行的各个事务之间,不能互相干扰;
持久性:事务一旦被提交,它对数据库的改变是永久的;
(2)数据操作可能会出现的问题
脏读:在正式提交数据之前,如果事务2发生异常导致回滚,则事务1在回滚之前读取的数据,为临时且无效的
不可重复读:事务1在事务2正常提交数据之前做了读取操作,之后,事务2正常提交数据,数据被更新,则事务1再次读取同一个字段时,值发生了变化
幻读:幻读针对插入操作,对于两个事务1和事务2,从事务1表中读取了一个字段,然后事务2插入了新的列,如果事务1再从新进行读取,则会发现多了几行。
(3)数据库的四种隔离级别
读未提交:什么都解决不了
读已提交:可以避免脏读
可重复读:可以避免脏读、不可重复读
串行化:所有都有可以解决
出现的问题讨论:「一致性和并发性」的问题,是在开发过程中的一对矛盾,一致性要求系统稳定不出差错,并发性要求能够在同一时间执行多个操作;
(4)事务的处理原则
需要保证所有的事务操作都作为一个不可分割的单元来执行,要么全都执行,如果出现错误,则全部回滚,回到最初的状态。
3-DAO及其子类
以使用到的customers表为例,项目结构为
- BaseDAO :基础的CRUD操作
- CustomersDAO:一组针对Customers表的接口,定义了Customers表的常用操作
- CustomersDAOImpl:针对接口的实现类
考虑到事务以后的数据库操作:
- 设置取消自动提交conn.setAutoCommit(false);
- 手动提交conn.commit();
- 如果异常…rollback…关闭资源
4-数据库连接池
(1)数据库连接池的出现是为了解决获取连接时花费资源问题,这样做的好处是:
- 资源重用
- 更快的系统反应速度
- 一种新的资源分配手段
- 统一的连接管理,避免连接泄露
(2)实现方式:
- DBCP
- C3P0
- Druid(推荐)
在使用数据库连接池操作中,需要将驱动导入IDEA,具体方式
5-DBUtils使用
之前我们使用自己写的一套CRUD来完成数据库的交互,这回可以使用Druid数据库连接池完成连接获取,使用DBUtils完成CRUD,其中:QueryRunner对象作为传入SQL执行的对象,调用update,query方法完成查询,其中需要我们确定的是query里的handler对象:
- BeanHander:是ResultSetHandler接口的实现类,用于封装表中的一条记录;
- BeanListHandler:是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合;
- MapHander:是ResultSetHandler接口的实现类,对应表中的一条记录;
- MapListHander:是ResultSetHandler接口的实现类,对应表中的多条记录;
- ScalarHandler:用于查询特殊值;
- 也可以自定义ResultSetHandler的实现类
//测试插入
@Test
public void testInsert() {
Connection conn = null;
try {
QueryRunner runner = new QueryRunner();
conn = JDBCUtils.getConnection3();
String sql = "insert into customers(name,email,birth)values(?,?,?)";
int insertCount = runner.update(conn, sql, "蔡徐坤","caixukun@126.com","1997-09-08");
System.out.println("添加了" + insertCount + "条记录");
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCUtils.closeResource(conn, null);
}
}
// 测试查询
@Test
public void testQuery1(){
Connection conn = null;
try {
QueryRunner runner = new QueryRunner();
conn = JDBCUtils.getConnection3();
String sql = "select id,name,email,birth from customers where id = ?";
BeanHandler<Customer> handler = new BeanHandler<>(Customer.class);
Customer customer = runner.query(conn, sql, handler, 23);
System.out.println(customer);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtils.closeResource(conn, null);
}
}
小结
说实话,完全没有想到,自己最近会因为小小的耳鸣进医院…,我太惜命了吧哈哈,JDBC我学的好好的…,大概用了8天时间吧,结束了jdbc,学习ORM思想下对数据库进行交互,难是不难,但是最近打算JavaWeb与数据结构算法一起搞,听说数据结构算法搞脑子,是这样吗?哼哼,还有就是,学习,总结,学习总结,不断输出!就想到这里吧。