Dbutils小框架-数据库操作实用工具学习总结(包括本地线程、事务)

重点

1.简介

 DBUtils是java编程中的数据库操作实用工具,小巧简单实用。
 DBUtils封装了对JDBC的操作,简化了JDBC操作。可以少写代码。
1.对于数据表的读操作,他可以把结果转成List,Array,Set等java集合,便于程序员操作;
2.对于数据表的写操作,也变得很简单(只需写sql语句)
3.可以使用数据源,使用JNDI,数据库连接池等技术来优化性能–重用已经构建好的数据库连接对象

2. 3个核心对象

2.1QueryRunner类

 QueryRunner中提供对sql语句操作的API.
 它主要有三个方法
query() 用于执行select
update() 用于执行insert update delete
batch() 批处理

3.ResultSetHandler下的处理器(结果集处理器)

/*ArrayHandler
	适合取1条记录。把该条记录的每列值封装到一个数组中Object[]*/
	@Test
	public void test1() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		 Object[]  objs = qr.query("select * from Account where id = 1", new ArrayHandler());
		
		 for(Object o : objs){
			 System.out.println(o);
		 }
	}
	
	/*ArrayListHandler
	适合取多条记录。把每条记录的每列值封装到一个数组中Object[],把数组封装到一个List中
*/
	@Test
	public void test2() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		 List<Object[]> list = qr.query("select * from Account", new ArrayListHandler());
		
		 for(Object[] hangs : list){
			 System.out.println("------");
			 for(Object object : hangs){
				 System.out.println(object);
			 }
		 }
	}
	/*ColumnListHandler
	取某一列的数据。封装到List中。
*/
	@Test
	public void test3() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		List<Object> list = qr.query("select * from Account",new ColumnListHandler(3));
		
		for(Object object : list){
			System.out.println(object);
		}
		 
	}
	
	/*KeyedHandler
	取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另外一个Map中,key为指定的字段值.默认第一个为KEY。
	*/

	@Test
	public void test4() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		Map<Object, Map<String, Object>> map = qr.query("select * from Account",new KeyedHandler());
		
		for(Entry<Object, Map<String, Object>> jilus : map.entrySet()){
			System.out.println(jilus.getKey());
			for(Entry<String, Object> object : jilus.getValue().entrySet()){
				System.out.println(object.getKey()+":"+object.getValue());
			}
		}
		System.out.println("-----------");
		
	}
	
	/*MapHandler
	适合取1条记录。把当前记录的列名和列值放到一个Map中
	*/
	@Test
	public void test5() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		Map<String, Object> map = qr.query("select * from Account where id = 3",new MapHandler());
		
		for(Entry<String, Object> entry : map.entrySet()){
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
		 
		
	}
	
	/*MapListHandler
	适合取多条记录。把每条记录封装到一个Map中,再把Map封装到List中*/

	@Test
	public void test6() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		List<Map<String, Object>> list = qr.query("select * from Account",new MapListHandler());
		
		for(Map<String, Object> map : list){
			System.out.println("---------------------");
			for(Entry<String, Object> jilu : map.entrySet()){
				System.out.println(jilu.getKey()+":"+jilu.getValue());
			}
		}
		 
		
	}
	
	/*ScalarHandler
	适合取单行单列数据
*/
	@Test
	public void test7() throws SQLException{
		//创建QueryRunner对象
		QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		//执行query
		Object object = qr.query("select * from Account",new ScalarHandler());
		
		System.out.println(object);
	}
	
	/*BeanHandler
	适合取单行多列数据
*/
	@Test
	public void test8() throws SQLException{
		//创建QueryRunner对象
		 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		
		//执行query
		 Account account =  qr.query("select * from Account",new BeanHandler<Account>(Account.class));
		 
		 System.out.println(account);
	}
	
	/*BeanListHandler (常用)
	适合多行多列
*/
	@Test
	public void test9() throws SQLException{
		//创建QueryRunner对象
		 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
		
		//执行query
		 List<Account> accounts =  qr.query("select * from Account",new BeanListHandler<Account>(Account.class));
		 
		for(Account account : accounts){
			System.out.println(account);
		}
	}

4.ThreadLocal【本地线程】

使用方法:

private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
	
	public static Connection getConnection(){
		try {
			Connection conn = tl.get();
			
			if (conn == null) {
		
				conn = C3P0Utils.getConnection();
				tl.set(conn);
				System.out.println("第一次从数据源获取Connection对象"+conn);
				
			} else {
				//System.out.println("第n次从ThreadLocal获取Connection对象");
			}
			return conn;
			
		}catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 开启事务
	 */
	public static void beginTransaction() {
		try {
			getConnection().setAutoCommit(false);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 回滚事务
	 */
	public static void rollbackTransaction() {
		 try {
			getConnection().rollback();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 提交事务
	 */
	public static void commitTransaction() {
		try {
			getConnection().commit();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 关闭事务
	 */
	public static void close() {
		try {
			getConnection().close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

总结:调用该类的get方法,永远返回当前线程放入的数据。后面的练习1,方法三,使用本地线程调用连接,创建事务,优化了代码。

练习

1.转帐案例

方式一:无事务
Dbutils小框架-数据库操作实用工具学习总结(包括本地线程、事务)_第1张图片
方式二 添加事务
Dbutils小框架-数据库操作实用工具学习总结(包括本地线程、事务)_第2张图片
方法三:有事务,在Service中不显示Connection,结合了ThreadLocal【本地线程】的优点(推荐使用)
Dbutils小框架-数据库操作实用工具学习总结(包括本地线程、事务)_第3张图片
Dbutils小框架-数据库操作实用工具学习总结(包括本地线程、事务)_第4张图片

总结

通过这个小框架的学习,优化了Dao层JDBC的操作,少写了不少代码,主要使用了框架的QueryRunner对象,让后利用了他的query,update方法,只用两行代码解决了以前的十几行代码,确实很方便,提高了开发效率,从转账案例里面,我学到了很多,比如创建来连接这个问题,一开始在DaoImpl里面写构造方法传连接,在ServiceImpl里面调用DaoImpl构造方法,传连接参数,太麻烦了,后面通过本地线程绑定连接的方法,实现了连接共享,简化了很多的代码,总之:利用线程池技术解决了多个连接的效率,BeanUtils封装了请求参数为模型,Dbutils框架简化了JDBC的代码,本地线程解决了线程共享的问题。遇到批处理sql或者连续执行多条sql时,为了保证数据的完整性,需要用到事务,用ThreadLocal【本地线程】创建,简化了创建connection。相信后面更多框架的学习,能高效的开发,web开发的关键,要知道数据的流向。

你可能感兴趣的:(JavaEE)