java学习记录三十四:DBUtils

一、DBUtils

一、解释

DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能

二、DBUtils的常用API介绍

1.创建QueryRunner对象的API

public QueryRunner(DataSource ds) ,提供数据源(连接池),DBUtils底层自动维护连接connection

2.QueryRunner执行增删改的SQL语句的API

int update(String sql, Object... params),执行增删改的SQL语句, params参数就是可变参数,参数个数取决于语句中问号的个数

eg: qr.update(“insert into user values(null,?,?,?)”,“zs”,“123456”,“张三”);

3.执行查询的SQL语句的API

query(String sql, ResultSetHandler<T> rsh, Object... params),其中ResultSetHandler是一个接口,表示结果集处理者

二、JavaBean

一、解释

  1. JavaBean说白了就是一个类, 用来封装数据用的

  2. JavaBean要求

    • 私有字段
    • 提供公共的get/set方法
    • 无参构造
    • 建议满参构造
    • 实现Serializable
  3. 字段和属性

    • 字段: 全局/成员变量 eg: private String username
    • 属性: 去掉get或者set首字母变小写 eg: setUsername-去掉set->Username-首字母变小写->username

    一般情况下,我们通过IDEA直接生成的set/get 习惯把字段和属性搞成一样而言

3.小结

  1. JavaBean用来封装数据用的
  2. 字段和属性
    • 字段: 全局/成员变量 eg: private String username
    • 属性: 去掉get或者set首字母变小写 eg: setUsername-去掉set->Username-首字母变小写->username

三、使用DBUtils完成增删改

步骤

  1. 拷贝jar包
  2. 创建QueryRunner()对象,传入dataSource
  3. 调用update()方法
public class UpdateTest {
    // 插入记录
    @Test
    public void insert() throws Exception {
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());

        // 2.调用update方法
        String sql = "insert into user values(null,?,?,?)";
        int rows = qr.update(sql, "tianqi", "123456", "田七");
        System.out.println("受影响的行数:" + rows);

    }

    // 删除记录  删除id为4的记录
    @Test
    public void delete() throws Exception {
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());

        // 2.调用update方法
        String sql = "delete from user where id = ?";
        int rows = qr.update(sql, 4);
        System.out.println("受影响的行数:" + rows);
    }

    // 修改记录  修改id为5的记录
    @Test
    public void update() throws Exception{
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());

        // 2.调用update方法
        String sql = "update user set password = ? where id = ?";
        int rows = qr.update(sql,"abcd",3);
        System.out.println("受影响的行数:" + rows);
    }
}

小结

  1. 创建QueryRuner()对象, 传入DataSource
  2. 调用update(String sql, Object…params)

四、使用DBUtils完成查询

步骤

  1. 拷贝jar包
  2. 创建QueryRunner()对象 传入DataSource
  3. 调用query(sql, resultSetHandler,params)方法
    ResultSetHandler结果集处理类介绍
    在这里插入图片描述
public queryRunner(DataSource ds);
query(String sql, ResultSetHandler<T> rsh, Object... params) 执行查询语句
      参数ResultSetHandler是一个接口,表示结果集处理者(对查询结果的封装):
      ResultSetHandler接口的实现类:
        ArrayHandler:适合查询结果是一条记录的,会把这条记录的数据封装到一个Object数组中
        ArrayListHandler:适合查询结果是多条记录的,会把每条记录的数据封装到一个Object数组中,然后把这些数组添加到List集合中
        BeanHandler:适合查询结果是一条记录的,会把这条记录的数据封装到一个javaBean对象中
        BeanListHandler:适合查询结果是多条记录的,会把每条记录的数据封装到一个javaBean对象中,然后把这些javaBean对象添加到List集合中
        ColumnListHandler:适合查询结果是单列多行的,会把该列的所有数据存储到List集合中
        KeyedHandle:适合查询结果是多条记录的,会把每条记录的数据封装到一个Map集合中,然后把这些Map集合添加到另一个Map集合中
        MapHandler:适合查询结果是一条记录的,会把这条记录的数据封装到一个Map集合中
        MapListHandler:适合查询结果是多条记录的,会把每条记录的数据封装到一个Map集合中,然后把这些Map集合添加到List集合中
        ScalarHandler:适合查询结果是单个值的,会把这个值封装成一个对象

1.查询一条数据封装到JavaBean对象中(使用BeanHandler)

 @Test
    public void select1() throws Exception{
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());

        // 2.调用query(sql,resultSetHandler,args)方法
        String sql = "select * from user where id = ?";
        User user = qr.query(sql, new BeanHandler<User>(User.class), 3);
        System.out.println(user);

    }

2.查询多条数据封装到List中(使用BeanListHandler)

 @Test
    public void select2() throws Exception{
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.调用query方法
        String sql = "select * from user";
        List<User> list = qr.query(sql, new BeanListHandler<User>(User.class));
        for (User user : list) {
            System.out.println(user);
        }
    }

3.查询一条数据,封装到Map对象中(使用MapHandler)

// 查询一条数据,封装到Map对象中(使用MapHandler)
    // 列名作为key,列中的值作为value
    @Test
    public void select3() throws Exception {
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.调用query方法
        String sql = "select * from user where id = ?";
        Map<String, Object> map = qr.query(sql, new MapHandler(), 3);
        for (String key : map.keySet()) {
            System.out.println(key + ":" + map.get(key));
        }
    }

4.查询多条数据,封装到List<Map>对象中(使用MapListHandler)

// 查询多条数据,封装到List<Map>对象中(使用MapListHandler)
    @Test
    public void select4() throws Exception{
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.调用query方法
        String sql = "select * from user";
        List<Map<String, Object>> list = qr.query(sql, new MapListHandler());
        for (Map<String, Object> map : list) {
            // map--->每条记录
            for (String key : map.keySet()) {
                System.out.println(key + ":" + map.get(key));
            }
            System.out.println("=================================================");
        }
    }

5.查询单个数据(使用ScalarHandler())

// 查询单个数据(使用ScalarHandler())
    @Test
    public void select5() throws Exception{
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.调用query方法
        String sql = "select count(*) from user";
        Long count = (Long) qr.query(sql, new ScalarHandler());
        System.out.println("记录数:"+count);
    }

6.查询单列多个值(使用ArrayListHandler)

   // 查询单列多个值(ArrayListHandler)
    // 单列多值: 每列的数据封装成一个数组,再把所有的数组存储到List集合中
    // 多条记录: 每条记录的数据封装成一个数组,再把所有的数组存储到List集合中
    @Test
    public void select6() throws Exception{
        // 1.创建QueryRunner对象,传入连接池
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
        // 2.调用query方法
        String sql = "select username from user";
        List<Object[]> list = qr.query(sql, new ArrayListHandler());
        for (Object[] arr : list) {
            System.out.println(Arrays.toString(arr));
        }
    }

7.查询一条记录(使用ArrayHandler)

	// 查询一条记录(ArrayHandler)
// 一条记录封装成一个数组,数组中的元素就是每列的值
@Test
public void select7() throws Exception{
    // 1.创建QueryRunner对象,传入连接池
    QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
    // 2.调用query方法
    String sql = "select * from user where id = ?";
    Object[] arr = qr.query(sql, new ArrayHandler(), 3);
    System.out.println(Arrays.toString(arr));
}

8.小结

  1. 步骤

    • 创建QueryRunner() 对象传入DataSource
    • 调用query(sql,ResultSetHandler, params…)
  2. ResultSetHandler

    • BeanHandler() 查询一条记录封装到JavaBean对象
    • BeanListHandler() 查询多条记录封装到List list
    • ScalarHandler() 封装单个记录的 eg:统计数量
    • ColumnListHandler() 封装单列多行记录
    • MapHandler() 查询一条记录封装到Map对象
    • MapListHandler() 查询多条记录封装到List list
    • ArrayHandler() 查询一条记录封装到数组中

    原理: 使用了反射+内省

  3. 注意实现

    封装到JavaBean条件, 查询出来的数据的列名必须和JavaBean属性一致

五、自定义DBUtils

一、元数据

我们要自定义DBUtils, 就需要知道列名, 参数个数等, 这些可以通过数据库的元数据库进行获得.元数据在建立框架和架构方面是特别重要的知识,我们可以使用数据库的元数据来创建自定义JDBC工具包, 模仿DBUtils.
元数据(MetaData),即定义数据的数据。打个比方,就好像我们要想搜索一首歌(歌本身是数据),而我们可以通过歌名,作者,专辑等信息来搜索,那么这些歌名,作者,专辑等等就是这首歌的元数据。因此数据库的元数据就是一些注明数据库信息的数据。
​ 简单来说: 数据库的元数据就是 数据库、表、列的定义信息。

​ ① 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。

② 由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。

二、ParameterMetaData

1.概述

​ ParameterMetaData是由preparedStatement对象通过getParameterMetaData方法获取而来,ParameterMetaData可用于获取有关PreparedStatement对象和其预编译sql语句 中的一些信息. eg:参数个数,获取指定位置占位符的SQL类型
​ 获得ParameterMetaData:

ParameterMetaData parameterMetaData =  preparedStatement.getParameterMetaData ()

2.ParameterMetaData相关的API

  • int getParameterCount(); 获得参数个数
  • int getParameterType(int param) 获取指定参数的SQL类型。 (注:MySQL不支持获取参数类型)

3.实例代码

public class Test1_参数元数据 {
    public static void main(String[] args) throws Exception{
        /*
            ParameterMetaData类:
                概述: 是一个参数元数据类,可以用来获取参数的元数据
                使用:
                    1.获取参数元数据类对象
                        PreparedStatement对象调用getParameterMetaData()方法
                    2.获取参数的元数据
                        ParameterMetaData相关的API
                            - int getParameterCount(); 获得参数个数
                            - int getParameterType(int param) 获取指定参数的SQL类型。 (注:MySQL不支持获取参数类型)

         */
        // 1.获取连接
        Connection connection = C3P0Utils.getConnection();

        // 2.预编译sql语句
        String sql = "select * from user where username = ? and password = ?";
        PreparedStatement ps = connection.prepareStatement(sql);

        // 3.通过PreparedStatement对象获取参数元数据对象
        ParameterMetaData pmd = ps.getParameterMetaData();// 参数元数据对象

        // 4.获取参数个数元数据   参数个数就是参数的元数据
        int count = pmd.getParameterCount();
        System.out.println("sql语句的参数个数:"+count);// 2

        // 5.获取参数类型元数据  参数类型也是参数的元数据
        //int parameterType = pmd.getParameterType(1);
        //System.out.println(parameterType);

        //String typeName = pmd.getParameterTypeName(1);
        //System.out.println(typeName);

    }
}

三、ResultSetMetaData

ResultSetMetaData是由ResultSet对象通过getMetaData方法获取而来,ResultSetMetaData可用于获取有关ResultSet对象中列的类型和属性的信息。
ResultSetMetaData获取结果集中的列名和列的类型
获得ResultSetMetaData:

ResultSetMetaData resultSetMetaData =  resultSet.getMetaData()

2.resultSetMetaData 相关的API

  • getColumnCount(); 获取结果集中列项目的个数
  • getColumnName(int column); 获得数据指定列的列名
  • getColumnTypeName();获取指定列的SQL类型
  • getColumnClassName();获取指定列SQL类型对应于Java的类型

3.实现

 public class Test2_结果集元数据 {
    public static void main(String[] args) throws Exception {
        /*
            ResultSetMetaData类:
                概述:是一个结果集元数据类,可以用来获取结果集的元数据
                使用:
                    1.获取结果集元数据类的对象
                        ResultSet的对象调用getMetaData()方法
                    2.获取结果集的元数据
                        ResultSetMetaData 相关的API
                        - getColumnCount(); 获取结果集中列项目的个数
                        - getColumnName(int column); 获得数据指定列的列名
                        - getColumnTypeName();获取指定列的SQL类型
                        - getColumnClassName();获取指定列SQL类型对应于Java的类型

         */
        // 1.获取连接
        Connection connection = C3P0Utils.getConnection();

        // 2.预编译sql语句
        String sql = "select * from user where username = ? and password = ?";
        PreparedStatement ps = connection.prepareStatement(sql);

        // 3.设置参数
        ps.setString(1, "zs");
        ps.setString(2, "123456");

        // 4.执行sql语句
        ResultSet resultSet = ps.executeQuery();

        // 5.获取结果集的元数据对象
        ResultSetMetaData rsmd = resultSet.getMetaData();

        // 1.获取列的数量
        int columnCount = rsmd.getColumnCount();
        System.out.println("列的个数:" + columnCount);//4

        // 2.获取列的名字
        for (int i = 1; i <= columnCount; i++) {
            System.out.println(rsmd.getColumnName(i));
        }
        System.out.println("==================================");
        // 3.获取列的MySQL类型
        for (int i = 1; i <= columnCount; i++) {
            System.out.println(rsmd.getColumnTypeName(i));
        }
        System.out.println("==================================");


        // 4.获取列在Mysql中的类型对应于java中的类型
        for (int i = 1; i <= columnCount; i++) {
            System.out.println(rsmd.getColumnClassName(i));
        }
    }
}

4.小结

  1. 元数据: 描述数据的数据. mysql元数据: 用来定义数据库, 表 ,列信息的 eg: 参数的个数, 列的个数, 列的类型…
  2. mysql元数据:
    • ParameterMetaData
    • ResultSetMetaData

六、自定义DBUtils增删改

模仿DBUtils, 完成增删改的功能

  1. 创建MyQueryRunner类, 定义dataSource, 提供有参构造方法
  2. 定义int update(String sql, Object…params)方法
//0.非空判断
//1.从dataSource里面获得connection
//2.根据sql语句创建预编译sql语句对象
//3.获得参数元数据对象, 获得参数的个数
//4.遍历, 从params取出值, 依次给参数? 赋值
//5.执行
//6.释放资源
public class MyQueryRunner {

    private DataSource dataSource;

    public MyQueryRunner(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public MyQueryRunner() {
    }

    /**
     * 增删改的方法
     * @param sql
     * @param args
     * @return rows
     */
    public int update(String sql,Object... args) throws Exception{
        // 非空判断
        // 连接池为空
        if (dataSource == null){
            throw new RuntimeException("连接池不能为null");
        }

        if (sql == null){
            throw  new RuntimeException("sql语句不能为空");
        }

         // 1.获得连接
        Connection connection = dataSource.getConnection();

        // 2.预编译sql语句
        PreparedStatement ps = connection.prepareStatement(sql);

        // 3.设置参数
        // 3.1 获得参数元数据类的对象
        ParameterMetaData pmd = ps.getParameterMetaData();

        // 3.2 根据参数元数据类的对象,获取参数个数(元数据)
        int count = pmd.getParameterCount();

        // 3.3 给参数赋值
        for (int i = 0; i < count; i++) {
            ps.setObject(i+1,args[i]);
        }

        // 4.执行sql语句
        int rows = ps.executeUpdate();

        // 5.释放资源
        C3P0Utils.release(null,ps,connection);

        // 6.返回影响的行数
        return  rows;
    }
}

4.小结

  1. 先模拟DBUtils写出架子
  2. update()
    • 封装了PrepareStatement操作
    • 用到了参数元数据
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值