锁定老帖子 主题:一种传递分页参数的方法
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-03-01
就为了一个简单的分页参数封装,搞一个ThreadLocal,我觉得还不如传这个参数来得方便。
另外,我有点疑惑,请楼主明示。一般我们分页做查询的时候,查询条件有很多,你的这种做法,在做“下一页”的时候,这些原先的查询条件在哪里?怎么取到?难道你不认为这些查询条件和分页参数其实没什么差别嘛? |
|
返回顶楼 | |
发表时间:2006-03-02
Prentice 写道 ajoo 写道 dao肯定是不需要pagination的。service需要么? 举个service接口需要pagination的例子? 我现在的做法是 Web层的Action调用service,servic调用dao 或是直接调用hibernateTemplate进行持久化操作。虽然有一些service操作代表的业务逻辑本身就是持久化操作,可以Action直接调用dao,但是我还是通过service调用Dao,这样一方面可以在service提供事务处理,另外就是统一得在service层建立一个业务逻辑的接口。这样就需要通过service将Pagination传递到Dao。 比如查询用户 UserDao 有一个方法 : List findUser( Date birthday , Pagination p ); 如果你选择直接在Action里调用UserDao的这个方法,那么就不需要用我说的方法。 而我的做法是 service层有个UserManager,他有一个同样的方法: List findUser( Date birthday , Pagination p ); 这个方法内,调用UserDao 的findUser,这样UserManager的接口上就要Pagination,这里出现Pagination的目的只是为了传递给Dao。 另一种情况,如果你把所有的查询操作从一个个service对象中抽取出来,有专门的QueryManager,那么Pagination出现在这些查询对象的接口上,我觉得也是正常的。 为什么不肯举个具体的例子呢? 没例子很难沟通的。 你这里的pagination看来是service和dao层通吃的一个数据结构了? 一个思路,能不能做一个两层通吃的Query对象呢?(只是个思路,不见得可行) 或者,能不能给service和dao各加一个withPagination()函数呢? interface UserService{ UserService withPagination(Pagination p);; User findById(String id);; User findByName(String name);; ...... } interface UserDao{ UserDao withPagination(Pagination p);; User findById(String id);; User findByName(String name);; ... } 只要每个dao和每个service加一个withPagination()就好了,不需要每个方法都加。 withPagination()是immutable的,所以不用担心状态变化问题。 用的时候,就: dao.withPagination(pagination);.findByName(...);; 要是还有其它的横切所有查询方法的逻辑,也可以再增加withOrder()之类的方法。 |
|
返回顶楼 | |
发表时间:2006-03-02
ajoo,你这种方法,withPagination()方法返回的是什么?一个新的service/dao对象实例?本来service对象和dao对象可以是singleton的,按照你的这种方法,singleton可以吗?
|
|
返回顶楼 | |
发表时间:2006-03-02
如果是immutable的,当然返回一个新的dao对象了。这个对象和原来的旧dao对象肯定都共享很多资源的,基本上就是一个非常轻量级的decorator,所以singleton与否没有多大意义吧?节省那么几次创建对象的开销能省几个银子?
而如果是mutable的,就返回this。这样就可以singleton了。 mutable的优点,在于实现起来方便。缺点,在于状态会发生变化,如果用的不好,很可能出现不应该发生的分页之类的错误(比如,别的request做的分页影响到了当前request)。 |
|
返回顶楼 | |
发表时间:2006-03-02
我看DAO/SERVICE一般写好了就比较稳定了,不会经常改动,省那几个方法,多了些不稳定因素得不偿失。
不过觉得还是把查询条件参数跟分页参数分开,我的看法是DAO可以用两个参数QueryObject, Pagination。Order要放也放在QueryObject里面。理由基本同Prentice之前所述,Pagination只是一个适应不同输出环境的参数。举个例子pda上,可能是10/page,PC上可能是30/page…… |
|
返回顶楼 | |
发表时间:2006-03-02
User findById(String id);
User findByName(String name); 如果这样呢 User find(Object form){ UserSearchForm doForm = (UserSearchForm)form; } 我一直是这么实现的 感觉接口更简化些 ---------------------------------------------------- 当进行多个不定数参数参数后在进行此基础上的跳页 是否考虑在内 |
|
返回顶楼 | |
发表时间:2006-03-02
ajoo 写道 为什么不肯举个具体的例子呢? 没例子很难沟通的。 Prentice 写道 .... 比如查询用户 UserDao 有一个方法 : List findUser( Date birthday , Pagination p ); 如果你选择直接在Action里调用UserDao的这个方法,那么就不需要用我说的方法。 ... 这就是我举的例子啊,是不是简单了一点 to ajoo: 另外,每次接受到一个http请求,都会创建一个新action,那么这个withPaginatin后的service可否每次由Ioc容器创建并注入新创建的action? 从解决具体问题的角度,使用参数传递Pagination,使用Query对象,还有ajoo提出的withPagination方法,都是可以的。我个人比较倾向于将查询独立出来,就是ajoo说的srevice,dao通吃的Query对象,这样就没有必要用threadlocal,web层的action直接面对Query。 扯开点说, 我在pagination上遇到的问题是:当系统结构分成多个层后, 会不会遇到某些参数需要跨层传递的情况 , 比如 WEB, Service, Dao三层, 某些参数在WEB 层获得,Dao层要使用,而Service层并不需要,现在的做法就是这些参数通过service传递给Dao。有没有其它方法? 我提出使用Threadlocal原因,是Spring用这种方法实现OpenSessionInView,我认为这种方法就是将hibernate Session看做当前request的一个资源 per request per session,因为request和线程相对应,所以session和线程绑定也顺理成章。那么能不能将pagination和当前的session绑定呢? 因为dao要使用pagination参数的目的就是减少不必要的数据库操作,提高性能,可否将Pagination看成当前session的附加参数。 |
|
返回顶楼 | |
发表时间:2006-03-02
你这个例子的问题是没有表现出用pagination当参数有什么不好。
withPagination自己就创建并注射了所有依赖,不需要也不应该依赖任何ioc容器。 一个大小通吃的Query对象好像不是那么好设计的。毕竟query或者criteria多种多样,你怎么能够统一表示呢?用visitor? 我不了解opensessioninview,反正我知道通过全局变量传递信息往往是非常糟糕的方法。threadlocal不过是单线程化了的全局变量。 |
|
返回顶楼 | |
发表时间:2006-03-02
可否这样:
//service interface UserService{ List processQueryWithPagination(Query query, Pagination p);; List processQuery(Query query);; Query findById(String id);; //no transaction declaration ...... } //action List result = (List);userService.processQueryWithPagination(userService.findById(id);, pagination);; 但是对客户端调用有了规则,还是不够理想。。。 |
|
返回顶楼 | |
发表时间:2006-03-02
ajoo 写道 你这个例子的问题是没有表现出用pagination当参数有什么不好。
对于单个的例子无所谓好坏。 如果当系统内每个service的接口上都出现许多Pagination参数,而这些Service都只是二传手,将pagination传递给Dao时,我就想是不是有其他方法传递参数。 目前,系统分层后,在web层action对象是面对每个用户的请求的,而从service开始就不分用户,或者说是面对所有用户,这样所有用户请求中包含的参数都需要通过service的接口传递下去。 |
|
返回顶楼 | |