日期:2014-05-20  浏览次数:20760 次

Java一个C/S的系统,如何传递记录集
小弟要做一个C/S结构的系统,在客户端发送命令,服务器端响应并查询数据库,然后返回得到的记录集,然后问题来了,如何在网络上传送记录集,我是这样做的,把记录集都存到一个Vector对象中,代码如下:
while(rs.next()){
if(temp){
soldto = new SoldToRef(rs.getString(1),
rs.getString(2)
);
SoldTos.add(soldto);
  }
}
SoldTos是一个Vector对象,但是我用:
Client.output.writeObject(SoldTos);
Client.output.flush();
写入输入输出流时就出错了,提示: java.io.NotSerializableException,为什么呢?
哪位大侠能否指示一下在C/S结构中如何传递记录集呢?最好能够给出实现的代码,万分感激!

------解决方案--------------------
不能直接将数据集(ResultSet)通过网络来传递,因为ResultSet是需要在线的,所以不能被序列化后进行传输。

请将结果集全部转为 List ,然后再将List进行传递。
------解决方案--------------------
没有那么复杂吧?
ArrayList result = new ArrayList();
while(rs.next()) {
VO vo = new VO(); // 值对象,偷懒用HashMap也行。
vo.setFiled(rs.getString(1)); // 把所有字段都取出来放入值对象
...
result.add(vo);
}
Client.output.writeObject(result);

------解决方案--------------------
VO是表示下值对象,你应该用过值对象?
用HashMap来代替也可以,Key就用序号或者字段名,Value就是字段值。


客户端没必要还原记录集吧,直接用ArrayList不就好了?
如果非要用ResultSet,那就只能用CachedRowSet了,具体可以Google下。
但是即便用了CachedRowSet,传递给目标客户端后,也只能做查询而不能做更新了。



最后还有一招,也是最不推荐的,就是客户端直接远程使用服务器端提供的JDBC数据源。
------解决方案--------------------
我觉得不是2楼的原因,因为楼主已经把rs封装到vector里了。
关键在Client.output.writeObject(SoldTos);
SoldTos里是不是装有没有实现Serializable接口的对象。
把这些对象实现Serializable接口再装入Vector即可。

另外,如果你是内部使用,还是CS,同意1楼的方案使用RMI,具体案例自己百度谷歌吧。
------解决方案--------------------
你看你哪个对象没有实现Serializable接口吧。
要想将对象序列化,那么,对象所属的类以及里面的成员变量,必须都要实现Serializable接口。
原始类型,有它们的封装类来代替。

题外话,
发送集合倒是可以,但是,集合与结果集,是有区别的。
我们查询一个百万条数据的表,查询全表内容,之后只遍历前十条记录就关闭结果集。
这时,其实,内存中,一般只存放fetchSize条(貌似是30多条)记录,
但是,如果我们把结果集的所有数据都发给客户端,客户端遍历前十条,然后把数据扔了。
这会是什么现象?
服务端要先缓存百万条记录到内存,然后发送,客户端在缓存,结果,只用到了前十条。
并且,期间,爆掉内存是常有的事情。