目录
一、什么是DBUtil
Commons DBUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能
二、DBUtil的增删改
Account是一个与数据库对应的pojo类,有id、name、money三个属性
@Test
public void testInsert() throws SQLException, InstantiationException, IllegalAccessException{
//dbutils 只是帮我们简化了CRUD 的代码, 但是连接的创建以及获取工作。 不在他的考虑范围
QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
//增加
queryRunner.update("insert into account values (null , ? , ? )", "zhaoliu" ,1000);
//删除
queryRunner.update("delete from account where id = ?", 5);
//更新
queryRunner.update("update account set money = ? where id = ?", 2000 , 6);
}
三、DBUtil的查询
1.直接new接口的匿名实现类
@Test
public void testInsert() throws SQLException, InstantiationException, IllegalAccessException{
//去执行查询,查询到的数据还是在result里面。 然后调用下面的handle方法,由用户手动去封装。
Account account = queryRunner.query("select * from account where id = ?", new ResultSetHandler<Account>(){
@Override
public Account handle(ResultSet rs) throws SQLException {
Account account = new Account();
while(rs.next()){
account.setName(nrs.getString("name"));
account.setMoney(rs.getInt("money"));
}
return account;
}
}, 6);
System.out.println(account.toString());
}
2.直接使用框架已经写好的实现类
- 查询单个对象:
//创建 QueryRunner 对象
QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
//查询单个对象
Account account = queryRunner.query("select * from account where id = ?", new BeanHandler<Account>(Account.class), 8);
- 查询多个对象:
QueryRunner queryRunner = new QueryRunner(new ComboPooledDataSource());
List<Account> list = queryRunner.query("select * from account ",new BeanListHandler<Account>(Account.class));
四、ResultSetHandler 常用的实现类
- BeanHandler,:查询到的单个数据封装成一个对象
- BeanListHandler:查询到的多个数据封装 成一个List<对象>
- ArrayHandler,:查询到的单个数据封装成一个数组
- ArrayListHandler:查询到的多个数据封装成一个集合 ,集合里面的元素是数组。
- MapHandler:查询到的单个数据封装成一个map
- MapListHandler:查询到的多个数据封装成一个集合 ,集合里面的元素是map。
五、编写自己的DBUtil(DBUtil的内部实现原理)
1.通用的增删改方法
- 以参数个数为主:
//通用的增删改功能
/**
* 以参数个数为准
* @param sql 需要操作的sql语句
* @param args 可变参数, 有几个占位符,就写几个参数进来。
*/
public void update(String sql ,Object ... args) {
Connection conn = null;
PreparedStatement ps=null;
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
//因为不知道是什么类型的数据,所以都使用setObject来对待。
ps.setObject(i+1, args[i]);
}
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
}
- 以 ?个数为主:
为了防止 update("update account set money = ? where id = ?" , 9 ,8,19,10,10,10); 这种情况出现,?个数与可变参数的个数不符,以参数为主可能发生错误。
/**
* 以 ? 个数为准 防止写了多余的参数
* @param sql 需要操作的sql语句
* @param args 可变参数, 有几个占位符,就写几个参数进来。
*/
public void update02(String sql ,Object ... args) {
Connection conn = null;
PreparedStatement ps=null;
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
//元数据
//获取到有几个问号,占位符
ParameterMetaData metaData = ps.getParameterMetaData();
int count = metaData.getParameterCount();
for (int i = 0; i < count; i++) {
//因为不知道是什么类型的数据,所以都使用setObject来对待。
ps.setObject(i+1, args[i]);
}
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
}
什么是元数据?
描述数据的数据 String sql , 描述这份sql字符串的数据叫做元数据
- 数据库元数据 DatabaseMetaData
- 参数元数据 ParameterMetaData
- 结果集元数据 ResultSetMetaData
2.通用的查询方法
public <T> T query(String sql , ResultSetHandler<T> handler, Object ...args ){
Connection conn = null;
PreparedStatement ps=null;
try {
conn = JDBCUtil.getConn();
ps = conn.prepareStatement(sql);
//获取到有几个问号,占位符
ParameterMetaData metaData = ps.getParameterMetaData();
int count = metaData.getParameterCount();
for (int i = 0; i < count; i++) {
//因为不知道是什么类型的数据,所以都使用setObject来对待。
ps.setObject(i+1, args[i]);
}
//执行查询工作, 然后得到结果集
ResultSet rs = ps.executeQuery();
//把结果集丢给调用者,让它去封装数据 ,返回封装数据
T t = (T) handler.handle(rs);
return t;
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
return null;
}
public interface ResultSetHandler<T> {
/**
* 定义了数据封装的规则。 规范。
* @param <T>
* @param rs
*/
T handle(ResultSet rs);
}