数据库的查询操作会得到一系列数据,JDBC API也提供了相关对象来接收查询结果集。

一、ResultSet

java.sql.ResultSet接口表示数据库查询的结果集。

JDBC提供以下连接方法来创建具有所需ResultSet的语句:

  • createStatement(int RSType, int RSConcurrency);
  • prepareStatement(String SQL, int RSType, int RSConcurrency);
  • prepareCall(String sql, int RSType, int RSConcurrency);

RSType参数表示ResultSet对象的类型,RSConcurrency是两个ResultSet常量之一,用于指定结果集是只读还是可更新。

1. ResultSet类型

ResultSet.TYPE_FORWARD_ONLY:光标只能在结果集中向前移动。
ResultSet.TYPE_SCROLL_INSENSITIVE:光标可以向前和向后滚动,结果集对创建结果集后发生的数据库所做的更改不敏感。
ResultSet.TYPE_SCROLL_SENSITIVE:光标可以向前和向后滚动,结果集对创建结果集之后发生的其他数据库的更改敏感。

如果不指定任何ResultSet类型,默认是TYPE_FORWARD_ONLY值。

2. ResultSet的并发性

ResultSet.CONCUR_READ_ONLY 创建只读结果集
ResultSet.CONCUR_UPDATABLE 创建可更新的结果集
如果不指定任何并发类型,默认是CONCUR_READ_ONLY值。

3. 查看结果集

ResultSet接口包含数十种获取当前行数据的方法。
每个可能的数据类型都有一个get方法,每个get方法有两个版本,一个是采用列名称,一个是采用列索引(从1开始)。

注意:ResultSet在数据库连接关闭后(close掉)后就不能使用了,必须一直保持连接的状态才能使用,否则需要使用到RowSet离线结果集。

二、RowSet

RowSet接口继承自ResultSet接口。与ResultSet相比,RowSet默认是可滚动、可更新、可序列化的结果集,可以作为JavaBean来方便地在网络上传输,用于同步两端数据。对于离线RowSet而言,程序从创建RowSet时就已经把数据load进内存,因此可以更好地利用内存性能,降低数据库服务器的负载,提高程序性能。

1. 什么是离线结果集

如果直接使用ResultSet, 程序在得到ResultSet记录之后需要立即使用,否则一旦关闭Connection就不再可用,要解决这种情况要么将ResultSet的结果转换成JavaBean存储,要么在Connection关闭之前完成所有操作,不过这些办法都不太方便。

但是通过离线的RowSet却能很好地解决这个问题。RowSet可以将ResultSet的结果集封装成RowSet对象,存储在内存中进行数据操作,而Connection则可以断开。直到数据操作完成之后,重新再连接数据库,进行数据同步即可。

总结起来就是说,RowSet可以把数据库的数据放在内存中进行离线读写操作,操作完成之后再同步到数据库中去。

RowSet接口下包含了JdbcRowSet, CachedRowSet, FilteredRowSet, JoinRowSet, WebRowSet,除了JdbcRowSet之外,后面四个都是离线RowSet。

2. RowSetFactory

在JDK1.6及以前的版本中,如果要使用JdbcRowSet,则必须使用JdbcRowSetImpl的构造器来构造对象,但是在编译的时候会有警告,因此JdbcRowSetImpl是内部专用的API,在未来版本可能会删除。这种获取JdbcRowSet的方式是不推荐的,因为使用内部API,在将来的版本中可能不兼容,而且这样的程序直接与具体的实现类JdbcRowSetImpl耦合,不利于维护和升级。

在JDK1.7中,引入了RowSetFactory和RowSetProvider接口,其中RowSetProvider负责创建RowSetFactory,而RowSetFactory则可以通过以下方法创建RowSet实例。

  • createCachedRowSet()
  • createFilteredRowSet()
  • createJdbcRowSet()
  • createJoinRowSet()
  • createWebRowSet()

创建对象时可以传入ResultSet实例填充RowSet,也可以在创建JdbcRowSet实例之后通过execute(sql)方法得到数据填充RowSet。

//创建RowSetFactory
RowSetFactory rowSetFactory = RowSetProvider.newFactory();
//创建指定的RowSet
CachedRowSet rowSet = rowSetFactory.createCachedRowSet();
//将ResultSet放到RowSet中
rowSet.populate(resultSet);

3. 离线查询分页

所谓分页,就是一次只装载ResultSet的某几条记录,这样可以避免CachedRowSet内存占用过大的问题。

CachedRowSet控制分页的方法:

  • populate(ResultSet rs, int startRow) , 从第startRow行开始装载
  • setPageSize(int pageSize), 设置每页大小
  • previousPage(); 在底层ResultSet可用情况下,让CachedRowSet读取上一页记录
  • nextPage() 在底层ResultSet可用情况下,让CachedRowSet读取下一页记录
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import java.sql.*; public class ConnectionManager {
private static final String URL = "jdbc:mysql://192.168.178.5:12345/cloudDB01";
private static final String USER_NAME = "root";
private static final String PASSWORD = "123456"; static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("加载MySQL数据库驱动失败");
}
} public static void main(String[] args) throws Exception{
String sql = "select * from dept";
Connection connection = DriverManager.getConnection(URL,USER_NAME, PASSWORD);
PreparedStatement psmt = connection.prepareStatement(sql);
ResultSet resultSet = psmt.executeQuery(); RowSetFactory rowSetFactory = RowSetProvider.newFactory();
CachedRowSet rowSet = rowSetFactory.createCachedRowSet();
rowSet.setPageSize(2);
rowSet.populate(resultSet, 2);//从第二行开始
while (rowSet.next()){
System.out.println(rowSet.getString(2));
}
}
}

注:CachedRowSet是一次性加载所有数据,是内存分页,并不是物理分页,实际开发中用到的也较少。

普通结果集ResultSet和离线结果集RowSet(四)的更多相关文章

  1. JDBC入门(2)--- ResultSet之滚动结果集

    一.ResultSet之滚动结果集 ResultSet表示结果集,它是一个二维的表格.ResultSet内部维护一个行光标(游标),ResultSet提供了一系列的方法来移动游标: void befo ...

  2. 结果集(ResultSet)用法

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

  3. JavaEE JDBC 可滚动和可更新的结果集ResultSet

    可滚动和可更新的结果集ResultSet @author ixenos 需求背景 1.对于一个只需要分析数据的程序来说,普通的ResultSet已够用 2.但如果ResultSet用于显示一张表或查询 ...

  4. Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)

    上一篇文章我们已经将SQL发送到了数据库,并返回了ResultSet,接下来就是将结果集 ResultSet 自动映射成实体类对象.这样使用者就无需再手动操作结果集,并将数据填充到实体类对象中.这可大 ...

  5. Kubeadm 1.9 HA 高可用集群本地离线镜像部署【已验证】

    k8s介绍 k8s 发展速度很快,目前很多大的公司容器集群都基于该项目,如京东,腾讯,滴滴,瓜子二手车,易宝支付,北森等等. kubernetes1.9版本发布2017年12月15日,每三个月一个迭代 ...

  6. [K8s 1.9实践]Kubeadm 1.9 HA 高可用 集群 本地离线镜像部署

    k8s介绍 k8s 发展速度很快,目前很多大的公司容器集群都基于该项目,如京东,腾讯,滴滴,瓜子二手车,北森等等. kubernetes1.9版本发布2017年12月15日,每是那三个月一个迭代, W ...

  7. 用 edgeadm 一键安装边缘 K8s 集群和原生 K8s 集群

    背景 目前,很多边缘计算容器开源项目在使用上均存在一个默认的前提:用户需要提前准备一个标准的或者特定工具搭建的 Kubernetes 集群,然后再通过特定工具或者其他方式在集群中部署相应组件来体验边缘 ...

  8. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  9. redis 集群环境搭建-redis集群管理

    集群架构 (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽. (2)节点的fail是通过集群中超过半数的节点检测失效时才生效. (3)客户端与redi ...

随机推荐

  1. springcloud~配置中心~对敏感信息加密

    简介 RSA非对称加密有着非常强大的安全性,HTTPS的SSL加密就是使用这种方法进行HTTPS请求加密传输的.因为RSA算法会涉及Private Key和Public Key分别用来加密和解密,所以 ...

  2. MySQL的表定义语法

    表定义 只有成功创建数据库后,才能创建数据表,数据表是字段的集合,在表中数据按行和列的格式存储 创建表 MySQL 使用 CREATE TABLE 创建表.其中有多个选择,主要由表创建定义(creat ...

  3. LeetCode刷题191124

    博主渣渣一枚,刷刷leetcode给自己瞅瞅,大神们由更好方法还望不吝赐教.题目及解法来自于力扣(LeetCode),传送门. 算法: 给出一个无重叠的 ,按照区间起始端点排序的区间列表. 在列表中插 ...

  4. 使用动态SQL处理table_name作为输入参数的存储过程(MySQL)

    关于mysql如何创建和使用存储过程,参考笔记<MySQL存储过程和函数创建>以及官网:https://dev.mysql.com/doc/refman/5.7/en/create-pro ...

  5. linux常用命令总结篇

    关于linux的一些基础命令,以前也学过,但是长时间不用还是感觉生疏了,所以记录下来以便后期温故知新. 1. cd:cd命令用来切换工作目录至dirname.cd ~ 进入用户主目录,cd - 进入之 ...

  6. celery配置

    celery配置 celery的官方文档其实相对还是写的很不错的.但是在一些深层次的使用上面却显得杂乱甚至就没有某些方面的介绍, 通过我的一个测试环境的settings.py来说明一些使用celery ...

  7. shell中字典的一个用法示例

    1. shell中字典的用法示例, 数组用法同字典 2. 以上使用sell配合字典实现的功能, 使用awk能轻松搞定, 如下: awk '{print $2}' file.txt | sort | u ...

  8. Fiddler使用方法之Fiddler显示IP,Fiddler中文乱码解决方法以及Fiddler模拟发送get/post请求

    Fiddler是一个HTTP的调试代理,以代理服务器的方式,监听系统的Http网络数据流动,是我们常用的抓包工具之一 今天为大家分享一下几个使用Fiddler的小技巧 一.Fiddler抓包中文乱码问 ...

  9. 【洛谷5644】[PKUWC2018] 猎人杀(容斥+生成函数+分治NTT)

    点此看题面 大致题意: 有\(n\)个人相互开枪,每个人有一个仇恨度\(a_i\),每个人死后会开枪再打死另一个还活着的人,且第一枪由你打响.设当前剩余人仇恨度总和为\(k\),则每个人被打中的概率为 ...

  10. 2019年FJNU低编赛 G题(dfs博弈)

    ###题目链接### 题目大意: 有一个 0 ~ n+1 的数轴,Alice 站在 0 点处,Bob 站在 n+1 点处.在 1 ~ n 上各有着权值. Alice 每次向右移动 1 格或两格 ,Bo ...