本文共 10897 字,大约阅读时间需要 36 分钟。
DBUtils 使用:
(1)copy jar包:
(2)核心类: QueryRunner类: (3)使用核心类完成读写,以及批量操作:写:
删除, 更新: 添加: 调用同一个方法: update()package com.yidongxueyuan.test;import java.io.File;import java.io.FileInputStream;import java.io.FileReader;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.sql.Blob;import java.sql.Clob;import java.sql.SQLException;import javax.sql.rowset.serial.SerialBlob;import javax.sql.rowset.serial.SerialClob;import javax.sql.rowset.serial.SerialException;import org.apache.commons.dbutils.QueryRunner;import org.junit.Test;import com.yidongxueyuan.utils.C3P0Util;public class QueryRunnerTest { //修改: 添加 @Test public void testUpdate() throws Exception { //不考虑事务: QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); int num = qr.update("insert into account (id, name, money) values(?,?,?)",new Object[]{1001,"王导演",250} ); System.out.println(num); } //删除操作: @Test public void testdelete() throws Exception { //不考虑事务: QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); int num = qr.update("delete from account where id=?",new Object[]{1001} ); System.out.println(num); } //修改: 自己完成: //操作大数据: 大文本, 大字节: //写入: 大文本 @Test public void testBigText()throws IOException, SerialException, SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); String sql ="insert into t3 values(?,?)"; //使用流进行读取外部的文件; File file = new File("C:\\Users\\Mrzhang\\Desktop\\分页.txt"); Reader reader = new FileReader(file); //读取: char chs []= new char[(int)file.length()]; reader.read(chs);//数据在字符数组当中: //clob这是java当中提供的字符对象: SerialClob clob的是一个实现类: Clob clob = new SerialClob(chs); Object [] params = {2,clob}; qr.update(sql, params); } //写入大字节: @Test public void testBigBlob()throws IOException, SerialException, SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); String sql ="insert into t4 values(?,?)"; //使用流进行读取外部的文件; File file = new File("C:\\Users\\Mrzhang\\Desktop\\01.png"); //字节流读取图片数据: InputStream in = new FileInputStream(file); byte b[]= new byte[(int)file.length()]; //clob这是java当中提供的字符对象: SerialClob clob的是一个实现类: Blob blob = new SerialBlob(b); Object [] params = {2,blob}; qr.update(sql, params); } //批量操作: @Test public void testbatch()throws IOException, SerialException, SQLException{ QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); String sql ="insert into account values(?,?,?)"; Object params [][]= new Object[10][];// 二维数组前面的【】: 记录的条数: 后面的【】是负责: ? 每条记录需要的参数的值: for(int i=0 ; i< params.length ;i++){ params[i]= new Object[]{i+10,"王导演"+i,i+100.0}; } //执行批量 qr.batch(sql, params); ///二维数组: } }
query方法:
各种结果集处理器的使用:
关于处理器是个什么东西,就是各种集合或者javabean的处理器,哪种处理器就封装哪种类型的数据吧。我的理解package com.yidongxueyuan.test;import java.sql.Connection;import java.util.Arrays;import java.util.List;import java.util.Map;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.ArrayHandler;import org.apache.commons.dbutils.handlers.ArrayListHandler;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.ColumnListHandler;import org.apache.commons.dbutils.handlers.KeyedHandler;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 com.yidongxueyuan.domain.Account;import com.yidongxueyuan.utils.C3P0Util;/* * 测试结果处理器: */public class TestResultSet { private QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());//构造的时候,需要指定一个数据源: @Test //ArrayHandler 处理器, 只适应于一条结果的的情况, 将表当中的第一条数据封装到了一个Object[] 数组当中: public void testDemo01() throws Exception { Connection conn= null; try { // conn = C3P0Util.getConnection(); String sql = "select * from account"; //没有参数: //查询操作: Object[] objs = qr.query(sql, new ArrayHandler() ); System.out.println(Arrays.toString(objs));// [1, aaa, 800.0] } catch (Exception e) { // TODO: handle exception } } // ArrayListHandler 适用于有多行的记录, 把每一条记录都封装到了不同的Object[]数组当中。 然后将Object数组放在list集合当中: @Test public void testDemo02() throws Exception { Connection conn= null; try { String sql = "select * from account"; //没有参数: //查询操作: List
这里只放最后一个代码~
其他代码放在github上 ~ ~ . 1: 事务: 操作单元:2: 处理事务:
需求: 转账: 有事务的支持:
三个版本:转账版本一:
QueryRunner 处理事务: query(conn, sql, param); query(conn, sql, param);处理事务:
(1)构建QueryRunner对象的时候,没有必要指定数据源: (2)执行具体方法的时候, 动态的传递一个conn对象: 这样保证了不同的方法使用的conn 对象是同一个对象。 既然是同一个conn 对象, 就可以保证多个操作处于同一个事务当中。总结:
现在将业务方法定义在dao层: dao层定义数据库的访问方法, 不应该定义业务方法。 将业务方法定义在业务层,dao只定义增删改查的方法:转账的 版本二:
优点: 将业务方法定义了业务service层: dao层只定义了和数据库相关的增删改查的方法:具体的操作:
dao层: 保证conn 的唯一: 采用注入的 方式: 有service层给dao层传递conn, 这样就保证了conn 的唯一: 弊端: service 层: 出现了Connection连接对象。 Connection对象是负责连接数据库的, 只能出现dao层, 不应该出现在service层。版本三: 对象: 本地线程局部变量对象: ThreadLocal 本质上一个是一个map 集合:
原理:
public class ThreadLocal{
//存: Map<Runnable,Object> map = new HashMap<Runnerable,Object>();public Object put(Object obj){ map.set( obj); return null; }//取 : public Object get(Object obj){ return map.get()}//移除: public Object remore(){ return map.remove(); }
}
总结: ThreadLocal这个类: 存放和取值的时候, key 都是本地线程:案例: 测试ThreadLocal类:
版本三: 使用ThreadLocal 管理事务:
代码如下:dao层:
package com.yidongxueyuan.dao3;import java.sql.Connection;import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import com.yidongxueyuan.domain.Account;public class DaoImpl implements Dao{ private Connection conn; public DaoImpl (Connection conn){//注入: this.conn = conn; } //依赖QueryRunner private QueryRunner qr = new QueryRunner (); //不需要给出数据源: @Override public Account findByName(String name) { String sql ="select * from account where name=?"; try { Account account = qr.query(conn, sql, new BeanHandler(Account.class),name); return account; } catch (SQLException e) { e.printStackTrace(); } return null; } @Override public void updateAccount(Account account) { String sql="update account set money = ? where name=?"; try { qr.update(conn, sql, account.getMoney(),account.getName()); } catch (SQLException e) { e.printStackTrace(); } } }
事务:
package com.yidongxueyuan.dao3;import java.sql.Connection;import javax.ejb.TransactionManagement;import com.yidongxueyuan.dao2.Dao;import com.yidongxueyuan.dao2.DaoImpl;import com.yidongxueyuan.domain.Account;import com.yidongxueyuan.utils.C3P0Util;import com.yidongxueyuan.utils.TransactionManager;/* * 业务层: 定义具体的业务方法: */public class TransFormer { //定义业务方法: public void transFormer(String SourceAccount,String targetAccount,float money) throws Exception{ Connection conn = TransactionManager.getConnection(); try { Dao dao = new DaoImpl(conn); TransactionManager.startTransaction(); //查询操作: //来源账户: Account sourceAcc = dao.findByName(SourceAccount); sourceAcc.setMoney(sourceAcc.getMoney()-money); //更新获取: dao.updateAccount(sourceAcc); //模拟异常的发生: int num = 1/0; //目标账户修改:更新回去: Account targetAcc = dao.findByName(targetAccount); targetAcc.setMoney(targetAcc.getMoney()+money); dao.updateAccount(targetAcc); } catch (Exception e) { //异常发生: TransactionManager.rollback(); } finally{ TransactionManager.commit(); //关闭资源: TransactionManager.release(); } }}
测试:
package com.yidongxueyuan.dao3;import org.apache.commons.dbutils.QueryRunner;import org.junit.Before;import org.junit.Test;import com.yidongxueyuan.utils.C3P0Util;public class TestTran { private QueryRunner qr = new QueryRunner(C3P0Util.getDataSource()); @Before public void before() throws Exception { // 把数据还原: qr.update("update account set money =1000 "); } @Test public void testname() throws Exception { TransFormer tf = new TransFormer(); tf.transFormer("aaa", "bbb", 100); }}
转载地址:http://mwqen.baihongyu.com/