zoukankan      html  css  js  c++  java
  • dbutils---原理以及使用

      原始的操作(增删改)数据库,得到连接后,需要写sql模板,以及设置模板中的参数,其余步骤都相同。

      原始的操作(查单个,以及查所有)数据库,也是得到连接后,写sql模板,以及设置模板中的参数,然后会返回结果集,其余步骤都一样。

    1.dbutils原理

    自己仿写的工具类(部分代码)==可以实现增删改和查

    使用的是c3p0数据库连接池得到的数据库池对象datasource===其实现方法看上篇中的数据库连接池

    package com.xjs.dbutils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import javax.sql.DataSource;
    /**
     * 自己写的一个工具类
     * @author hp
     *
     * @param <T>
     */
    public class QR<T> {
        private DataSource datasource;
    
        public QR() {
            
        }
        public QR(DataSource datasource) {
            this.datasource = datasource;
        }
        /**
         * 做insert、update、delete
         * @param sql
         * @param params
         * @return
         */
        public int update(String sql,Object...params){
            Connection con=null;
            PreparedStatement pstmt=null;
            try {
                //1.通过连接池得到连接对象
                con=datasource.getConnection();
                //2.使用sql创建pstmt
                pstmt=con.prepareStatement(sql);
                //3.给sql模板中的参数赋值
                initParams(pstmt, params);
                    return pstmt.executeUpdate();
                
            } catch (Exception e) {
                throw new RuntimeException(e);
            }finally{//关闭
                try {
                    if(pstmt!=null) pstmt.close();
                    if(con!=null) con.close();
                } catch (SQLException e2) {
                    // TODO: handle exception
                }
            }        //执行sql,返回的是影响的行数
    
        }
        
        //给sql模板中的参数赋值---数组
        private void initParams(PreparedStatement pstmt,Object... params) 
                throws SQLException{
            
            for(int i=0;i<params.length;i++){
                pstmt.setObject(i+1,params[i] );
            }
        }
        //传一个sql模板,一个接口(把结果集封装成JavaBean),SQL模板中的参数
        public T query(String sql,RsHandler<T> rh,Object... params){
            Connection con=null;
            PreparedStatement pstmt=null;
            ResultSet rs=null;
            try {
                //1.通过连接池得到连接对象
                con=datasource.getConnection();
                //2.使用sql创建pstmt
                pstmt=con.prepareStatement(sql);
                //3.给sql模板中的参数赋值
                initParams(pstmt, params);
                //4.执行
                rs=pstmt.executeQuery();
                
                //5.返回  结果集--->对象
                return rh.handle(rs);
                
            } catch (Exception e) {
                throw new RuntimeException(e);
            }finally{//关闭
                try {
                    if(pstmt!=null) pstmt.close();
                    if(con!=null) con.close();
                } catch (SQLException e2) {
                    // TODO: handle exception
                }
            }    
        }
    
    }
    //接口---把结果集给这个接口的这个方法---变成一个对象
    //把结果集转换成需要的类型!---谁调用方法,谁提供其实现
    interface RsHandler<T>{
        public T handle(ResultSet rs) throws SQLException;
    }

    测试:

    package com.xjs.dbutils;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import org.junit.Test;
    
    import com.xjs.jdbc.JdbcUtils;
    
    public class Demo2 {
        @Test
        public void fun1(){
            Stu s=new Stu(1,"zhangSan",23,"男");
            addStu(s);
        }
        
        public void addStu(Stu stu){
            //1.创建对象时给出连接池
            QR qr=new QR(JdbcUtils.getDataSource());
            //2.给出sql模板
            String sql="insert into stu values(?,?,?,?)";
            //3.给出模板中的参数
            Object[] params={stu.getId(),stu.getName(),stu.getAge(),stu.getSex()};
            //4.调用增删改
            qr.update(sql, params);
        }
        
        @Test
        public void fun2(){
            Stu s=load(1);
            System.out.println(s);
        }
        
        public Stu load(int id){
            QR qr=new QR(JdbcUtils.getDataSource());
            String sql="select * from stu where id=?";
            Object[] params={id};
            
            //内部类
            RsHandler<Stu> rh=new RsHandler<Stu>() {
                
                @Override
                public Stu handle(ResultSet rs) throws SQLException {
                    if(!rs.next()) return null;
                    Stu stu=new Stu();
                    stu.setId(rs.getInt("id"));
                    stu.setName(rs.getString("name"));
                    stu.setAge(rs.getInt("age"));
                    stu.setSex(rs.getString("sex"));
                    return stu;
                }
            };
            
            return (Stu)qr.query(sql, rh, params);
            
        }
    }

    2.dbutlis工具类的使用

    使用该工具类需要导包:commons-dbutils-1.4.jar

    QueryRunner核心类:

      update方法:

        * int update(String sql, Object...  params) --->可执行增、删、改语句

        * int update(Connection con, String sql, Object... params)--->需要调用者提供Connection,这说明本方法不再管理Connection了。支持事务!

      query方法:

        * T  query(String sql, ResultSetHandler rsh, Object... params) --->可执行查询

          >它会先得到ResultSet结果集,然后调用rsh的handle()把rs转换成需要的类型!

        * T query(Connection con, String sql, ResultSetHandler rsh, Object... params),支持事务

      ResultSetHandler接口:

        *BeanHandler(单行)--->其接口的实现类,它的构造器需要一个Class类型的参数,用来把一行结果转换成指定类型的JavaBean对象。

        *BeanListHandler(多行)--->构造器需要一个Class类型的参数,用来把一行结果集转换成一个JavaBean,那么多行就是转换成List对象,一堆JavaBean。

        *MapHandler(单行)--->把一行结果集转换Map对象。

          >一行记录:

            id  name  age  sex

            1  金泰妍  31  女

          >一个Map:

            {id:1, name:金泰妍, age:31, sex:女}

        *MapListHandler(多行)--->把一行记录转换成一个Map,多行记录就是多个Map,即List<Map>!

        *ScalarHandler(单行单列)--->通常用于select count(*) from 表名 语句!结果集是单行单列的!它返回一个Object。

    测试1:

    package com.xjs.dbutils;
    
    import java.sql.SQLException;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.junit.Test;
    
    import com.xjs.jdbc.JdbcUtils;
    
    public class Demo3 {
    
        @Test
        public void fun1() throws SQLException{
            QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
            String sql="insert into stu values(?,?,?,?)";
            Object[] params={0,"金泰妍",31,"女"};
            qr.update(sql,params);
        }
        
        @Test
        public void fun2() throws SQLException{
            //1.创建QueryRunner,需要提供数据库连接池对象
            QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
            //2.给出SQL模板
            String sql="select * from stu where id=?";
            //3.给出参数
            Object[] params={0};
            /*
             * 4.执行query()方法,需要给出结果集处理器,即ResultSetHandler的实现类对象
             * 我们给的是BeanHandler,它实现了ResultSetHandler接口
             * 它需要一个类型,然后它会把rs中的数据封装到指定类型的JavaBean对象中,然后返回JavaBean对象。
             */
            Stu s=qr.query(sql, new BeanHandler<Stu>(Stu.class), params);//要求数据库的列名必须和类的属性名一致(保证映射)
            System.out.println(s);
        }
    }

    测试2:

        /*
         * 使用BeanListHandler,返回的是一个List<Map>
         */
        @Test
        public void fun3() throws SQLException{
            QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
            String sql="select * from stu";
            //直接封装成对象的集合
            List<Stu> list = qr.query(sql, new BeanListHandler<Stu>(Stu.class));
            
            for(int i=0;i<list.size();i++){
                System.out.println(list.get(i));
            }
        }
        /*
         * 使用MapHandler的应用,它是单行处理器,把一行记录转换成一个Map对象
         */
        @Test
        public void fun4() throws SQLException{
            QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
            String sql="select * from stu where id=?";
            Object[] params={0};
            Map map= qr.query(sql, new MapHandler(),params);
            System.out.println(map);
        }
        /*
         * 使用MapListHandler,它是多行处理器,把每行都转换成一个Map,即List<Map>
         */
        @Test
        public void fun5() throws SQLException{
            QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
            String sql="select * from stu";
            List<Map<String, Object>> list = qr.query(sql, new MapListHandler());
            
            System.out.println(list);
        }
        /*
         * 使用ScalarHandler
         */
        @Test
        public void fun6() throws SQLException{
            QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());
            String sql="select count(*) from stu";
            //返回值类型在不同的地方是不同的,有Integer、Long、BigInteger
            Object obj= qr.query(sql, new ScalarHandler());
            System.out.println(obj);//2--->行
        }
  • 相关阅读:
    [服务器]Windows Server 2008 64位1核1G安装SQL Server2008
    [工作]离职了!好好休息一下
    [工作]IT连和IT恋产品已完成第一版,准备上线运营
    [SQL Server]储存过程中使用临时表循环操作数据
    [Swift]Xcode格式化代码快捷键
    [Swift]使用Alamofire传递参数时报错
    [工作]记录一下目前的工作
    [Swift]Swift图片显示方式设置,控件UIImageView的contentMode属性设置
    [Swift]创建桥接文件,Swift使用MJRefresh刷新插件
    我遇到了改变的机会
  • 原文地址:https://www.cnblogs.com/xjs1874704478/p/10939764.html
Copyright © 2011-2022 走看看