1. 程式人生 > >dbUtils進行資料庫操作

dbUtils進行資料庫操作

package cn.itcast.test;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;

import cn.itcast.commons.CommonUtils;
import cn.itcast.jdbc.JdbcUtils;
import cn.itcast.jdbc.TxQueryRunner;

/**
 * TxQueryRunner它是QueryRunner的子類!(commons-dbutils.jar)
 *   可用起來與QueryRunner相似的!
 *   我們的類支援事務!它底層使用了JdbcUtils來獲取連線!
 *   
 * 簡化jdbc的操作
 * QueryRunner的三個方法:
 * * update() --> insert、update、delete
 * * query() --> select
 * * batch() --> 批處理
 * @author qdmmy6
 *
 */
public class TxQueryRunnerTest {
	/**
	 * 測試update()方法,用來執行insert、update、delete語句
	 * @throws SQLException
	 */
	@Test
	public void testUpdate() throws SQLException {
		String sql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
		Object[] params = {"1", "p1", 1, "男"};//給sql中對應的引數
		
		QueryRunner qr = new TxQueryRunner();//我們沒有給物件提供連線池
		qr.update(sql, params);//執行sql,也不提供連線,它內部會使用JdbcUtils來獲取連線
	}
	
	/**
	 * 使用事務
	 * @throws SQLException
	 */
	@Test
	public void testUpdate2() throws Exception {
		try {
			JdbcUtils.beginTransaction();//開啟事務
			
			String sql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
			QueryRunner qr = new TxQueryRunner();
			Object[] params = {"2", "p2", 2, "女"};
			qr.update(sql, params);//執行
			
			if(false) {
				throw new Exception();
			}
			
			params = new Object[]{"3", "p3", 3, "女"};
			qr.update(sql, params);//執行			
			
			JdbcUtils.commitTransaction();//提交事務
		} catch(Exception e) {
			try {
				JdbcUtils.rollbackTransaction();//回滾事務
			} catch (SQLException e1) {
			}
			throw e;
		}		
	}
	
	/**
	 * 測試查詢方法
	 *   我們知道JDBC查詢的結果的是ResultSet
	 *   而QueryRunner查詢的結果是通過ResultSet對映後的資料。
	 *     * QueryRunner第一步是執行select,得到ResultSet
	 *     * 把ResultSet轉換成其他型別的!
	 *   通過轉換結果:
	 *      * javaBean:把結果集封裝到javaBean中
	 *      * Map:把結果集封裝到Map中
	 *      * 把結果集封裝到Object中(結果集是單行單列)
	 * @throws SQLException 
	 *      
	 *  
	 */
	/*
	 * 單行結果集對映到javaBean中
	 */
	@Test
	public void testQuery1() throws SQLException {
		String sql = "select * from t_person where pid=?";
		QueryRunner qr = new TxQueryRunner();
		/*
		 * 第二個引數型別為ResultSetHandler,它是一個介面,表示對映的結果型別。
		 * 
		 * BeanHandler --> 它是ResultSetHandler的實現類,它的作用是把結果集封裝到Person物件中
		 */
		Person p = qr.query(sql, new BeanHandler<Person>(Person.class), "1");
		System.out.println(p);
	}
	
	/**
	 * 使用BeanListHandler
	 *   把多行結果集對映到List<Bean>,即多個JavaBean物件。
	 *   一行結果集記錄對應一個javaBean物件,多行就對應List<Bean>
	 * @throws SQLException
	 */
	@Test
	public void testQuery2() throws SQLException {
		String sql = "select * from t_person";
		QueryRunner qr = new TxQueryRunner();
		/*
		 * 第二個引數型別為ResultSetHandler,它是一個介面,表示對映的結果型別。
		 * 
		 * BeanListHandler --> 它是ResultSetHandler的實現類,
		 *   它的作用是把結果集封裝到List<Person>物件中
		 */
		List<Person> list = qr.query(sql, new BeanListHandler<Person>(Person.class));
		System.out.println(list);
	}
	
	/**
	 * 使用MapHandler,把單行結果集封裝到Map物件中
	 * @throws SQLException
	 */
	@Test
	public void testQuery3() throws SQLException {
		String sql = "select * from t_person where pid=?";
		QueryRunner qr = new TxQueryRunner();
		/*
		 * 第二個引數型別為ResultSetHandler,它是一個介面,表示對映的結果型別。
		 * 
		 * BeanListHandler --> 它是ResultSetHandler的實現類,
		 *   它的作用是把結果集封裝到List<Person>物件中
		 */
		Map<String, Object> map = qr.query(sql, new MapHandler(), "1");
		System.out.println(map);
	}
	
	/**
	 * 使用MapListHandler,把多行結果集封裝到List<Map>中,即多個Map
	 *   一行對應一個Map,多行對應List<Map>
	 * @throws SQLException
	 */
	@Test
	public void testQuery4() throws SQLException {
		String sql = "select * from t_person";
		QueryRunner qr = new TxQueryRunner();
		/*
		 * 第二個引數型別為ResultSetHandler,它是一個介面,表示對映的結果型別。
		 * 
		 * BeanListHandler --> 它是ResultSetHandler的實現類,
		 *   它的作用是把結果集封裝到List<Person>物件中
		 */
		List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
		System.out.println(mapList);
	}
	
	/**
	 * 使用ScalarHandler,把單行單列的結果集封裝到Object中
	 * @throws SQLException
	 */
	@Test
	public void testQuery5() throws SQLException {
		String sql = "select count(*) from t_person";//結果集是單行單列的
		QueryRunner qr = new TxQueryRunner();

		Object obj = qr.query(sql, new ScalarHandler());
		/*
		 * 我們知道select count(1),結果一定是個整數!
		 * > Integer
		 * > Long
		 * > BigInteger
		 * 
		 * 不同的驅動,結果不同!
		 * 無論是哪種型別,它都是Number型別!強轉成Number一定不出錯
		 */
		Number number = (Number)obj;
		long cnt = number.longValue();
		System.out.println(cnt);
	}
	
	/**
	 * 一行結果集中包含了兩張表的列
	 * 使用MapHandler來處理
	 * 1. 把結果集封裝到map中
	 * 2. 使用map生成Person物件
	 * 3. 使用map生成address物件
	 * 4. 把兩個實體物件建立關係
	 * @throws SQLException
	 */
	@Test
	public void testQuery6() throws SQLException {
		String sql = "SELECT * FROM t_person p, t_address a WHERE p.aid=a.aid AND p.pid=?";
		QueryRunner qr = new TxQueryRunner();
		/*
		 * 1. 得到Map
		 */
		Map map = qr.query(sql, new MapHandler(), "aaa");
		/*
		 * 2. 把Map中部分資料封裝到Person中
		 */
		Person p = CommonUtils.toBean(map, Person.class);
		/*
		 * 3. 把Map中部分資料封裝到Address中
		 */
		Address addr = CommonUtils.toBean(map, Address.class);
		/*
		 * 4. 建立兩個實體的關係
		 */
		p.setAddress(addr);
		
		System.out.println(p);
	}
}