欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA基础 之 RowSet

程序员文章站 2022-04-06 17:44:48
...

注意:

    1.本例建议在Java 7 下使用(尽管RowSet从1.4就出现过)

    2.由于很多人看到长代码就产生抵触情绪,本例将部分代码截段,使用时直接粘贴到主程序即可

 

概述:

 

    1.RowSet继承自ResultSet,但是它默认就是可滚动、可更新、可序列化(方便网络传输),可当作JavaBeans使用

       它下面主要有5个子接口JdbcRowSet、CachedRowSet、WebRowSet、JoinRowSet、FilteredRowSet

       JdbcRowSet:封装ResultSet,使得它能可以当作JavaBeans使用,但是它必须保持与数据库的连接(非离线)

       CachedRowSet:拥有JdbcRowSet所有功能,同时还能断开数据库连接进行离线操作

       WebRowSet:拥有所有的CachedRowSet功能,同时还能通过xml来描述自己(把自己写成xml,通过xml来配置自己)

       JoinRowSet:拥有所有WebRowSet的功能,同时它能在断开数据源的情况下做一个sql join(感觉就是java版的表连接,比如2个结果集 我通过什么字段将其关联成一个表,sql中的join(联表)操作)

       FilteredRowSet:有所有哦的WebRowSet的功能,如其名,可以做过滤操作(在不使用查询语句和断开数据源的情况下)

    2.优点

       1.某些子接口支持离线操作(可断开数据库连接)

          当前使用ResultSet的方式:

          方式1.将结果集遍历,封装成List<Map<String,Object>>,然后关闭数据库连接,使用这个封装好的对象(最常用的形式)

          方式2.再遍历使用ResultSet的过程,数据库连接一直处于打开状态,操作完毕后才关闭数据库连接(简单程序和初学者都这么干)

          方式1就是有一次转换的过程,无形中造成了性能的浪费,方式2的数据库连接一直处于打开状态,性能低且不安全。

          RowSet有很多可离线的子接口,解决了上面两种方式的所有问题,想必这是极好的~

        2.可当作JavaBeans使用,可序列化(方便网络传输)

    3.本例讲述的内容

       1.java7前RowSet的使用(比常规的5步使用jdbc简单很多)

       2.java7后RowSet的使用(更简单)

       3.演示离线的RowSet

       4.离线的RowSet操作

       5.RowSet的分页

 

更多的了解请看 http://docs.oracle.com/javase/tutorial/jdbc/basics/rowset.html

 

 

package com.cxy.test;

import java.sql.Connection;
import java.sql.DriverManager;

import javax.sql.rowset.JdbcRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;

import com.sun.rowset.JdbcRowSetImpl;

/**
 * @author cxy
 */
public class RowSetTest
{
	public static void main(String[] args) throws Exception
	{
		Class.forName("com.mysql.jdbc.Driver");
		//java7前的使用方法,是不是看起来简单很多~
		try
		(
				Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbtest", "root", "root");
				JdbcRowSet jrs=new JdbcRowSetImpl(con);  //传递一个con给JdbcRowSet构造器就可以啦
		)
		{
			jrs.setCommand("select * from t_student");
			jrs.execute();
			System.out.println("id\t姓名\t 性别");
			while(jrs.next())
			{
				System.out.println(jrs.getString(1)+"\t"+jrs.getString(2)+"\t"+jrs.getString(3));
			}
		}
		System.out.println("=======================");
		
		//java7开始 提供了RowSetFactory接口来生成各种RowSet
		RowSetFactory rsf=RowSetProvider.newFactory();  //先使用RowSetProvider创建一个RowSetFactory
		try
		(
			JdbcRowSet jrs=rsf.createJdbcRowSet();
		)
		{
			jrs.setUrl("jdbc:mysql://localhost/dbtest");
			jrs.setUsername("root");
			jrs.setPassword("root");
			jrs.setCommand("select * from t_student");
			jrs.execute();
			System.out.println("id\t姓名\t 性别");
			while(jrs.next())
			{
				System.out.println(jrs.getString(1)+"\t"+jrs.getString(2)+"\t"+jrs.getString(3));
			}
		}
		System.out.println("=======================");
		//是不是更简单了呢?我认为还是极好的~ 至少我只知道一个JdbcRowSet就可以进行数据库操作了,不像原来要创建各种对象
		//如果RowSet没有提供一个con的话,那么他将使用RowSetReader来完成execute方法
	}
}

上面演示了Java RowSet的基本用法。

 

亮点:离线功能演示

 

                //下面 我们来看一个离线版的RowSet,关闭数据库连接后仍然能使用的RowSet
		try
		(
				//由于JdbcRowSet是非离线的 所以 这里我们更换成一个离线的RowSet:CachedRowSet
				Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbtest", "root", "root");
				PreparedStatement pstmt=con.prepareStatement("select * from t_student", 
															 ResultSet.TYPE_SCROLL_SENSITIVE,
															 ResultSet.CONCUR_UPDATABLE);
				ResultSet rs=pstmt.executeQuery();
				CachedRowSet crs=rsf.createCachedRowSet();
		)
		{
			crs.populate(rs); //封装rs成CachedRowSet
			con.close();  //好了 我们将con这个关闭
			try
			{
				while(rs.next())
				{
					System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
				}
			}catch(Exception e)
			{
				System.out.println("由于con已经关闭,rs不能再被访问");
			}
			System.out.println("但是离线的crs仍可访问");
			System.out.println("id\t姓名\t 性别");
			while(crs.next())
			{
				System.out.println(crs.getString(1)+"\t"+crs.getString(2)+"\t"+crs.getString(3));
			}
		}
		System.out.println("=======================");

 

 

操作RowSet演示,以插入为例,更多的请看我博客中的《Java基础 之 ResultSet》

 

                //演示如果操作数据(这里演示的是如何插入数据)
		CachedRowSet crs1=rsf.createCachedRowSet();
		crs1.setUrl("jdbc:mysql://localhost/dbtest");
		crs1.setUsername("root");
		crs1.setPassword("root");
		crs1.setCommand("select * from t_student");
		crs1.execute();
		
		//这样的操作只能改变离线的RowSet
		crs1.moveToInsertRow();  //将指针移动到插入行,当前的位置将会被记住
		crs1.updateString(1, UUID.randomUUID().toString().replace("-", ""));
		crs1.updateString(2, "克隆人"+System.currentTimeMillis());
		crs1.updateString(3, "女");
		crs1.insertRow(); //必须和moveToInsertRow联合使用
		crs1.moveToCurrentRow(); //做完插入操作后,将指针指回到插入状态前的行
		crs1.beforeFirst();
		while(crs1.next())
		{
			System.out.println(crs1.getString(1)+","+crs1.getString(2)+","+crs1.getString(3));
		}
		
		//如果想同步数据库那么就需要重新连接数据库,然后把数据提交上去
		try
		(
				Connection con=DriverManager.getConnection("jdbc:mysql://localhost/dbtest", "root", "root");
		)
		{
			con.setAutoCommit(false);  //这句必须要否则会造成下面那句的异常
			crs1.acceptChanges(con);  //同步数据到数据库
		}
		System.out.println("=======================");

 

 

最后我们来看看它的分页功能

 

                //最后我们来看看分页
		/* 第一种方式 有ResultSet的
		 * crs.setPageSize(pageSize); //设置每页的大小
		 * crs.populate(rs, (page-1)*pageSize+1); //封装rs从第几行(根据页和每页大小算出)开始
		 * 个人觉得这种方式不好,因为 这个实际上还是先查出了所有结果rs,然后再同java的方式截取出咱们想要的那页数据
		 * */
		crs1.setPageSize(3); //每页显示几条
		crs1.execute();
		System.out.println(crs1.isBeforeFirst());
		int i=1;
		System.out.println("第"+i+"页:");
		while(crs1.next())
		{
			System.out.println(crs1.getString(1)+","+crs1.getString(2)+","+crs1.getString(3));
		}
		i++;
		while(crs1.nextPage())
		{
			System.out.println("第"+i+"页:");
			while(crs1.next())
			{
				System.out.println(crs1.getString(1)+","+crs1.getString(2)+","+crs1.getString(3));
			}
			i++;
		}

    说明:

 

       1.官方解释 每次nextPage都会创建一个新的CachedRowSet,每次只有PageSize条数据在内存中

       2.另外crs.previousPage();可以向前翻页

 

结束语:

    遗留问题:

    这种不创建con的方式,是通过RowSetReader去读取数据的,但是目前还没时间看它到底是如何实现的,它是每次读取数据都要做数据库连接么?每次执行完再关闭连接?如果是这样的话那会产生性能问题吧?处保险起见个人觉得还是弄个数据库连接池 然后将CachedRowSet中放一个con。

 

相关连接:

《Java基础 之 ResultSet》

《Java基础 之 ResultSetMetaData》

《Java基础 之 JDBC》

 

声明:

1.原创文章,转载请标明并加本文连接。

2.文章反映个人愚见,如有异议欢迎讨论指正

 

相关标签: java RowSet jdbc