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)
1 @Test 2 3 public void testSelect01() throws Exception{ 4 5 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 6 7 List<User> list =qr.query("select * from bookcard;", new ResultSetHandler<List<User>>(){ 8 9 //当query方法执行完select语句后,将结果集以参数的形式传递进来 10 11 public List<User> handle(ResultSet rs) throws SQLException { 12 13 List<User> list = new ArrayList<User>(); 14 15 while(rs.next()){ 16 17 User u = new User(); 18 19 u.setCid(rs.getInt(1)); 20 21 u.setName(rs.getString(2)); 22 23 u.setSex(rs.getString(3)); 24 25 u.setCardDate(rs.getString(4)); 26 27 u.setDeposit(rs.getDouble(5)); 28 29 list.add(u); 30 31 } 32 33 return list; 34 35 }}); 36 37 38 39 for(User user :list){ 40 41 System.out.println(user.toString()); 42 43 } 44 45 }
简化后的操作方法(BeanListHandler implements ResultSetHandler)
1 @Test 2 public void testSelect02() throws SQLException{ 3 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 4 List<User> list =qr.query("select * from bookcard where cid=?;", new BeanListHandler<User>(User.class),1001); 5 for(User user : list){ 6 System.out.println(user.toString()); 7 } 8 }
3.QueryRunner对象
commons-dbutils-1.4/apidocs/index.html
new QueryRunner(); 它的事务可以手动控制。
也就是说此对象调用的方法(如:query、update、batrch)参数中要有Connection对象
new QueryRunner(DataSource ds); 它的事务是自动控制的。一个sql一个事务。
此对象调用的方法(如:query、update、batrch)参数中无需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)
1 public class TestCRUD { 2 @Test 3 public void testSelect() throws SQLException{ 4 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 5 List<User> list =qr.query("select * from bookcard where cid=?;", new BeanListHandler<User>(User.class),1001); 6 for(User user : list){ 7 System.out.println(user.toString()); 8 } 9 } 10 @Test 11 public void testInsert() throws SQLException{ 12 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 13 qr.update("insert into bookcard(cid,name,sex,cardDate,deposit) values(?,?,?,?,?)",1004,"小小","男","2019-01-01",404); 14 15 } 16 17 @Test 18 public void testUpdate() throws SQLException{ 19 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 20 qr.update("update bookcard set name=?,sex=? where cid=?;","消亡","女",1004); 21 } 22 23 @Test 24 public void testDelete() throws SQLException{ 25 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 26 qr.update("delete from bookcard where cid=?",1004); 27 } 28 29 @Test 30 public void testBatch() throws SQLException{ 31 //只能执行相同类型的sql语句 32 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 33 Object[][] params = new Object[5][];//高维代表执行多少次sql语句 34 for(int i=0;i<5;i++){ 35 params[i]= new Object[]{"小王0"+i,"男","2010-10-10",406}; //给每次执行sql语句中的?赋值 36 } 37 qr.batch("insert into bookcard(name,sex,cardDate,deposit) values(?,?,?,?)", params); 38 } 39 }
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:最常用的方式
1 @Test//ArrayHandler:适合取1条记录。把该记录的每列值封装到一个数组Object[]中 2 3 public void test01() throws SQLException{ 4 5 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 6 7 //Object[] arr=qr.query("select * from bookcard where cid=?;", new ArrayHandler(),1002); 8 9 Object[] arr = qr.query("select * from bookcard;", new ArrayHandler()); 10 11 for(Object o : arr){ 12 13 System.out.println(o); 14 15 } 16 17 } 18 19 20 21 @Test//ArrayListHandler:适合取多条记录。把每条记录的每列值封装到一个数组Object[]中,把数组封装到一个List中 22 23 public void test02() throws SQLException{ 24 25 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 26 27 List<Object[]> list =qr.query("select * from bookcard;", new ArrayListHandler()); 28 29 for(Object[] obj : list){ 30 31 for(Object o : obj){ 32 33 System.out.println(o); 34 35 } 36 37 System.out.println("------------------------------"); 38 39 } 40 41 } 42 43 44 45 @Test//ColumnListHandler:取某一列的数据,封装到List中。 46 47 public void test03() throws SQLException{ 48 49 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 50 51 List<Object> list =qr.query("select cid,name from bookcard;", new ColumnListHandler(2)); 52 53 for(Object o : list){ 54 55 System.out.println(o); 56 57 } 58 59 } 60 61 62 63 @Test //KeyedHandler:取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另一个Map中,key为指定的字段值。 64 65 public void test04() throws SQLException{ 66 67 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 68 69 Map<Object, Map<String, Object>> map =qr.query("select * from bookcard;", new KeyedHandler(1)); 70 71 for(Map.Entry<Object, Map<String,Object>> m : map.entrySet()){ 72 73 for(Map.Entry<String, Object> mm : m.getValue().entrySet()){ 74 75 System.out.println(mm.getKey()+" "+mm.getValue()); 76 77 } 78 79 System.out.println("------------------------"); 80 81 } 82 83 } 84 85 86 87 @Test//MapHandler:适合取一条记录,把当前记录的列名和列值放到一个Map中 88 89 public void test05() throws SQLException{ 90 91 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 92 93 Map<String, Object> map =qr.query("select * from bookcard where cid=?", new MapHandler(),1002); 94 95 for(Map.Entry<String, Object> m : map.entrySet()){ 96 97 System.out.println(m.getKey()+" "+m.getValue()); 98 99 } 100 101 } 102 103 104 105 @Test //MapListHandler:适合取多条记录,把每条记录封装到一个Map中,再把Map封装到List中。 106 107 public void test06() throws SQLException{ 108 109 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 110 111 List<Map<String, Object>> list =qr.query("select * from bookcard;", new MapListHandler()); 112 113 for(Map<String,Object> map : list){ 114 115 for(Map.Entry<String, Object> m : map.entrySet()){ 116 117 System.out.println(m.getKey()+" "+m.getValue()); 118 119 } 120 121 System.out.println("--------------------"); 122 123 } 124 125 } 126 127 128 129 @Test //ScalarHandler:适合取单行单列数据 130 131 public void test07() throws SQLException{ 132 133 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 134 135 Object object = qr.query("select name from bookcard where cid=?;", new ScalarHandler(1),1002); 136 137 System.out.println(object); 138 139 } 140 141 142 143 @Test //BeanHandler:适合单行数据的查询 144 145 public void test08() throws SQLException{ 146 147 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 148 149 User user =qr.query("select * from bookcard;", new BeanHandler<User>(User.class)); 150 151 System.out.println(user); 152 153 } 154 155 156 157 @Test //BeanListHandler 158 159 public void test09() throws SQLException{ 160 161 QueryRunner qr = new QueryRunner(C3P0Util.getDatesource()); 162 163 List<User> list =qr.query("select * from bookcard;", new BeanListHandler<User>(User.class)); 164 165 for(User user: list){ 166 167 System.out.println(user); 168 169 } 170 171 }
5.ThreadLocal(作用:只有当前线程能够访问到存放的变量,适用与进行事务的处理操作)
模拟ThreadLocal的设计:调用该类的get方法,永远返回当前线程放入的数据。线程局部变量。
1 public class ThreadLocal{ 2 3 private Map<Runnable,Object> container = new HashMap<Runnable,Object>(); 4 5 6 7 public void set(Object value){ 8 9 10 11 container.put(Thread.currentThread(),value);//用当前线程作为key 12 13 } 14 15 16 17 public Object get(){ 18 19 20 21 return container.get(Thread.currentThread()); 22 23 } 24 25 26 27 public void remove(){ 28 29 30 31 container.remove(Thread.currentThread()); 32 33 } 34 35 }