0


除夕快乐之三天学会JDBC(六)DbUtils工具&分页技术

一.DbUtils工具

1.概述

**1 Apache-DbUtils **

commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

API介绍:

  • org.apache.commons.dbutils.QueryRunner
  • org.apache.commons.dbutils.ResultSetHandler
  • 工具类:org.apache.commons.dbutils.DbUtils

**2 QueryRunner **

QueryRunner类是Dbutils的核心类之一,提供对sql语句操作的API

  • int update(String sql, Object... params):执行insert update delete操作
  • query(String sql, ResultSetHandler rsh, Object… params) :执行 select操作

2.通过QueryRunner添加数据

  1. 导入commons-dbutils-1.6.jar包,并引入工程

  2. 通过DataSource对象初始化QueryRunner对象

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.commons.dbutils.QueryRunner;

import java.io.InputStream;
import java.util.Properties;

public class DBUtils_test {
    public static void main(String[] args) throws Exception {
        //通过DataSource对象初始化QueryRunner对象
        InputStream is=DBUtils_test.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties properties=new Properties();
        properties.load(is);
        QueryRunner queryRunner=new QueryRunner(DruidDataSourceFactory.createDataSource(properties));
        //编写sql,并通过update方法执行
        String sql="insert into user(username,userpassword)values(?,?)";
        //返回受影响的行数
        int count=queryRunner.update(sql,"QueryRunnerTest","QueryRunner");
        System.out.println(count);
    }
}

注:实际上QueryRunner的update方法仍然使用PreparedStatement来实现。

3.通过QueryRunner查询数据

**ResultSetHandler **

ResultSetHandler接口(org.apache.commons.dbutils.ResultSethandler)执行处理一个结果集对象,将数据转变并处理为任何一种形式,供其他应用使用。

public interface ResultSetHandler<T> { 
    T handle(ResultSet var1) throws SQLException;
}

ResultSetHandler****实现类

*通过QueryRunner*查询数据 **

返回单条记录并封装成实体类对象

返回多条记录并封装成实体类对象列表

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.hbb.jdbc.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.io.InputStream;
import java.util.List;
import java.util.Properties;

public class DBUtils_test {
    public static void main(String[] args) throws Exception {
        //通过DataSource对象初始化QueryRunner对象
        InputStream is=DBUtils_test.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties properties=new Properties();
        properties.load(is);
        QueryRunner queryRunner=new QueryRunner(DruidDataSourceFactory.createDataSource(properties));

        /*
        String sql="select * from user where id = ?";
        //将结果集中的第一行数据封装到一个对应的JavaBean实例中
        BeanHandler<User> bh=new BeanHandler<>(User.class);
        //queryRunner.query返回的对象类型和bh类型一样,所以这里是User
        User user=queryRunner.query(sql,bh,7);
        System.out.println(user.getUsername());
         */

        String sql="select * from user";
        //将结果集中的每一行数据封装到一个对应的JavaBean实例中
        BeanListHandler<User> bh=new BeanListHandler<>(User.class);
        //queryRunner.query返回的对象类型和bh类型一样,所以这里是User
        List<User> users=queryRunner.query(sql,bh);
        for (User u:users){
            System.out.println(u.getUsername());
        }
    }
}

查询User表中一共有多少条数据

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.io.InputStream;
import java.util.Properties;

public class DBUtils_test {
    public static void main(String[] args) throws Exception {
        //通过DataSource对象初始化QueryRunner对象
        InputStream is=DBUtils_test.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties properties=new Properties();
        properties.load(is);
        QueryRunner queryRunner=new QueryRunner(DruidDataSourceFactory.createDataSource(properties));

        String sql = "select count(*) from user";
        //通过ScalarHandler保存单一值
        ScalarHandler sh = new ScalarHandler();
        //数据条数
        Long count = (Long) queryRunner.query(sql,sh);
        System.out.println(count);
    }
}

4.自定义ResultSetHandler

实现ResultSetHandler接口,返回一个Map对象:

  1. 创建MyResultSetHandler类,并implements ResultSetHandler接口,重写handle方法
public class MyResultSetHandler implements ResultSetHandler { 
    @Override public Object handle(ResultSet resultSet) throws SQLException { 
        return null; 
    } 
}
  1. 当QueryRunner从数据库中查询完毕,会调用handle方法,并传入一个ResultSet参数,通过

ResultSet参数封装Map返回。

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;

import java.io.InputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class MyResultSetHandler implements ResultSetHandler {

    @Override
    public Object handle(ResultSet resultSet) throws SQLException {
        Map<String,String> map=null;
        if (resultSet.next()){
            //创建一个map对象
            map = new HashMap<>();
            map.put("id",resultSet.getString("id"));
            map.put("username",resultSet.getString("username"));
            map.put("userpassword",resultSet.getString("userpassword"));
        }
        return map;
    }

    public static void main(String[] args) throws Exception {
        //通过DataSource对象初始化QueryRunner对象
        InputStream is=DBUtils_test.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties properties=new Properties();
        properties.load(is);
        QueryRunner queryRunner=new QueryRunner(DruidDataSourceFactory.createDataSource(properties));
        //通过MyResultSetHandler获取map对象
        String sql = "select * from user where id = ?";
        MyResultSetHandler msh = new MyResultSetHandler();
        Map<String,String> map = (Map<String, String>) queryRunner.query(sql,msh,7);
        System.out.println(map);
    }
}

二.分页技术

1.概述

当一个操作数据库进行查询的语句返回的结果集内容如果过多,那么内存极有可能溢出,所以在大数据的情况下分页是必须的。

分页技术实现:

**物理分页: **

  • 数据库执行查询时(实现分页查询),查询需要的数据—依赖数据库的SQL语句
  • 在SQL查询时,从数据库只检索分页需要的数据
  • 通常不同的数据库有着不同的物理分页语句
  • MySql/Oracle,每种数据库的分页写法是不同的
  • MySql物理分页采用limit关键字,Oracle物理分页采用rowNum

**逻辑分页: **

  • 在sql查询时,先从数据库检索出所有数据的结果集,在程序内,通过逻辑语句获得分页需要的数据

2.数据库中的分页使用

**MySql Limit **

向MySql的user表中添加4条数据

insert into user values(5,'admin5','def'); 
insert into user values(6,'admin6','ghi'); 
insert into user values(7,'admin7','jkl'); 
insert into user values(8,'admin8','opq');

Limit的使用

select * from user limit m,n

其中m与n为数字。n代表需要获取多少行的数据项(即一页有多少行),而m代表从哪开始(以0为起始)。

例如我们想从user表中先获取前两行数据项(1-2)的name列数据,则SQL为:

select * from user limit 0,2;

那么如果要继续往下看一页两行的数据项(3-4)则下一步的SQL应该为:

select * from user limit 2,2;

以此类推

分页公式:(当前页-1)*每页大小

3.JDBC分页

jdbc通过分页关键字实现分页效果,将分页结果存在分页对象中

分页类(即分页的JavaBean)

package com.hbb.page;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class Page {
    //当前页数
    private Integer currentPage;
    //每页显示的记录数
    private Integer pageSize;
    //总记录数
    private Integer totalCount;
    //总页数
    private Integer totalPage;
    //每页显示的数据
    private List<Map<String,Object>> list=new ArrayList<>();

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(Integer totalCount) {
        this.totalCount = totalCount;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public List<Map<String, Object>> getList() {
        return list;
    }

    public void setList(List<Map<String, Object>> list) {
        this.list = list;
    }
}

实现类:

import com.hbb.jdbc.JDBCUtilsDruid;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.HashMap;
import java.util.Map;

public class MySQLPage {
    public static void main(String[] args) throws Exception {
        //测试
        Page page = new Page();
        //当前查询页数
        page.setCurrentPage(2);
        //每页大小
        page.setPageSize(2);
        Page respage = selectPage(page);
        //输出总页数
        System.out.println("总页数:"+respage.getTotalPage());
        //输出总记录数
        System.out.println("总记录数:"+respage.getTotalCount());
        //输出结果集
        System.out.println(respage.getList());
    }

    public static Page selectPage(Page page)throws Exception{
        Connection conn = JDBCUtilsDruid.getConnection();
        String sql = "select * from user limit ?,?";
        //预处理sql
        PreparedStatement ps = conn.prepareStatement(sql);
        //设置查询页数 (当前页-1)*每页数量
        ps.setInt(1,(page.getCurrentPage() - 1) * page.getPageSize());
        //设置每页数量
        ps.setInt(2,page.getPageSize());
        //执行sql
        ResultSet rs = ps.executeQuery();
        //获取元数据
        ResultSetMetaData rsmd = rs.getMetaData();
        while (rs.next()) {
            Map<String,Object> map = new HashMap<>();
            //根据元数据填充map
            for(int i = 0; i < rsmd.getColumnCount(); i++) {
                //注意这里是获取元数据的列名
                String columnName = rsmd.getColumnName(i + 1);
                //这里是获取结果集的具体数值
                String columnValue = rs.getString(i + 1);
                map.put(columnName,columnValue);
            }
            page.getList().add(map);
        }
        //查询总记录数
        sql = "select count(*) from user";
        ps = conn.prepareStatement(sql);
        rs = ps.executeQuery();
        if (rs.next()) {
            //获取总记录数
            int count = rs.getInt(1);
            //设置总记录数
            page.setTotalCount(count);
            //总页数=总数/每页数量 向上取整
            Double totalpage = Math.ceil((double) count / (double) page.getPageSize());
            page.setTotalPage(totalpage.intValue());
        }
        return page;
    }
}
标签: JDBC mysql JavaEE

本文转载自: https://blog.csdn.net/weixin_44593822/article/details/122756503
版权归原作者 深海鱼肝油ya 所有, 如有侵权,请联系我们删除。

“除夕快乐之三天学会JDBC(六)DbUtils工具&amp;分页技术”的评论:

还没有评论