一个可以重复遍历的RowSet

本文内容主要是对com.sun.rowset.CachedRowSetImpl工具类的使用样例

这里复习一下JBDC数据库查询

PreparedStatement pstmt = conn.prepareStatement(fsql);
ResultSet rs = pstmt.executeQuery();

这个ResultSet一般是只能遍历一次的,如果需要多次重复遍历一般会使用工具类com.sun.rowset.CachedRowSetImpl 将ResultSet的rs对象populate方法缓存,这样的花开只要每次beforeFirst下就可以重复遍历

CachedRowSet crs = new CachedRowSetImpl();
crs.populate(rs);
crs.beforeFirst();

将ResultSet转换为List<Map<String,T>> 或者List<Bean>一般是使用以下方式

List<Map<String,Object>> listMap=new ArrayList<Map<String,Object>>();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
Map<String, Object> bean=null;
	while(rs.next()){
		bean=new HashMap<String, Object>();
		for (int i = 0; i <columnCount; i++) {
			bean.put(metaData.getColumnName(i+1), rs.getObject(i+1));
		}
	listMap.add(bean);
}

 如果将List<Map<String,T>>转换为ResultSet呢? 网络上一般都是使以下方式创建多个列的结果集,大致原理步骤就是首先数据库使用sql创建多个字段先查询出一个没有记录数的结果集,且先转换为缓存的结果集,然后将列表数据根据不同列塞入

Strng fsql="SELECT '' AS COLUM_1,'' AS COLUM_2 FROM DUAL WHERE 1=2 ";
PreparedStatement pstmt = conn.prepareStatement(fsql);
ResultSet rs = pstmt.executeQuery();
CachedRowSet crs = new CachedRowSetImpl();
crs.populate(rs);
crs.beforeFirst();

List<Map<String,String>> listBean=new ArrayList<>();

String[] colNames=new String[]{"CLOUM_1","CLOUM_2"};

for (Map<String, String> bean : listBean) {
     rs.last();
     rs.moveToInsertRow();
     for (String columName : colNames) {
        rs.updateObject(columName,bean.get(columName));
     }
     rs.insertRow();
     rs.moveToCurrentRow();
     rs.beforeFirst();
}

 以上方法虽然可以解决问题,,但是让我不能忍受的是(需要连接数据库,很烦),但对日常模拟测试,可优化为以下代码

public static <T> RowSet list2RowSet(List<Map<String, T>> listBean, Set<String> colNames) throws SQLException {
		if (listBean == null) {
			listBean = new ArrayList<Map<String, T>>();
		}
		if (colNames == null || colNames.isEmpty()) {
			throw new RuntimeException("行至少有一列");
		}
		CachedRowSetImpl rs = new CachedRowSetImpl();
		RowSetMetaData metaData = new RowSetMetaDataImpl();
		rs.setMetaData(metaData);
		metaData.setColumnCount(colNames.size());
		int columnIndex = 0;
		for (String columName : colNames) {
			metaData.setColumnName(++columnIndex, columName);
			metaData.setColumnLabel(columnIndex, columName);
		}
		for (Map<String, T> bean : listBean) {
			rs.last();
			rs.moveToInsertRow();
			for (String columName : colNames) {
				rs.updateObject(columName, bean.get(columName));
			}
			columnIndex = 0;
			rs.insertRow();
			rs.moveToCurrentRow();
			rs.beforeFirst();
		}
		return rs;
	}

测试方法

public static void main(String[] args) {
		try {
			List<Map<String, Object>> listBean = new ArrayList<Map<String, Object>>();
			for (int i = 0; i < 5; i++) {
				Map<String, Object> bean1 = new HashMap<String, Object>();
				bean1.put("USER_NAME", "邓霖涛_" + i);
				bean1.put("PASSWORD", Math.random());
				listBean.add(bean1);
			}
			Set<String> colNames = listBean.get(0).keySet();
			RowSet rs = list2RowSet(listBean, colNames);

			//打印输出
			while (rs.next()) {
				System.out.println(rs.getObject("USER_NAME"));
				System.out.println(rs.getObject("PASSWORD"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

输出测试结果

 总结:com.sun.rowset.CachedRowSetImpl 类简单来说就是一个实现了RowSet接口与的一个缓存实现,具体可以查看对于源码,可对内部所有元数据重新定义,数据插入等等, 对目前来说这个工具类好像没什么鸡毛用处,但对于老系统(十几年前的可能还是JDBC直接操作RowSet,前端组件都可能是使用RowSet进行遍历生成相应的UI表格等等),还是可以了解一般

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓霖涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值