详解Java如何判断ResultSet结果集是否为空

目录
  • 问题描述
  • 深究问题
    • ResultSet 的 Type 属性
  • 解决办法

问题描述

ResultSet 表示 select 语句的查询结果集。ResultSet 对象具有指向其当前数据行的指针, 最初,指针被置于第一行记录之前,通过 next() 方法可以将指针移动到下一行记录。

next() 方法在 ResultSet 对象没有一行记录时返回 false ,因此可以在 while 循环中使用它来遍历结果集,也可以利用该方法判断结果集是否为空。

示例代码如下:

//此处省略连接数据库的代码...

Statement stmt =conn.createStatement();
ResultSet  rs     =stmr.executeQuery("select  *  from  Test");

if(rs.next()){
System.out.println("结果集不为空!");
}

else{
System.out.println("结果集为空!");
}

此时出现第一个坑:Java 的 ResultSet 对象,默认是不可更新的,仅有一个向前移动的指针。

因此,只能遍历它一次,并且只能按从第一行到最后一行的顺序进行。

当你使用了 rs.next() 进行判断后,会出现第一行数据丢失的情况。

这也是我一开始遇到的问题。

深究问题

ResultSet 的 Type 属性

遇到问题后我第一想法是在搜索引擎上搜索相关解决办法,但看了一圈具体有以下“解法”:

调用 rs.last() 方法,以获取 ResultSet中 记录的总数,然后调用 rs.beforeFirst() 方法将光标移回到第一条记录前面

这种方法看上去可行,但当我实际修改后运行,却出现报错

Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.

这又是什么原因呢?

出现这个报错的主要原因是:

ResultSet.TYPE_FORWARD_ONLY 类型的 ResultSet 只允许向前遍历,不支持访问先前的记录或确定其大小。因此,使用 last() 和 getRow() 等方法都是不可行。

而 ResultSet 的 Type 属性有如下几种:

参数类型 说明
ResultSet.TYPE_FORWORD_ONLY 结果集的游标只能向下滚动
ResultSet.TYPE_SCROLL_INSENSITIVE 结果集的游标可以上下移动,当数据库变化时,当前结果集不变
ResultSet.TYPE_SCROLL_SENSITIVE 返回可滚动的结果集,当数据库变化时,当前结果集同步改变

当 Statement stmt = conn.createStatement(); 中 的 createStatement() 缺省时等价于: createStatement(ResultSet.TYPE_FORWORD_ONLY,ResultSet.CONCUR_READ_ONLY);

也就是结果集的游标只能向下滚动

所以才会出现 Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY. 的报错

也就是 ResultSet 默认情况下,只能使用 next() 方法向前逐行移动游标,而不支持 last()、first() 以及 absolute() 等方法,如果要使用 last()、absolute() 等方法,必须在由 Connection 生成 Statement 时指定相应的参数,格式如下:

Statement stmt =conn.ctrateStatement(游标类型,记录更新权限);

解决办法

1.手动指定游标类型

Statement stmt =conn.createStatement(ResultSet.TYPE_SCOLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

2.将 ResultSet 的内容复制到一个 List 中,然后检查 List 是否为空

List<Object[]> results = new ArrayList<>();
while (rs.next()) {
    int columnCount = rs.getMetaData().getColumnCount();
    Object[] row = new Object[columnCount];
    for (int i = 1; i <= columnCount; i++) {
        row[i - 1] = rs.getObject(i);
    }
    results.add(row);
}

if (!results.isEmpty()) {
    // ResultSet不为空,可以执行读取操作
} else {
    // ResultSet为空,不执行读取操作
}

请注意,在实际生产环境中,请考虑数据量和内存使用情况,因为将所有记录复制到List中可能对内存产生很大影响。

3.定义 一个计数变量 i ,每次 next() 则 ++i ,在 while() 循环结束后判断 i 是否小于等于 0

int i = 0;
while (resultSet.next()){
    System.out.println(...);
    ++i;
}
if(i<=0)
    System.out.println(...);

到此这篇关于详解Java如何判断ResultSet结果集是否为空的文章就介绍到这了,更多相关Java判断ResultSet是否为空内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • sqlserver和java将resultSet中的记录转换为学生对象

    目录 1.Student.java 2.DBUtil.java 3.result.java 4.实现结果 要将结果转化为对象,所以第一步要创建一个对象: 1.Student.java public class Student { //学号.姓名.班级.性别.专业.学院 //类中的属性一定要跟数据库中的一摸一样 包括名称,数据类型 private String 学号; private String 姓名; private String 班级; private String 性别; private

  • java打印表格 将ResultSet中的数据打印成表格问题

    目录 问题描述 思路 实现 测试 运行结果 总结 问题描述 MySQL的查询语句输出如下: mysql> select * from instructor;+-------+------------+------------+-----------+| ID    | name       | dept_name  | salary    |+-------+------------+------------+-----------+| 10101 | Srinivasan | Comp. Sc

  • java中ResultSet遍历数据操作

    1.查找数据库中表的列名 <pre name="code" class="html">String sql = "select *from tblmetadatainfo"; ResultSet rs = MySqlHelper.executeQuery(sql, null); String str=""; try { ResultSetMetaData rsmd = rs.getMetaData(); for (

  • Java使用PreparedStatement接口及ResultSet结果集的方法示例

    本文实例讲述了Java使用PreparedStatement接口及ResultSet结果集的方法.分享给大家供大家参考,具体如下: 说明: 1.PreparedStatement接口继承Statement,它的实例包含已编译的SQL语句,执行速度要快于Statement. 2.PreparedStatement继承了Statement的所有功能,三种方法executeUpdate.executeQuery.execute不再需要参数. 3.在JDBC应用中,一般都用PreparedStateme

  • Java ResultSet案例讲解

    ResultSet ResultSet是我们使用jdbc连接时,查询的一个返回结果集,ResultSet resultSet = stmt.executeQuery(sql),下面就使用例子介绍ResultSet的使用 例子是通过jdbc连接查account表中的数据,然后用实体类Account封装起来,返回这个类的集合.  jdbc工具类代码 package com.lingaolu.Utils; import java.io.FileReader; import java.io.IOExce

  • java sql ResultSet 之getRow()用法说明

    今天学习到sql中的ResultSet,用到了获取总函数,网上百度说是使用getRow()方法,但是一值返回0. 后台调试才发现getRow()并不是获取总行数,而是返回当前指针所在函数,故在不移动指针时一直为0. 附: 1.判断ResultSet行数是否为0: ResultSet表示select语句的查询结果集.ResultSet对象具有指向其当前数据行的指针, 最初,指针被置于第一行记录之前,通过next()方法可以将指针移动到下一行记录. next()方法在ResultSet对象没有一行记

  • 详解Java如何判断ResultSet结果集是否为空

    目录 问题描述 深究问题 ResultSet 的 Type 属性 解决办法 问题描述 ResultSet 表示 select 语句的查询结果集.ResultSet 对象具有指向其当前数据行的指针, 最初,指针被置于第一行记录之前,通过 next() 方法可以将指针移动到下一行记录. next() 方法在 ResultSet 对象没有一行记录时返回 false ,因此可以在 while 循环中使用它来遍历结果集,也可以利用该方法判断结果集是否为空. 示例代码如下: //此处省略连接数据库的代码..

  • 详解Java实现数据结构之并查集

    ​一.什么是并查集 对于一种数据结构,肯定是有自己的应用场景和特性,那么并查集是处理什么问题的呢? 并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题,常常在使用中以森林来表示.在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受:即使在空

  • 详解Java中数组判断元素存在几种方式比较

    1. 通过将数组转换成List,然后使用List中的contains进行判断其是否存在 public static boolean useList(String[] arr,String containValue){ return Arrays.asList(arr).contains(containValue); } 需要注意的是Arrays.asList这个方法中转换的List并不是java.util.ArrayList而是java.util.Arrays.ArrayList,其中java.

  • 详解java中String值为空字符串与null的判断方法

    Java空字符串与null的区别 1.类型 null表示的是一个对象的值,而不是一个字符串.例如声明一个对象的引用,String a=null. ""表示的是一个空字符串,也就是说它的长度为0.例如声明一个字符串String s="". 2.内存分配 String a=null:表示声明一个字符串对象的引用,但指向为null,也就是说还没有指向任何的内存空间. String s="":表示声明一个字符串类型的引用,其值为""空

  • 详解Java数据库连接JDBC基础知识(操作数据库:增删改查)

    一.JDBC简介 JDBC是连接java应用程序和数据库之间的桥梁. 什么是JDBC? Java语言访问数据库的一种规范,是一套API. JDBC (Java Database Connectivity) API,即Java数据库编程接口,是一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库.比如建立数据库连接.执行SQL语句进行数据的存取操作. JDBC代表Java数据库连接. JDBC库中所包含的API任务通常与数据库使用: 连接到数据库 创

  • 详解java调用存储过程并封装成map

    详解java调用存储过程并封装成map 本文代码中注释写的比较清楚不在单独说明,希望能帮助到大家, 实例代码: public List<Map<String , Object>> doCallProcedure(String procedureString,String[] parameters) throws PersistentDataOperationException { if (!isReady ()) { throw new PersistentDataOperatio

  • 详解Java 虚拟机垃圾收集机制

    1 垃圾收集发生的区域 之前我们介绍过 Java 内存运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈三个区域随线程共存亡.栈中的每一个栈帧分配多少内存基本上在类结构确定下来时就已知,因此这几个区域的内存分配和回收都具有确定性,不需要考虑如何回收的问题,当方法结束或线程结束,内存自然也跟着回收了 而 Java 堆和方法区这两个区域则有显著的不确定性,只有在程序运行时我们才能知道程序究竟创建了哪些对象,创建了多少对象,所以这部分内存的分配和回收是动态的,垃圾收集器所关注的正是这部分内存该

  • 详解Java类动态加载和热替换

    前言 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次加载后,会长期留驻JVM,直到JVM退出.这个说法,是不是正确的? 2) 在开发的一个集成平台中,需要集成类似接口的多种工具,并且工具可能会有新增,同时在不同的环境部署会有裁剪(例如对外提供服务的应用,不能提供特定的采购的工具),如何才能更好地实现? 针对上面的第2点,我们采用Java插件化开发实现.上面的两个问题,都和Java的类加载和热替换机制有关. 1. Java的类加载器和双亲委派模

  • 详解Java TCC分布式事务实现原理

    概述 之前网上看到很多写分布式事务的文章,不过大多都是将分布式事务各种技术方案简单介绍一下.很多朋友看了还是不知道分布式事务到底怎么回事,在项目里到底如何使用. 所以这篇文章,就用大白话+手工绘图,并结合一个电商系统的案例实践,来给大家讲清楚到底什么是 TCC 分布式事务. 业务场景介绍 咱们先来看看业务场景,假设你现在有一个电商系统,里面有一个支付订单的场景. 那对一个订单支付之后,我们需要做下面的步骤: 更改订单的状态为"已支付" 扣减商品库存 给会员增加积分 创建销售出库单通知仓

  • 详解Java分布式系统中session一致性问题

    业务场景 在单机系统中,用户登陆之后,服务端会保存用户的会话信息,只要用户不退出重新登陆,在一段时间内用户可以一直访问该网站,无需重复登陆.用户的信息存在服务端的 session 中,session中可以存放服务端需要的一些用户信息,例如用户ID,所属公司companyId,所属部门deptId等等. 但是随着业务的发展,技术架构需要调整,原来的单机系统逐渐被更换,架构由单机扩展到分布式,甚至当下流行的微服务.虽然在用户端看来系统仍然是一个整体,但在技术端来说业务则被拆分成多个模块,各个模块之间

随机推荐