目录
一.DbUtils工具
1.概述
2.通过QueryRunner添加数据
3.通过QueryRunner查询数据?
4.自定义ResultSetHandler
二.分页技术
1.概述
2.数据库中的分页使用
3.JDBC分页
一.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;
}
}
2.
当
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;
}
}
|