JDBC高级+轻量级数据库框架DbUtils

左先生 12天前   阅读数 11 0

JDBC高级和DbUtils

1. BaseDao方法补充

1.1 为什么要提供该方法

完成一个查询返回值类型是Object[],并且是存储于List集合中的一种方式,实际返回值类型是 List<Object[]>
 处理的是查询数据结果无法映射到类对象中,ORM,所有的数据按照查询结果字段顺序要求从数据库读取数据保存到Object数组,为了能满足多行数据查询要求,Object数组存储到List中

1.2 方法分析

分析:
 权限修饰符:
  public
 返回值类型:
  List<Object[]>
 方法名:
  query
形式参数列表:
  String sql select查询语句
  对应当前SQL语句的参数
方法声明:
 public List<Object[]> query(String sql, Object[] parameters)

/** * 通用查询方法,返回值是对应字段数据的Object类型数组,并且存储于List集合 * * @param sql Select查询SQL语句 * @param parameters 对应当前SQL语句的参数 * @return 包含数据行数据的List<Object[]> 如果没有查询到数据,返回null */
public List<Object[]> query(String sql, Object[] parameters) {
    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    List<Object[]> list = new ArrayList<>();
    try {
        connection = JdbcUtil.getConnection();
        preparedStatement = connection.prepareStatement(sql);
        /* 获取SQL语句参数个数!!!通过SQL语句元数据获取(ParameterMetaData) */
        int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
        /* parameterCount 参数个数不能为0 parameters != null 参数数组不为null,因为存在当前方法没有参数,数组传入null parameterCount == parameters.length 参数个数和传入的Object类型参数数容量一致 */
        if (parameterCount != 0 && parameters != null && parameterCount == parameters.length)
            for (int i = 0; i < parameters.length; i++) {
                /* SQL语句参数下标从1开始 数组数据下标从0开始 */
                preparedStatement.setObject(i + 1, parameters[i]);
            }
        }
        resultSet = preparedStatement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        while (resultSet.next()) {
            Object[] values = new Object[columnCount];
            for (int i = 1; i <= columnCount; i++) {
                values[i - 1] = resultSet.getObject(i);
            }
            list.add(values);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
    return list.size() != 0 ? list : null;
}
1.3 BaseDao优化
// Ctrl + Alt + M 光标选择代码块生成一个方法
/** * 类内私有化处理PreparedStatement预处理SQL语句和参数数组赋值操作 * * @param preparedStatement 预处理SQL语句对应的PreparedStatement对象 * @param parameters 对应当前SQL语句的Object类型数组 * @throws SQLException SQL异常 */
private void parseSqlParameter(PreparedStatement preparedStatement, Object[] parameters) throws SQLException {
    /* 获取SQL语句参数个数!!!通过SQL语句元数据获取(ParameterMetaData) */
    int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
    
    /* parameterCount 参数个数不能为0 parameters != null 参数数组不为null,因为存在当前方法没有参数,数组传入null parameterCount == parameters.length 参数个数和传入的Object类型参数数容量一致 */
    if (parameterCount != 0 && parameters != null && parameterCount == parameters.length) {
        for (int i = 0; i < parameters.length; i++) {
            /* SQL语句参数下标从1开始 数组数据下标从0开始 */
            preparedStatement.setObject(i + 1, parameters[i]);
        }
    }
}

2. 项目使用JdbcUitl,BaseDao完成数据持久化操作

2.1 需求

使用数据库作为数据持久化操作是一个非常非常常见。剥离原本的数据保存方式,之前数据保存使用的是Json个数文件,并且使用到Dao层
 项目Dao层需要继承BaseDao完成对于数据的操作CRUD。并且数据库和当前项目中的实体类是对应关系:
 数据表 ==> 实体类名一致
 字段名 ==> 成员变量名
 数据类型 ==> 成员变量数据类型

完成一个简版Student管理系统
 dao
  interface StudentDao
  impl(package)
   StudentDaoImpl
 service
  interface StudentService
  impl(package)
   StudentServiceImpl
 view
  interface ProjectView
  impl(package)
   ProjectViewImpl
 mainproject
  main方法

2.2 数据库设计
字段 数据类型
id int PRI AI
name varchar(50) NN
age int NN
gender boolean NN
score float(5, 2) NN
address text NN
2.3 Student实体类
2.4 StudentDao规范
2.5 StudentDaoImpl实现
2.6 StudentService规范
2.7 StudentServiceImpl实现
2.8 StudentView规范
2.9 StudentViewImpl实现
2.10 StudentController实现
2.11 StudentProject main方法

在这里插入图片描述

3. 轻量级数据库ORM框架DbUtils

3.1 DbUtils介绍

Apache组织下的一个轻量级ORM框架
 Commons DbUtils: JDBC Utility Component
两个核心方法
 update方法 ==> insert,update,delete
 query方法 ==> select

一个核心类
 QueryRunner DbUtils的核心类

3.2 DbUtils ORM工具使用
package com.qfedu.c_dbutils;

import com.qfedu.b_studentsys.entity.Student;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;
import util.JdbcUtil;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/** * DbUtils ORM框架演示 * * @author Anonymous 2020/3/25 16:03 */
public class DbUtilsTest {
    @Test
    public void testInsert() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. 插入数据到Student数据表中
        String sql = "insert into student(name, age, gender, score, address) value(?, ?, ?, ?, ?)";
        Object[] parameters = {"老黑", 70, true, 59, "河南郑州"};

        // 3. 获取数据库连接
        Connection connection = JdbcUtil.getConnection();

        // 4. 执行Update方法
        runner.update(connection, sql, parameters);

        JdbcUtil.close(connection);
    }

    /** * 了解操作方式, ResultSetHandler */
    @Test
    public void testQuery1() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /* ResultSetHandler 核心接口 ResultSet结果集 Handler处理, 核心方法 handler(ResultSet rs) */
        Student student = runner.query(connection, sql, rs -> {
            Student stu = null;
            if (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                boolean gender = rs.getBoolean("gender");
                float score = rs.getFloat("score");
                String address = rs.getString("address");

                stu = new Student(id, name, age, gender, score, address);
            }
            return stu;
        });

        System.out.println(student);
        JdbcUtil.close(connection);
    }

    /** * BeanHandler */
    @Test
    public void queryBean() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /* BeanHandler: 处理符合JavaBean规范的类对象,传入参数是对应JavaBean规范 Class对象 */
        Student student = runner.query(connection, sql, new BeanHandler<>(Student.class));

        System.out.println(student);

        JdbcUtil.close(connection);
    }

    /** * BeanListHandler */
    @Test
    public void queryBeanList() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id > ?";

        Connection connection = JdbcUtil.getConnection();

        /* BeanListHandler: 处理符合JavaBean规范的实体类,并且返回值是一个List集合 包含制定的JavaBean实体类 */
        List<Student> list = runner.query(connection, sql, new BeanListHandler<>(Student.class), 2);

        for (Student student : list) {
            System.out.println(student);
        }
        JdbcUtil.close(connection);
    }

    /** * ArrayHandler */
    @Test
    public void queryArray() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /* ArrayHandler: 查询一个数据行,数据行中的所有数据整合成一个Object类型数组返回 */
        Object[] values = runner.query(connection, sql, new ArrayHandler());

        System.out.println(Arrays.toString(values));

        JdbcUtil.close(connection);
    }

    /** * ArrayListHandler */
    @Test
    public void queryArrayList() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id > ?";

        Connection connection = JdbcUtil.getConnection();

        /* ArrayListHandler: 查询结果集中所有数据行,每一行数据对应一个Object类型数组,存储在List集合中 */
        List<Object[]> list = runner.query(connection, sql, new ArrayListHandler(), 2);

        for (Object[] values : list) {
            System.out.println(Arrays.toString(values));
        }
        JdbcUtil.close(connection);
    }

    /** * MapHandler */
    @Test
    public void queryMap() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /* MapHandler: 处理一个数据行,数据行中字段是对应Key,字段对应数据是value,组成一个Map双边队列 */
        Map<String, Object> map = runner.query(connection, sql, new MapHandler());

        System.out.println(map);
    }

    /** * MapListHandler */
    @Test
    public void queryMapList() throws SQLException {
        // 1. DbUtils核心类 QueryRunner对象
        QueryRunner runner = new QueryRunner();

        // 2. SQL语句
        String sql = "select * from student where id > ?";

        Connection connection = JdbcUtil.getConnection();

        /* MapListHandler: 结果集中所有的数据行,每一行对应一个Map对象,字段名为Key,字段对应的数据为value,所有数据行存储 在List中 */
        List<Map<String, Object>> mapList = runner.query(connection, sql, new MapListHandler(), 2);

        for (Map<String, Object> map : mapList) {
            System.out.println(map);
        }
    }
}

3.3 ResultHandler以及其子类

ResultSetHandler 核心接口
 ResultSet结果集 Handler处理,
 核心方法 handler(ResultSet rs)

BeanHandler:
 处理符合JavaBean规范的类对象,传入参数是对应JavaBean规范 Class对象

BeanListHandler:
 处理符合JavaBean规范的实体类,并且返回值是一个List集合包含制定的JavaBean实体类

ArrayHandler:
 查询一个数据行,数据行中的所有数据整合成一个Object类型数组返回

ArrayListHandler:
 查询结果集中所有数据行,每一行数据对应一个Object类型数组,存储在List集合中

MapHandler:
 处理一个数据行,数据行中字段是对应Key,字段对应数据是value,组成一个Map双边队列

MapListHandler:
 结果集中所有的数据行,每一行对应一个Map对象,字段名为Key,字段对应的数据为value,所有数据行存储在List中

发布了39 篇原创文章 · 获赞 70 · 访问量 1万+

注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: