Java -- DBUtils 框架 操作MySQL数据库

1. 增删改查 常用Handler处理器示例

QueryRunner类提供了两个构造方法:
默认的构造方法
需要一个 javax.sql.DataSource来作参数的构造方法。
 
public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理PreparedStatementResultSet 的创建和关闭
public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException: 几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource)或使用的setDataSource方法中重新获得Connection
public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException :执行一个不需要置换参数的查询操作。
public int update(Connection conn, String sql, Object[] params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
public int update(Connection conn, String sql) throws SQLException:用来执行一个不需要置换参数的更新操作。
 
ResultSetHandler 接口的实现类
ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
public class Demo1 {

	/**
	 create database dbutils;
	 use dbutils;
	 create table user(
	 	id int primary key auto_increment,
	 	name varchar(40),
	 	password varchar(40),
	 	email varchar(60),
	 	birthday date
	 );
	 insert into user(name,password,email,birthday) values('zs','123','xj@qq.com','1990-06-27');
	 insert into user(name,password,email,birthday) values('ls','123','xj@qq.com','1990-06-27');
	 insert into user(name,password,email,birthday) values('ww','123','xj@qq.com','1990-06-27');
	 * @throws SQLException 
	 */
	
	@Test
	public void add() throws SQLException  
	{
		//创建QueryRunner时带 连接池,获得的连接 用完后会自动归还到连接池
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "insert into user(name,password,email,birthday) values(?,?,?,?)";
		Object[] params = {"kevin", "12345", "xj@163.com", new Date()};
		qr.update(sql, params);
	}

	@Test
	public void delete() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "delete from user where id=?";	
		qr.update(sql, 1);
	}
	
	@Test
	public void update() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "update user set name=? where id=?";
		Object[] params = {"xiangjie", 2};
		qr.update(sql, params);
	}
	
	@Test
	public void find() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from user where id=?";	
		Object[] params = {2};
		User user = (User) qr.query(sql, new BeanHandler(User.class), params);
		System.out.println(user.getName());
	}
	
	@Test
	public void getAll() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from user";			
		List list = (List) qr.query(sql, new BeanListHandler(User.class));
		System.out.println(list.size());
	}
	
	@Test
	public void testBatch() throws SQLException //SQL批处理
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "insert into user(name,password,email,birthday) values(?,?,?,?)";
		Object[][] params = new Object[10][];
		for(int i=0; i<10; i++)
		{
			params[i] = new Object[]{"xx"+i, "123456", "xj@qq.com", new Date()};			
		}
		qr.batch(sql, params);
	}
	
	
	// dbutils 存储大文本 (不建议使用,无缓存,文本被直接放到内存,很大文本直接用JDBC)
	/*
	  create table testclob
	  (
	  	id int primary key auto_increment,
	  	resume text
	  );
	 */
	@Test
	public void testclob() throws IOException, SerialException, SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String path = Demo1.class.getClassLoader().getResource("test.txt").getPath();
		String sql = "insert into testclob(resume) values(?)";
		FileReader in  =new FileReader(path);
		char[] buffer = new char[(int) new File(path).length()];
		in.read(buffer);
		SerialClob clob = new SerialClob(buffer);
		Object[] params = {clob};
		qr.update(sql, params);
	}
	
	/*
	 *  dbutils 提供的 handler 处理器
	 */
	@Test
	public void testArrayHandler() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from  user";
		Object[] result =  (Object[]) qr.query(sql, new ArrayHandler());
		System.out.println(Arrays.asList(result));
	}
	
	@Test
	public void testArrayListHandler() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from  user";
		List<Object[]> list  =  (List<Object[]>) qr.query(sql, new ArrayListHandler());
		for(Object[] obj : list)		
			System.out.println(Arrays.asList(obj));
	}
	
	@Test
	public void testKeyedHandler() throws SQLException 
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from  user";
		
		Map<Integer, Map> map =  (Map<Integer, Map>) qr.query(sql, new KeyedHandler("id"));
		for(Map.Entry<Integer, Map> me : map.entrySet())
		{
			int id = me.getKey();
			Map<String, Object> innermap = me.getValue();
			for(Map.Entry<String , Object> innerme : innermap.entrySet() )
			{
				String columnName = innerme.getKey();
				Object value = innerme.getValue();
				System.out.println(columnName + "=" + value);
			}
			System.out.println("-----------------");
		}
	}
	
	@Test
	public void testMapHandler() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from  user";
		
		Map<String, Object> map = (Map<String, Object>) qr.query(sql, new MapHandler());
		for(Map.Entry<String , Object> entry : map.entrySet())
		{
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
	}
	
	@Test
	public void testMapListHandler() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from  user";
		
		List<Map<String, Object>> list = (List<Map<String, Object>>) qr.query(sql, new MapListHandler());
		for(Map<String, Object> map : list)
		{
			for(Map.Entry<String, Object> entry : map.entrySet())
			{
				System.out.println(entry.getKey() + "=" + entry.getValue());
			}
			System.out.println("------------------");
		}	
	}
	
	@Test 
	public void testScalarHandler() throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select count(*) from  user";
		long L =  (Long) qr.query(sql, new ScalarHandler(1));
		int count = (int) L;
		System.out.println("count: " + count);
	}
}


2. 事务操作

方式一: 能实现功能,但不实用

dao层 提供增删改查,共用一个connect

/*
  create table account(
  	id int primary key auto_increment,
  	name varchar(40),
  	money float
  );
  
  insert into account(name,money) values('aaa',1000);
  insert into account(name,money) values('bbb',1000);
  insert into account(name,money) values('ccc',1000);
  insert into account(name,money) values('ddd',1000);
 */

public class AccountDao {
		
	private Connection conn = null;
	public AccountDao(Connection conn)
	{
		this.conn = conn;
	}
	
	/*
	public void transfer() throws SQLException //不实用
	{
		Connection conn = null;
		
		try {
			conn = JdbcUtils_C3P0.getConnection();
			conn.setAutoCommit(false);
			QueryRunner qr = new QueryRunner();
			String sql1  = "update account set money=money-100 where id=1";
			String sql2  = "update account set money=money+100 where id=2";
			
			qr.update(conn, sql1);
			qr.update(conn, sql2);
			conn.commit();
			System.out.println("transfer success");			
		} catch (SQLException e) {
			conn.rollback();
			e.printStackTrace();
		}finally{
			conn.close();
		}				
	}
	*/
	
	
	public void update(Account account) throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "update account set name=?,money=? where id=?";
		Object[] params = {account.getName(), account.getMoney(), account.getId()};
		qr.update(conn, sql, params);
	}
	
	public Account find(int id) throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from account where id=?";			
		return  (Account) qr.query(conn, sql, id, new BeanHandler(Account.class));
	}
}

Service层 提供transfer方法, 操作事务

public class AccountService {

	public void transfer(int sourceid, int targetid, float money) throws SQLException 
	{
		Connection conn = null;
		
		try {
			conn = JdbcUtils_C3P0.getConnection();
			conn.setAutoCommit(false);
			AccountDao dao = new AccountDao(conn);
			
			Account source = dao.find(sourceid);
			Account target = dao.find(targetid);
			source.setMoney(source.getMoney()-money);
			target.setMoney(target.getMoney()+money);
			
			dao.update(source);
			dao.update(target);
			conn.commit();
			
		} catch (SQLException e) {
			if(conn!=null)
				conn.rollback();		
		}finally{
			if(conn!=null)
				conn.close();
		}	
	}	
}


方式二: 利用ThreadLocal容器存储Connection, 实用方案

service层

public class AccountService {

	public void transfer(int sourceid, int targetid, float money) throws SQLException 
	{		
		try {
			
			JdbcUtils_C3P0.startTransaction(); //利用工具类, 开启事务
 			
			AccountDao dao = new AccountDao();
			
			Account source = dao.find(sourceid);
			Account target = dao.find(targetid);
			source.setMoney(source.getMoney()-money);
			target.setMoney(target.getMoney()+money);
			
			dao.update(source);
			//int i=1/0; //制造异常中断
			dao.update(target);
		
			JdbcUtils_C3P0.commit();
		} catch (SQLException e) {
			e.printStackTrace();
			JdbcUtils_C3P0.rollback();  //回滚
		}finally{
			JdbcUtils_C3P0.release(); //释放连接
		}	
	}	
}

Dao层

public class AccountDao {
		
	private Connection conn = null;
	public AccountDao(Connection conn)
	{
		this.conn = conn;
	}
	
	public AccountDao(){} 
			
	public void update(Account account) throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "update account set name=?,money=? where id=?";
		Object[] params = {account.getName(), account.getMoney(), account.getId()};
		qr.update(JdbcUtils_C3P0.getConnection(), sql, params); //利用工具类获得连接
	}
	
	public Account find(int id) throws SQLException
	{
		QueryRunner qr = new QueryRunner(JdbcUtils_C3P0.getDataSource());
		String sql = "select * from account where id=?";			
		return  (Account) qr.query(JdbcUtils_C3P0.getConnection(), sql, id, new BeanHandler(Account.class));
	}
}

工具类:

public class JdbcUtils_C3P0 {

	private static ComboPooledDataSource ds = null;
	private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();  //Threadlocal容器
	static{
		ds = new ComboPooledDataSource("c3p0config");			
	}
		
	public static Connection getConnection() throws SQLException{
		
		Connection conn = threadLocal.get();
		if(conn==null)
		{
			conn = getDataSource().getConnection();
			threadLocal.set(conn);
		}			
		return conn;
	}
	
	public static DataSource getDataSource()
	{
		return ds;
	}
	
	public static void startTransaction()
	{
		Connection conn = threadLocal.get();
		try{
			if(conn == null)
			{
				conn = getDataSource().getConnection();
				threadLocal.set(conn);
			}
			conn.setAutoCommit(false);
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public static void rollback()
	{
		try
		{
			Connection conn = threadLocal.get();
			if(conn!=null)
				conn.rollback();
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public static void commit()
	{
		try
		{
			Connection conn = threadLocal.get();
			if(conn!=null)
				conn.commit();
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public static void release()
	{
		try
		{
			Connection conn = threadLocal.get();
			if(conn!=null)
			{
				conn.close();
				threadLocal.remove();
			}
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
}

工具类C3P0配置文档

<?xml version="1.0" encoding="UTF-8"?>

<!--
c3p0-config.xml
private static ComboPooledDataSource ds;
static{
	try {
		ds = new ComboPooledDataSource("c3p0config");
	} catch (Exception e) {
		throw new ExceptionInInitializerError(e);
	}
}
-->

<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/transaction</property>
		<property name="user">root</property>
		<property name="password">123456</property>
		
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">100</property>
		
		
	</default-config>

	<named-config name="c3p0config">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/dbutils</property>
		<property name="user">root</property>
		<property name="password">123456</property>
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">100</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
	</named-config>

</c3p0-config>





 

 

 

 

 

posted @ 2013-12-20 16:30  今晚打酱油_  阅读(313)  评论(0编辑  收藏  举报