求助JAVA使用JDBC连接数据库,while (rs.next())循环拿数不全

CXYliukai 2021-04-08 05:00:08
查询的是数据库名称,账号权限足够,while (rs.next())循环时,有时不进入循环
查的数据少



/**
* 查询库名
*
* @return
*/
public List<String> GetLibList() {
List<String> result = new ArrayList();
try {
String sql = "select SCHEMA_NAME from information_schema.schemata";
// 创建sql语句执行器
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
// ResultSetMetaData rs_metaData = rs.getMetaData();
while (rs.next()) {
String a = new String();
a = rs.getString("SCHEMA_NAME");
result.add(a);
}
return result;
} catch (Exception e) {
return result;
}
}
...全文
718 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰思雨 2021-04-09
  • 打赏
  • 举报
回复
哦。补充一下哈, 上一次查询创建的 Statement、PreparedStatement 不会自动关闭或者回收,只有连接断开了,才有可能被自动回收。所以,如果不显示的关闭这些对象,会有内存泄露的风险,不是对象占用的内存,而是对象所保持的资源,有可能不能被有效的进行回收。 上一次查询创建的 ResultSet 对象,会在下一次查询的时候被强制关闭。
冰思雨 2021-04-09
  • 打赏
  • 举报
回复
引用 6 楼 CXYliukai 的回复:
捕获的异常是:java.sql.SQLException: After end of result set 加上rs.next();和不加rs.next();正好是真实的数据库名称
你这个异常在单线程访问数据库的情况下是不会出现的,应该是多线程情况下出现了这种问题。 解决方案是,不要使用全局性质的数据库连接,换句话说,就是 函数中的 conn 对象要在每个函数当中独立获取,而不是写成成员变量或者全局变量的形式共享给每个函数。 我这样写,你能看的明白吗? 你写一个获取连接的函数,每次要使用 conn 的时候,都调用这个函数进行获取,然后,获取函数的函数体里面,通过数据源或者工厂类的对象进行新连接的创建,然后,使用完连接之后,记得关闭连接。 下面解释一下这个异常的本身的含义: 结果集 ResultSet 的游标已经访问完最后一个了,你依然还要针对下一个记录进行访问,由于没有可访问的记录才抛出当前异常。 多个线程同时使用一个数据库连接进行数据库访问时,每次访问都会清理回收一些资源。 比如,上一次查询时创建的 Statement、PreparedStatement、ResultSet 等对象,都会被关闭或者回收。 因为,如果不将上一次查询的游标进行关闭,下一次(当前)查询的结果就无法进行遍历。同一连接,同时只能操纵一个游标进行数据库访问。 楼主的异常状况就是 ResultSet 在遍历的过程中,被后续查询给强行关闭了,造成了访问数据不全的情况。 另外,楼主的代码里面,有个非常严峻的问题,就是没有显示的关闭 Statement、PreparedStatement、ResultSet 等对象,在程序出现异常时,会有很大隐患产生。 数据库的访问过程中会用到很多对象,这些对象都会存在生命周期的,我们编程人员要把控好这些对象的生命周期,不要依赖JVM的垃圾回收,很多情况下要显示的进行资源的关闭处理,以免造成内存泄露和其他的隐患,因为,垃圾回收只回收对象,对象所占有的资源未必会被同时回收,要显示调用 close 方法。 例如:关闭 conn 和 回收 conn 对象所占用的内存,是两个概念。 关闭 conn 是将本程序与数据库建立的通信连接断开,但是,conn 对象仍然在内存中。回收 conn 对象,则是将内存清掉,但是,本地与数据库的通信连接会被操作系统代理维护,没有显示的调用 close 方法的话,这个连接就不会及时被关闭了。
qq_39936465 2021-04-09
  • 打赏
  • 举报
回复
引用 5 楼 CXYliukai 的回复:
[quote=引用 2 楼 nayi_224 的回复:]虽然可能性不大但是自己吞异常也不是好习惯
        } catch (Exception e) {
e.printStackTrace();
                return result;
        }
再就是看下是否连错数据库
数据库连接的没问题,换了另一个数据库还是这样,明天这样试试看[/quote] 你可以在循环中设置打印语句控制台输出,看看取得了那些值,再和数据库对比一下。
CXYliukai 2021-04-09
  • 打赏
  • 举报
回复
引用 2 楼 nayi_224 的回复:
虽然可能性不大但是自己吞异常也不是好习惯
        } catch (Exception e) {
e.printStackTrace();
                return result;
        }
再就是看下是否连错数据库
捕获的异常是:java.sql.SQLException: After end of result set 加上rs.next();和不加rs.next();正好是真实的数据库名称
CXYliukai 2021-04-09
  • 打赏
  • 举报
回复
引用 8 楼 冰思雨 的回复:
[quote=引用 6 楼 CXYliukai 的回复:] 捕获的异常是:java.sql.SQLException: After end of result set 加上rs.next();和不加rs.next();正好是真实的数据库名称
你这个异常在单线程访问数据库的情况下是不会出现的,应该是多线程情况下出现了这种问题。 解决方案是,不要使用全局性质的数据库连接,换句话说,就是 函数中的 conn 对象要在每个函数当中独立获取,而不是写成成员变量或者全局变量的形式共享给每个函数。 我这样写,你能看的明白吗? 你写一个获取连接的函数,每次要使用 conn 的时候,都调用这个函数进行获取,然后,获取函数的函数体里面,通过数据源或者工厂类的对象进行新连接的创建,然后,使用完连接之后,记得关闭连接。 下面解释一下这个异常的本身的含义: 结果集 ResultSet 的游标已经访问完最后一个了,你依然还要针对下一个记录进行访问,由于没有可访问的记录才抛出当前异常。 多个线程同时使用一个数据库连接进行数据库访问时,每次访问都会清理回收一些资源。 比如,上一次查询时创建的 Statement、PreparedStatement、ResultSet 等对象,都会被关闭或者回收。 因为,如果不将上一次查询的游标进行关闭,下一次(当前)查询的结果就无法进行遍历。同一连接,同时只能操纵一个游标进行数据库访问。 楼主的异常状况就是 ResultSet 在遍历的过程中,被后续查询给强行关闭了,造成了访问数据不全的情况。 另外,楼主的代码里面,有个非常严峻的问题,就是没有显示的关闭 Statement、PreparedStatement、ResultSet 等对象,在程序出现异常时,会有很大隐患产生。 数据库的访问过程中会用到很多对象,这些对象都会存在生命周期的,我们编程人员要把控好这些对象的生命周期,不要依赖JVM的垃圾回收,很多情况下要显示的进行资源的关闭处理,以免造成内存泄露和其他的隐患,因为,垃圾回收只回收对象,对象所占有的资源未必会被同时回收,要显示调用 close 方法。 例如:关闭 conn 和 回收 conn 对象所占用的内存,是两个概念。 关闭 conn 是将本程序与数据库建立的通信连接断开,但是,conn 对象仍然在内存中。回收 conn 对象,则是将内存清掉,但是,本地与数据库的通信连接会被操作系统代理维护,没有显示的调用 close 方法的话,这个连接就不会及时被关闭了。 [/quote]首先谢谢您,是我循环的时候出现了问题。 我给JComboBox赋值的时候 是这样写的

List<String> list= GetLibList();
for (int i = 0; i < list.size(); i++) {
jC.addItem(list.remove(i));
}
这样循环就没事了

list.forEach(s -> jC.addItem(s));
CXYliukai 2021-04-08
  • 打赏
  • 举报
回复
引用 2 楼 nayi_224 的回复:
虽然可能性不大但是自己吞异常也不是好习惯
        } catch (Exception e) {
e.printStackTrace();
                return result;
        }
再就是看下是否连错数据库
数据库连接的没问题,换了另一个数据库还是这样,明天这样试试看
CXYliukai 2021-04-08
  • 打赏
  • 举报
回复
引用 3 楼 冰思雨 的回复:
你这代码,不存在直接跳过循环的情况。 如果 rs.next() 返回 false ,循环就直接结束了,怎么会跳过? 如果 rs.next() 返回 true,那就一定会进入循环体,既然进入了循环体,就一定不是跳过循环的状况了。 另外,异常没有进行处理。代码当中吞掉异常,是最不可取的,当程序出现问题的时候,吞掉异常会增加问题排查的难度。 楼主的这段代码,出现问题最可能的原因有两个: 1. 程序连接的账户权限没给全,所以,查询的数据可能不全;(当然,楼主说权限管够,那就不考虑了) 2. 循环过程中抛出了异常,比如,循环第8条数据的时候抛出异常,然后,异常被吞了,直接返回了7条记录。
我赞成第二点,刚写java不太懂,明天上班了在研究一下
冰思雨 2021-04-08
  • 打赏
  • 举报
回复
你这代码,不存在直接跳过循环的情况。 如果 rs.next() 返回 false ,循环就直接结束了,怎么会跳过? 如果 rs.next() 返回 true,那就一定会进入循环体,既然进入了循环体,就一定不是跳过循环的状况了。 另外,异常没有进行处理。代码当中吞掉异常,是最不可取的,当程序出现问题的时候,吞掉异常会增加问题排查的难度。 楼主的这段代码,出现问题最可能的原因有两个: 1. 程序连接的账户权限没给全,所以,查询的数据可能不全;(当然,楼主说权限管够,那就不考虑了) 2. 循环过程中抛出了异常,比如,循环第8条数据的时候抛出异常,然后,异常被吞了,直接返回了7条记录。
nayi_224 2021-04-08
  • 打赏
  • 举报
回复
虽然可能性不大但是自己吞异常也不是好习惯
        } catch (Exception e) {
e.printStackTrace();
                return result;
        }
再就是看下是否连错数据库
CXYliukai 2021-04-08
  • 打赏
  • 举报
回复
例如:有十条数据,只能查出来七条,有三次直接跳过循环

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧