DBUtils与连接池
DBUtils是java编程中的数据库操作实用工具,小巧简单实用。
DBUtils封装了对JDBC的操作,简化了JDBC操作。可以少写代码。
1.对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
2.对于数据表的写操作,也变得很简单(只需写sql语句)
3.可以使用数据源,使用JNDI,数据库连接池等技术来优化性能--重用已经构建好的数据库连接对象
1.DBUtils的三个核心对象
> QueryRunner类
> ResultSetHandler接口
> DBUtils类
QueryRunner类
QueryRunner中提供对sql语句操作的API
它主要有三个方法
query() 用于执行select
update() 用于执行insert update delete
batch() 批处理
ResultSetHandler接口
用于定义select操作后,怎样封装结果集.
DbUtils类
它就是一个工具类,定义了关闭资源与事务处理的方法
2.Dbutils快速入门
> 1.导入jar包
> 2.创建QueryRunner对象
> 3.使用query方法执行select语句
> 4.使用ResultSetHandler封装结果集
> 5.使用DbUtils类释放资源
原始操作方法(使用ResultSetHandler):
@Test
public void testSelect01() throws Exception{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<User> list =qr.query("select * from bookcard;", new ResultSetHandler<List<User>>(){
//当query方法执行完select语句后,将结果集以参数的形式传递进来
public List<User> handle(ResultSet rs) throws SQLException {
List<User> list = new ArrayList<User>();
while(rs.next()){
User u = new User();
u.setCid(rs.getInt(1));
u.setName(rs.getString(2));
u.setSex(rs.getString(3));
u.setCardDate(rs.getString(4));
u.setDeposit(rs.getDouble(5));
list.add(u);
}
return list;
}});
for(User user :list){
System.out.println(user.toString());
}
}
简化后的操作方法(BeanListHandler implements ResultSetHandler)
@Test
public void testSelect02() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<User> list =qr.query("select * from bookcard where cid=?;", new BeanListHandler<User>(User.class),1001);
for(User user : list){
System.out.println(user.toString());
}
}
3.QueryRunner对象
commons-dbutils-1.4/apidocs/index.html
3.1构造函数
> new QueryRunner(); 它的事务可以手动控制。
也就是说此对象调用的方法(如:query、update、batrch)参数中要有Connection对象。
> new QueryRunner(DataSource ds); 它的事务是自动控制的。一个sql一个事务。
此对象调用的方法(如:query、update、batrch)参数中无需Connection对象。
3.2方法(使用无参构造方法时,调用的方法中参数要有connection)
- <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
- <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
- int update(String sql, Object... params)
- int update(Connection conn, String sql, Object... params)
- int[] batch(String sql, Object[][] params)
- int[] batch(Connection conn, String sql, Object[][] params)
例:
public class TestCRUD {
@Test
public void testSelect() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<User> list =qr.query("select * from bookcard where cid=?;", new BeanListHandler<User>(User.class),1001);
for(User user : list){
System.out.println(user.toString());
}
}
@Test
public void testInsert() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
qr.update("insert into bookcard(cid,name,sex,cardDate,deposit) values(?,?,?,?,?)",1004,"小小","男","2019-01-01",404);
}
@Test
public void testUpdate() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
qr.update("update bookcard set name=?,sex=? where cid=?;","消亡","女",1004);
}
@Test
public void testDelete() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
qr.update("delete from bookcard where cid=?",1004);
}
@Test
public void testBatch() throws SQLException{
//只能执行相同类型的sql语句
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
Object[][] params = new Object[5][];//高维代表执行多少次sql语句
for(int i=0;i<5;i++){
params[i]= new Object[]{"小王0"+i,"男","2010-10-10",406}; //给每次执行sql语句中的?赋值
}
qr.batch("insert into bookcard(name,sex,cardDate,deposit) values(?,?,?,?)", params);
}
}
4.ResultSetHandler接口
ResultSetHandler下的所有结果处理器(9个类):ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[]
ArrayListHandler:适合取多条记录。把每条记录的每列值封装到一个数组中Object[],把数组封装到一个List中
ColumnListHandler:取某一列的数据。封装到List中。
KeyedHandler:取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另外一个Map中,key为指定的字段值。
MapHandler:适合取1条记录。把当前记录的列名和列值放到一个Map中
MapListHandler:适合取多条记录。把每条记录封装到一个Map中,再把Map封装到List中
ScalarHandler:适合取单行单列数据
BeanHandler:适合单行数据的查询
BeanListHandler:最常用的方式
@Test//ArrayHandler:适合取1条记录。把该记录的每列值封装到一个数组Object[]中
public void test01() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
//Object[] arr=qr.query("select * from bookcard where cid=?;", new ArrayHandler(),1002);
Object[] arr = qr.query("select * from bookcard;", new ArrayHandler());
for(Object o : arr){
System.out.println(o);
}
}
@Test//ArrayListHandler:适合取多条记录。把每条记录的每列值封装到一个数组Object[]中,把数组封装到一个List中
public void test02() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<Object[]> list =qr.query("select * from bookcard;", new ArrayListHandler());
for(Object[] obj : list){
for(Object o : obj){
System.out.println(o);
}
System.out.println("------------------------------");
}
}
@Test//ColumnListHandler:取某一列的数据,封装到List中。
public void test03() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<Object> list =qr.query("select cid,name from bookcard;", new ColumnListHandler(2));
for(Object o : list){
System.out.println(o);
}
}
@Test //KeyedHandler:取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另一个Map中,key为指定的字段值。
public void test04() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
Map<Object, Map<String, Object>> map =qr.query("select * from bookcard;", new KeyedHandler(1));
for(Map.Entry<Object, Map<String,Object>> m : map.entrySet()){
for(Map.Entry<String, Object> mm : m.getValue().entrySet()){
System.out.println(mm.getKey()+"\t"+mm.getValue());
}
System.out.println("------------------------");
}
}
@Test//MapHandler:适合取一条记录,把当前记录的列名和列值放到一个Map中
public void test05() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
Map<String, Object> map =qr.query("select * from bookcard where cid=?", new MapHandler(),1002);
for(Map.Entry<String, Object> m : map.entrySet()){
System.out.println(m.getKey()+"\t"+m.getValue());
}
}
@Test //MapListHandler:适合取多条记录,把每条记录封装到一个Map中,再把Map封装到List中。
public void test06() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<Map<String, Object>> list =qr.query("select * from bookcard;", new MapListHandler());
for(Map<String,Object> map : list){
for(Map.Entry<String, Object> m : map.entrySet()){
System.out.println(m.getKey()+"\t"+m.getValue());
}
System.out.println("--------------------");
}
}
@Test //ScalarHandler:适合取单行单列数据
public void test07() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
Object object = qr.query("select name from bookcard where cid=?;", new ScalarHandler(1),1002);
System.out.println(object);
}
@Test //BeanHandler:适合单行数据的查询
public void test08() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
User user =qr.query("select * from bookcard;", new BeanHandler<User>(User.class));
System.out.println(user);
}
@Test //BeanListHandler
public void test09() throws SQLException{
QueryRunner qr = new QueryRunner(C3P0Util.getDatesource());
List<User> list =qr.query("select * from bookcard;", new BeanListHandler<User>(User.class));
for(User user: list){
System.out.println(user);
}
}
5.ThreadLocal(作用:只有当前线程能够访问到存放的变量,适用与进行事务的处理操作)
模拟ThreadLocal的设计:调用该类的get方法,永远返回当前线程放入的数据。线程局部变量。
public class ThreadLocal{
private Map<Runnable,Object> container = new HashMap<Runnable,Object>();
public void set(Object value){
container.put(Thread.currentThread(),value);//用当前线程作为key
}
public Object get(){
return container.get(Thread.currentThread());
}
public void remove(){
container.remove(Thread.currentThread());
}
}
例如:进行转账操作:点击打开链接