JavaWeb笔记-19-DBUtils处理结果集之QueryRunner类、 方法使用及内部机制

common-dbutils.jar

1、QueryRunner :


作用:  简化了查询,增删改的代码。

update方法:

1)  
    //执行增、删、改语句
         int update(String sql, Object... params) 
2)           
     //支持事务
         int update(Connection con, String sql, Object... parmas)  
             需要调用者提供Connection,这说明本方法不再管理Connection了。

query方法:

1)
//可执行查询
    T query(String sql, ResultSetHandler rsh, Object... params)
        运行机制:它会先得到ResultSet,然后调用rsh的handle()把rs转换成需要的类型!

2) 
 //支持事务
    T query(Connection con, String sql, ResultSetHadler rsh, Object... params)

ResultSetHandler接口:

1)
//把一行结果转换成指定类型的javaBean对象
     BeanHandler(单行)    构造器需要一个Class类型的参数.

2) 
 //把多行就是转换成List对象,一堆javabean
     BeanListHandler(多行)    构造器也是需要一个Class类型的参数。

3)
 MapHandler(单行) --> 把一行结果集转换Map对象
      > 一行记录:
        sid  sname  age  gender
        1001 zs     99   male
      > 一个Map:
        {sid:1001, sname:zs, age:99, gender:male}

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

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

2、QueryRunner类的使用 :


public class Demo3 {

// 1)
    //添加语句。
    @Test
    public void fun1() throws SQLException {
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "insert into t_stu values(?,?,?,?)";
        Object[] params = {1002, "liSi", 88, "female"};

        qr.update(sql, params);
    }

// 2)
    //查询。
    @Test
    public void fun2() throws SQLException {
        // 创建QueryRunner,需要提供数据库连接池对象
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        // 给出sql模板
        String sql = "select * from t_stu where sid=?";
        // 给出参数
        Object[] params = {1001};

//      ResultSetHandler<Stu> rsh = new ResultSetHandler<Stu>() {
//
//          @Override
//          public Stu handle(ResultSet rs) throws SQLException {
//              // TODO Auto-generated method stub
//              return null;
//          }
//      };
        // 执行query()方法,需要给出结果集处理器,即ResultSetHandler的实现类对象
        // 我们给的是BeanHandler,它实现了ResultSetHandler
        // 它需要一个类型,然后它会把rs中的数据封装到指定类型的javabean对象中,然后返回javabean
        Stu stu = qr.query(sql, new BeanHandler<Stu>(Stu.class), params);
        System.out.println(stu);
    }


// 3)
    /**
     * BeanListHandler的应用,它是多行处理器
     * 每行对象一个Stu对象!
     * @throws Exception
     */
    @Test
    public void fun3() throws Exception {
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "select * from t_stu";
        List<Stu> stuList = qr.query(sql, new BeanListHandler<Stu>(Stu.class));

        System.out.println(stuList);
    }

//4)
    /**
     * MapHandler的应用,它是单行处理器,把一行转换成一个Map对象
     * @throws SQLException 
     */
    @Test
    public void fun4() throws SQLException  {
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "select * from t_stu where sid=?";
        Object[] params = {1001};
        Map map = qr.query(sql, new MapHandler(), params);

        System.out.println(map);
    }

// 5)
    /**
     * MapListHandler,它是多行处理器,把每行都转换成一个Map,即List<Map>
     * @throws SQLException
     */
    @Test
    public void fun5() throws SQLException  {
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "select * from t_stu";
        List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler());

        System.out.println(mapList);
    }

// 6)
    /**
     * ScalarHandler,它是单行单列时使用,最为合适!
     * @throws SQLException
     */
    @Test
    public void fun6() throws SQLException {
        QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
        String sql = "select count(*) from t_stu";
        /*
         * Integer、Long、BigInteger
         */
        Number cnt = (Number)qr.query(sql, new ScalarHandler());

        long c = cnt.longValue();
        System.out.println(c);
    }
}

3、查询及增删改内部原理:


public class QR<T> {
    private DataSource dataSource;

    //带参构造器。
    //得到连接在方法外部得到连接 方法内可同一使用
    public QR(DataSource dataSource) {
        this.dataSource = dataSource;  //传参为连接池  得到连接
    }

    //无参构造器
    public QR() {
        super();
    }

    /**
     * 做insert、update、delete
     * @param sql
     * @param params
     * @return
     */
     //第一个参数:为sql模板  ,第二个参数:可变参数
    public int update(String sql, Object... params) {   
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = dataSource.getConnection();//通过连接池得到连接对象

            pstmt = con.prepareStatement(sql);//使用sql创建pstmt

            //调用方法给参数赋值。方法内部循环遍历可变参数。
            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 e1) {}
        }
    }

    // 利用循环给可变参数赋值
    private void initParams(PreparedStatement pstmt, Object... params) 
            throws SQLException {
        for(int i = 0; i < params.length; i++) {
            pstmt.setObject(i+1, params[i]);   //利用PreparedStatement 挨个为参数赋值
        }
    }


    //查询功能  参数为 sql模板、 接口、 可变参数
    public T query(String sql, RsHandler<T> rh, Object... params) {  
        Connection con = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            con = dataSource.getConnection();//通过连接池得到连接对象

            pstmt = con.prepareStatement(sql);//使用sql创建pstmt
            initParams(pstmt, params);//设置参数

            rs = pstmt.executeQuery();//执行

            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 e1) {}
        }
    }
}

// 用来把结果集转换成需要的类型! 
interface RsHandler<T> {
    //传参为结果集,返回需要的Object
    public T handle(ResultSet rs) throws SQLException;
}



调用:
public class Demo2 {
    @Test
    public void fun1() {
//      Stu s = new Stu(1001, "zhangSan", 99, "male");
//      addStu(s);

        Stu s = load(1001);
        System.out.println(s);
    }

    //增、删、改
    public void addStu(Stu stu) {
        QR qr = new QR(JdbcUtils.getDataSource());//创建对象时给出连接池
        String sql = "insert into stu values(?,?,?,?)";//给出sql模板
        // 给出参数
        Object[] params = {stu.getSid(), stu.getSname(), stu.getAge(), stu.getGender()};
        // 调用update执行增、删、改!
        qr.update(sql, params);
    }

    //查询
    public Stu load(int sid) {
        QR qr = new QR(JdbcUtils.getDataSource());//创建对象时给出连接池
        String sql = "select * from stu where sid=?";//给出sql模板
        Object[] params = {sid};

            //查询功能内部需要一个接口参数。先创建一个接口类
            //此时需要一个接口,用来调用接口实现类型的转换的方法。
            RsHandler<Stu> rh = new RsHandler<Stu>() {
                //添加内部类,在查询功能内部需要调用此类功能,为stu设置参数。最终返回
                //实现转换类型接口的方法 将rs转为stu  
                public Stu handle(ResultSet rs) throws SQLException {  //
                    if(!rs.next()) return null;
                    Stu stu = new Stu();
                    stu.setSid(rs.getInt("sid"));
                    stu.setSname(rs.getString("sname"));
                    stu.setAge(rs.getInt("age"));
                    stu.setGender(rs.getString("gender"));
                    return stu;
                }
            };
        return (Stu) qr.query(sql, rh, params);  //调用查询功能。
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41307491/article/details/81476658
今日推荐