MySQL数据库入门学习(五)——使用工具类封装JDBC实现MySQL的查询操作

发布于 2021-02-18  1261 次阅读


MySQL数据库入门学习(五)——使用工具类封装JDBC实现MySQL的查询操作

1.前言

我们知道,事实上,MySQL的 “增删查改”其实就是分为两类,一类是更新操作:int executeUpdate(String sql)包括了插入(insert),更新(update),删除(delete);另外一类是查询操作(select),由ResultSet executeQuery(String sql) 或者 ResultSet executeQuery() 实现。在上篇文章:MySQL数据库入门学习(四)——使用工具类封装JDBC实现MySQL的更新操作中已经实现了自定义封装的MySQL的更新操作。现在我们开始对查询操作进行封装.

2.查询操作的步骤

2.1首先观察一个查询方法

/**
     * 通过ID查询book
     * @param id 要查询的book的ID
     * @return 返回ID对应的book
     */
    public Book findBookById(int id) {
        //需要执行的查找的sql语句
        String sql = "select * from book  where id = ?";
        //结果集
        ResultSet resultSet = null;
        Book book = null;
        try {
            //获取创建连接
            Connection connection = JDBCUtil.getConnection();
            //创建预处理对象
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            //设置id占位符对应的值
            preparedStatement.setInt(1, id);
            //开始执行查询语句,并返回查询的结果集
            resultSet = preparedStatement.executeQuery();
            //如果查询到结果不为空而是有记录
            if(resultSet.next()) {
            //获取book的name
            String name = resultSet.getString("name");
            //获取book的status
            byte status = resultSet.getByte("status");
            //获取book的price
            double price = resultSet.getDouble("price");
            //获取book的discount
            float discount = resultSet.getFloat("discount");
            //获取book的isBorrowed
            boolean isBorrowed = resultSet.getBoolean("isBorrowed");
            //获取book的createTime
            Date date = resultSet.getDate("createTime");
            book = new Book();
            book.setBorrowed(isBorrowed);
            book.setDiscount(discount);
            book.setId(id);
            book.setPrice(price);
            book.setName(name);
            book.setStatus(status);
            book.setCreateTime(date);
            }
            //释放资源,先开启的后释放
            JDBCUtil.close(connection, preparedStatement, resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
            book = null;
        }


        return book;

    }

我们发现,查询(query)操作有这几个步骤:
①获取连接对象Connection 。
②根据sql语句创建预处理对象PreparedStatement
③使用实际参数替换PreparedStatement 中的占位符“?”。
④执行查询操作:preparedStatement.executeQuery(),得到结果集ResultSet。
⑤封装结果集ResultSet到实体对象book中。
⑥关闭资源
⑦返回结果对象book。
这个是对于方法 public Book findBookById(int id);来说,它的参数只有一个,但是在有些查询情况中,查询的条件肯定不止一个,因此来说,我们可以将这个查询条件用一个可变的Object数组params来表示。然后preparedStatement.setXXX(int parameterIndex, XXX x);中XXX也就是填充的实际参数类型是不确定的。这时候我们可以使用preparedStatement.setObject(int parameterIndex, Object x)来进行设置参数。因为Object是所有类的公共父类,所以使用这个参数可以达到代码通用性来设置占位符“?"。

2.2抽取通用的查询方法

作为一个通用的查询方法,查询不同的对象时候返回的结果对象不同,比如说查询学生Student那么返回的是student对象,查询book,那么返回的是book对象等。因此这个通用的查询方法返回的是一个泛型对象,交给查询者指定:

public static <T> T  query(String sql,Object... params)

但是我们知道,这样子通过preparedStatement.setObject(i+1,params[i]);后执行 ResultSet result =preparedStatement.executeQuery();得到的是一个结果集ResultSet ,这是时候我们需要对这个结果集封装成对应的实体对象。由此我们需要指定一个处理器ResultSetHandler专门处理这个结果集。这里定义一个接口:

/**
 * @author 陌意随影
 TODO :结果集处理器。
 *2021年2月18日  下午12:44:11
 */
public interface ResultSetHandler<T> {
    /**
     * @param resultSet  查询的结果集
     * @return  返回一个实体对象
     */
    T handleResutl(ResultSet resultSet);

}

这样,我们定义的这个查询方法抽取为:

public static <T> T  query(String sql, ResultSetHandler<T>  resultSetHandler,Object... params);

这个ResultSetHandler接口我们可以由查询者自定义实现这个接口,然后在这个T handleResutl(ResultSet resultSet);方法中将ResultSet封装成一个实体对象T并返回即可。

2.3完整的查询方法代码

/**
 * 执行sql的查询语句。
 * @param sql 需要执行的sql语句
 * @param params 预处理占位符中的实际参数数组
 * @resultSetHandler 结果集处理器,负责将结果集ResultSet封装成对象。
 * @return 返回查询的对象。
 */
public static <T> T  query(String sql, ResultSetHandler<T>  resultSetHandler,Object... params){
      if (params==null) return null;
      //获取连接对象
    Connection connection=JDBCUtil.getConnection();
    PreparedStatement preparedStatement=null;

    ResultSet resultSet = null;
    try {
        //创建预处理对象
        preparedStatement= connection.prepareStatement(sql);
        //使用实际参数替换占位符
        for (int i= 0;i < params.length;i++){
              //parameterIndex从1开始
               preparedStatement.setObject(i+1,params[i]);
        }
        //执行sql查询语句
        resultSet = preparedStatement.executeQuery();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    //关闭资源
    JDBCUtil.close(connection,preparedStatement,null);
    //通过处理器处理这个结果集,封装成一个实体对象
    T t = resultSetHandler.resultSetHandler(resultSet);
      return t;
}

3.实现查询book的方法

3.1首先自定义实现一个book的结果集处理器,对结果集进行封装成一个对象

/**
 * @author 陌意随影
 TODO :book的结果集处理实现类
 *2021年2月18日  下午1:26:07
 */
public class BookResultSetHandlerImpl implements ResultSetHandler<List<Book>>{

    @Override
    public List<Book> resultSetHandler(ResultSet resultSet) {
        List<Book> bookList = new ArrayList<>();
        try {
            //如果查询到结果不为空而是有记录
            while(resultSet.next()) {
            //获取book的ID
            int id = resultSet.getInt("id");
            //获取book的name
            String name = resultSet.getString("name");
            //获取book的status
            byte status = resultSet.getByte("status");
            //获取book的price
            double price = resultSet.getDouble("price");
            //获取book的discount
            float discount = resultSet.getFloat("discount");
            //获取book的isBorrowed
            boolean isBorrowed = resultSet.getBoolean("isBorrowed");
            //获取book的createTime
            Date date = resultSet.getDate("createTime");
            Book book = new Book();
            book.setBorrowed(isBorrowed);
            book.setDiscount(discount);
            book.setId(id);
            book.setPrice(price);
            book.setName(name);
            book.setStatus(status);
            book.setCreateTime(date);
            bookList.add(book);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bookList;
    }

3.2查询所有book

/**
     * 查询所有图书
     * @return 返回List<book>
     */
    public List<Book> findAllBook() {
        //拼接需要执行的查找的sql语句
        String sql = "select * from book ";
        //结果集
        List<Book> bookList = JDBCUtil.query(sql, new BookResultSetHandlerImpl());
        return bookList;

    }

3.3通过ID查询book

  /**
     * 通过ID查询book
     * @param id 要查询的book的ID
     * @return 返回ID对应的book
     */
    public Book findBookById(int id) {
        //需要执行的查找的sql语句
        String sql = "select * from book  where id = ?";
        //结果集
        List<Book> bookList = JDBCUtil.query(sql, new BookResultSetHandlerImpl(),id);
        if (bookList == null || bookList.size() == 0 ) {
            return null;
        }
        //根据ID查询只有一个对象
        Book book = bookList.get(0);
        return book;

    }

4.测试

在这里插入图片描述
在这里插入图片描述

5.本项目源代码下载:


繁华落尽,雪花漫天飞舞。