CachedRowSet Invalid scale size. Cannot be less than zero

本文介绍了解决使用CachedRowSet时出现的“Cannot be less than zero”错误的方法。通过升级JDK版本或调整查询方式可以有效避免这一问题。
在项目中有用到CachedRowSet这个类
在底层封装的方法中,将调用执行方法的返回参数ResultSet,丢入CachedRowSet
在调用populate(rs)时报了这个错:CachedRowSet Invalid scale size. Cannot be less than zero.上网搜了下,似乎这是JDBC的BUG,对数值型的封装有误。
我将JDK从1.5换为了1.6,问题解决。
或者将NUMBER型的字段,在查询时+0,如:
select num+0 num from tableName也可以解决此问题
如果想脱敏所有列 怎么修改下面的代码 import java.sql.*; import java.util.HashSet; import java.util.Set; import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.RowSetProvider; public class DataMasker { // 脱敏规则实现 public static ResultSet maskSensitiveData(ResultSet originalRs) throws SQLException { // 创建可离线操作的CachedRowSet CachedRowSet crs = RowSetProvider.newFactory().createCachedRowSet(); crs.populate(originalRs); return new ResultSetWrapper(crs) { // 定义需要脱敏的字段名 private final Set<String> maskedColumns = new HashSet<String>() {{ add("name"); // 实际根据业务需求添加字段 add("phone"); // 示例字段 }}; @Override public String getString(String columnLabel) throws SQLException { String value = super.getString(columnLabel); return maskedColumns.contains(columnLabel.toLowerCase()) ? maskString(value) : value; } }; } // 具体脱敏逻辑 private static String maskString(String origin) { if (origin == null || origin.isEmpty()) return origin; final int keepChars = 1; // 保留前1位明文 if (origin.length() <= keepChars) { return origin + "*"; // 短字符串处理 } // 构造脱敏字符串: 保留前N位 + 星号填充 StringBuilder masked = new StringBuilder(origin.substring(0, keepChars)); for (int i = keepChars; i < origin.length(); i++) { masked.append('*'); } return masked.toString(); } // ResultSet包装类 private static abstract class ResultSetWrapper implements ResultSet { protected final ResultSet delegate; public ResultSetWrapper(ResultSet delegate) { this.delegate = delegate; } // 默认实现所有ResultSet方法(实际需要重写数百个方法,此处简化) @Override public boolean next() throws SQLException { return delegate.next(); } @Override public String getString(int columnIndex) throws SQLException { return delegate.getString(columnIndex); } // ... 其他方法委托给原始ResultSet // 关键重写方法 @Override public String getString(String columnLabel) throws SQLException { return delegate.getString(columnLabel); } } // 使用示例 public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/pced"; String user = "root"; String password = "pass123"; try (Connection conn = DriverManager.getConnection(url, user, password); PreparedStatement pstmt = conn.prepareStatement("SELECT id, name, phone FROM t_test")) { ResultSet rs = pstmt.executeQuery(); ResultSet maskedRs = maskSensitiveData(rs); while (maskedRs.next()) { System.out.println("ID: " + maskedRs.getInt("id") + " | Name: " + maskedRs.getString("name") + " | Phone: " + maskedRs.getString("phone")); } } catch (SQLException e) { e.printStackTrace(); } } }
09-03
public static ResultSet maskSensitiveData(ResultSet originalRs, String ruleJson) throws SQLException { // 创建可离线操作的CachedRowSet CachedRowSet crs = RowSetProvider.newFactory().createCachedRowSet(); crs.populate(originalRs); return new PgResultSetWrapper(crs) { // 定义需要脱敏的字段名 private final Set<String> maskedColumns = new HashSet<String>() {{ //this.addAll(set); //todo 时间类型无法脱敏 加上之后返回值为null,待测试去掉情况 add("name"); add("salary"); }}; @Override public String getString(String columnLabel) throws SQLException { String value = super.getString(columnLabel); return maskedColumns.contains(columnLabel.toLowerCase()) ? maskString(value, ruleJson) : value; } }; } private static String maskString(String origin, String ruleJson){ int length = origin.length(); String desData=""; if (ruleJson != null){ String maskType = JdbcConfig.getMaskType(""); String[] split = ruleJson.split("&"); for (String s : split) { String[] rule = s.split(","); Integer minLength = Integer.valueOf(rule[0]); Integer maxLength = Integer.valueOf(rule[1]); Integer front = Integer.valueOf(rule[2]); Integer back = Integer.valueOf(rule[3]); if (length>minLength && maxLength>length){ if (("1".equals(maskType))){ int maskLen = Math.max(0, length - front - back); StringBuilder maskBuilder = new StringBuilder(); for (int i = 0; i < maskLen; i++) { maskBuilder.append('*'); } String maskStars = maskBuilder.toString(); desData = origin.substring(0, front) + maskStars + (back > 0 ? origin.substring(length - back) : ""); }else if ("2".equals(maskType)){ StringBuilder sb = new StringBuilder(origin); // 屏蔽前部 for (int i = 0; i < Math.min(front, length); i++) { sb.setCharAt(i, '*'); } // 屏蔽后部 for (int i = Math.max(length - back, 0); i < length; i++) { sb.setCharAt(i, '*'); } desData = sb.toString(); }else { return origin; } } } } return desData; } 加上这些代码之后 timestamp和date类型返回null怎么解决
09-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值