1 jdbc回顾
1.1 批处理
Statement 执行多条sql
addBatch(sql)
clearBatch()
int[] executeBatch()
PreparedStatement 执行一条sql语句,多组参数
addBatch() 执行之前必须设置实际参数 psmt.setXxxx()
clearBatch()
executeBatch()
1.2 事务
事务:一组业务逻辑操作,要么全部成功,要么全部不成功。
事务特性:ACID
原子性:整体
一致性:数据
隔离性:并发
持久性:结果
隔离问题:脏读、不可重复读、幻读
隔离级别:读未提交、读已提交、可重复读、串行化
jdbc事务操作
开启事务:conn.setAutoCommit(false);
提交事务:conn.commit();
回滚事务:conn.rollback();
conn.rollback(savepoint);
1.3 连接池
接口:javax.sql.DataSource 数据源,getConnection() 获得连接
第三方
DBCP:BasicDataSource --> driverClassName, url ,username, password
C3P0:ComboPooledDataSource --> driverClass , jdbcUrl ,user , password
tomcat内置: JNDI容器,名称字符串(“a/b/c”) --> lookup(“java:/comp/env/…”)
2 自定义连接池
实现步骤
1.创建池,池中存放连接
2.当使用连接池,从池中获得(移除)–保证当前连接只能被一个人使用。
3.使用完成之后,将当前连接归还(添加)
实现细节
1.使用LinkedList 易于增删,给集合中添加自定义对象(MyConnection)对 DriverManager生成Connection进行增强
2.使用 remove(0) 移除第一个保证同时只有一个人使用当前连接。使用递归处理连接池中没有连接情况。
3.通过 conn.close() 进行当前连接的归还。
方法增强种类:
1.继承:父子类 – 前提:必须有父类
2.装饰者设计模式,前提:必须有接口【】
设计模式–固定的代码
3.动态代理,前提:必须有接口
4.字节码增强。例如:cglib、javaassist等
3 DbUtils
apache 提供工具类,简化JDBC开发。
导入jar包:
默认情况将使用连接池,将连接池交予工具,jdbc对象都有工具维护(Connection /Statement/ResultSet)
核心类:QueryRunner
方式1:没有事务【】
构造方法:new QueryRunner(DataSource); , 提供连接池,工具自己维护连接
方法api
update(sql, params…) 执行DML sql 语句,并设置实际参数(可变参数,可以多个)
query(sql, handler , params…) 执行DQL 语句,params实际参数,将查询结果集ResultSet,使用Handler提供处理类进行处理,并将数据封装到指定的内容中。
方式2:使用事务(Connection),必须手动获得连接,且程序进行维护
构造方法:new QueryRunner()
方法api
update(conn , sql, params…)
query(conn , sql ,handler ,params…)
处理类:将ResultSet 按照 指定的策略进行数据封装。(设计模式:策略)
BeanListHandler ,将查询每一条封装到指定JavaBean,将javaBean实例添加集合,最后返回集合。
BeanListHandler(User.class)
BeanHandler ,将查询一条封装到指定javabean,并返回javabean实例
BeanHandler(User.class)
ScalarHandler 处理一行一列结果集(聚合函数)
ArrayHandler 将查询一条记录所有的数据封装到数组中,并返回。Object[] arr = {1,“jack”,“1234”};
ArrayListHandler 将查询每一条记录封装到数组中,在数组添加到List集合,最后返回list集合。
new ArrayList() , list.add(Object[] )
ColumnListHandler 将执行列封装List集合。 List list = {“jack”,“rose”,“tom”};
KeyedHandler 将每一条记录封装到Map<String,Object> A , 在将mapA封装到map B中 , mapB.key 就是指定的key,mapB.value 就是mapa
{
rose={id=1, username=rose, password=9999},
jack={id=2, username=jack, password=1234}
}
MapHandler 将一条记录封装到Map,并返回map
{id=2, username=jack, password=1234}
MapListHandler ,将每一条封装Map中,将Map添加List集合中,返回List集合。
工具类:
DbUtils.commitAndCloseQuietly(conn);
DbUtils.rollbackAndCloseQuietly(conn);
//手动事务
@Test
public void demo09(){
//1 获得连接
Connection conn = null;
try {
conn = JdbcUtils.getConnection();
/**开启事务*/
conn.setAutoCommit(false);
//2核心类
QueryRunner runner = new QueryRunner(); //注意:使用事务时,不传递连接池
//3 删除
int r = runner.update(conn, "delete from t_user where id = ?", 2);
System.out.println(r);
/**提交*/
//conn.commit();
DbUtils.commitAndCloseQuietly(conn);
} catch (Exception e) {
DbUtils.rollbackAndCloseQuietly(conn);
throw new RuntimeException(e);
}
}
4 自定义DbUtils
DbUtils 底层使用PreparedStatement
query方法进行查询,并通过 设置结果集处理类进行相应数据封装。使用策略模式。
1.获得运行时查询结果集中列数,及每一列名称
元数据MetaData,用于描述数据库的数据。
ResultSetMetaData rsMetaData = = rs.getMetaData()
rsMetaData.getColumnCount() , rsMetaData.getColumnName(index)
2. 给javabean封装数据
5 BeanUtils
apache commons 组件一个,用于给javabean进行数据封装的。
导入jar
核心:commons-beanutils-1.8.3.jar
依赖:commons-logging-1.1.1.jar
核心类:BeanUtils
setProperty(bean,name,value) ,给指定的javabean 指定的属性名,设置值。
等效 bean.setName(value)
populate(bean,Map<String,String[]>) 给指定的javabean封装map数据。map.key javabean属性名
类型转换器,定义自定义需求
ConvertUtils.register(converter , Class);
DateConverter dateConverter = new DateConverter();
// * 设置转换格式
//dateConverter.setPattern(“yyyy-MM-dd HH:mm:ss”);
String[] patterns = {“yyyy-MM-dd HH:mm:ss”,“yyyy-MM-dd”};
dateConverter.setPatterns(patterns);
ConvertUtils.register(dateConverter, java.util.Date.class);
6 案例
6.1 名称
客户管理系统:customer manager system (cms)
6.2 功能分析
添加客户
查询所有客户
修改客户
条件查询
分页查询
删除客户
6.3 技术分析
三层系统架构
数据库优化:c3p0连接池
DBUtils ,jdbc简化操作
BeanUtils,javabean数据封装
6.4 环境搭建
6.4.1 导入jar包
6.4.2 包结构
6.4.3 数据库及表
create table t_customer(
id varchar(32) primary key , #UUID
name varchar(50), #姓名
gender char(1), #性别
birthday date, #生日,类型选择: date ,varchar(19) yyyy-MM-dd hh:mm:ss , int getTime() 等
cellphone varchar(11),#电话
email varchar(100), #邮箱
preference varchar(50), #爱好,格式: 1,2,3,4
type varchar(10), #类型
description varchar(500) #描述
);
6.4.4 javabean
private String id;
private String name;
private String gender;
private Date birthday;
private String cellphone;
private String email;
private String preference;
private String type;
private String description;
6.4.5 工具类及配置文件
6.4.5.1 连接池
public class JdbcUtils {
//定义一个连接池
private static DataSource dataSource = new ComboPooledDataSource("day17_cms_xml");
/**
* 获得连接池(数据源)
* @return
*/
public static DataSource getDataSource(){
return dataSource;
}
}
6.4.5.2 javabean封装
6.4.5.3 字符串工具
6.4.6 dao层
使用DbUtils完成
save 、update、delete、findAll、findById