数据库应用中,很多查询结果中的记录条数是很多的.如果一次取出返回给客户,会造成很大的问题.人们解决这个问题的方法就是分页.
java中最基础的jdbc 层,Resultset中,可以使用absolute()方法定位记录位置----记录的游标等类型是否要求滑动的,需要再确认.另外getRow()方法返回当前游标所在行号,从0开始计数. last()配上getRow()可以获取此次查询后得到的行数.
关于jdbc的使用,原先考虑过跨层之间传数据的问题,因为Resultset是有连接的,所以不适合用来传数据.中间想到把resultset转换成xml或其他的对象(比如pojo).本来想手工做,但后来研究发现,其实jdbc提供了更方便的方法.那就是RowSet接口,ResultSet可以把结果保存到 CachedReowset 这之类的对象中, 这些对象是无连接的,可以用作层之间传递大宗数据. 甚至好像还可以自动把Resultset直接 保存到xmlRow中吧,需要再确认了.
可见,有了rowset接口以后,至少可以省去手工把resultset 转换成其他比如bean 中的麻烦,但是这种自动转换的rowset 是否具有某种缺点或需要注意的地方,那就需要使用的时候再研究了.
在hibernate中也有比较方便的分页方法.session.createQuery() 以后得到的query接口中有setFirstResult() 和setMaxResults() 两个方法,可以实现分页. 如果再实现一个特别的类,在类中记录curPage,pageLen,然后通过计算,需要的时候再次从query中查询,就会比较方便的得到分页的功能了.只是要再专门的写类和方法才行,需要且也值得专门设计一下.
使用hibernate作为数据访问层,只能解决某些问题,对那些单个实体表和类的操作,确实非常简单,使用工具生成代码,甚至都不需要自己写代码. 但是对于复杂的连接查询(在实际的应用中非常多),其实hibernate是不能很好支持的.即使可以进行对象之间的一对一,多对多之类的映射,但象我之前写惯了sql的应用者,总觉得直接用sql来的快和省事.况且,很多复杂的连接查询,也没有办法用映射解决的.那些查询的条件有时候都要写好几行,你想,要是用映射怎么来表示呢? 本来的想法是使用hibernate的connection对象或者干脆做一独立的jdbc访问模块,和hibernate并列或者在hibernate的上面.经过研究之后又发现,hibernate提供了native sql的功能.可以使用session.createSQLQuery() 获得SQLQuery接口,然后通过配合 addScalar() 方法,可以获得一个对象列表. 这种方法也没有仔细研究呢,但这至少提供了一个方法,
需要进一步研究,到底是使用sqlQuery 还是直接使用session 的jdbc connection, 研究后再确定吧.
原生的sql语句还没有真正使用过,但是看的有些资料好像说不能查询没有映射的实体.如果是这样,那还是不够灵活,也不能满足我的特殊需求了.
这些只是思路,还没有设计出具体的方案,以后有时间再总结吧.
++++++++++++++++++++++++
在修改divs (和偶尔的channels修改也会遇到)时,遇到虽然调用了dao的update方法(save也一样),但是没有执行update操作到数据库,后来发现这是与manytoone 或 onetomany 有关的.如果在pojo中,有这两个关联,则需要小心处理更新的问题.我的divs类的情况是这样的,其中有一个manytoone到channels的关联,有了这个关联后,可能是后来我自己又为了方便还是怎么地,加了一个 channId的属性,导致这个类没有办法更新,而且还不报错,直到后来在onetomany下加了 @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE),再执行更新时,就打出update语句,原来是多出一个channid的属性设置--在update的set子句中.
看看这个够复杂吧,manytoone的属性,又跟onetomany搞上关系,真是云里雾里,现在我通过删除后来加上的channId属性,解决了这个问题,但是其实其中道理,还不是太明白的.大概要好好看看hibernate的内部机制才行, 这个还是应该值得研究一下的.
--hibernate reference 介绍 xml 的使用.可以看看.