锁定老帖子 主题:一种传递分页参数的方法
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-02-28
感觉这样做,接口变得晦涩,完全没有必要。
极端情况,不是啥参数都可以放到threadLocal里传递? 对于常变化的参数,象hongliang说的,传递一个通用Query对象,比较好。就算不考虑分页,这样处理也是有理由的,其他查询条件的变化通常也会比较频繁。 |
|
返回顶楼 | |
发表时间:2006-02-28
反对这种做法,我一次web request过程中,可能牵涉n个Service的m个DAO调用,可能涉及x种domain对象的分页处理,你要在ThreadLocal里面分别传递好多个分页参数,而且还必须清楚的区分哪个参数是哪个DAO用到的。这种大量隐式契约的编程味道太坏了。
其实分页很简单,封装一个Pagination对象,所有需要传入传出的参数都封装在里面就OK了,Hibernate版我贴过代码的,用起来很方便。 |
|
返回顶楼 | |
发表时间:2006-02-28
partech 写道 感觉这样做,接口变得晦涩,完全没有必要。
极端情况,不是啥参数都可以放到threadLocal里传递? 对于常变化的参数,象hongliang说的,传递一个通用Query对象,比较好。就算不考虑分页,这样处理也是有理由的,其他查询条件的变化通常也会比较频繁。 你的意思是不支持楼主的ThreadLocal的做法? 给你看我现在的BaseDao类,其中大概有这样几个方法: public interface BaseDao { //... List findListByClass(Class clazz, QueryMeta qm);; List findListByHql(String hql, Object value, QueryMeta qm);; List findListByHql(String hql, Object[] values, QueryMeta qm);; List findListByHql(String hql, QueryMeta qm);; //... } 每个方法里都要套个QueryMeta参数,如果用楼主的方法,代码就可以变成: public interface BaseDao { //... List findListByClass(Class clazz);; List findListByHql(String hql, Object value);; List findListByHql(String hql, Object[] values);; List findListByHql(String hql);; //... } 就简洁许多叻,QueryMeta对象由实现类在实现代码中用ThreadLocal取得,应该没什么不妥吧? |
|
返回顶楼 | |
发表时间:2006-02-28
robbin 写道 反对这种做法,我一次web request过程中,可能牵涉n个Service的m个DAO调用,可能涉及x种domain对象的分页处理,你要在ThreadLocal里面分别传递好多个分页参数,而且还必须清楚的区分哪个参数是哪个DAO用到的。这种大量隐式契约的编程味道太坏了。
n个Service、m个dao、x个domain对象,的确复杂,不适合这种方法。不过对于一般的应用,一个页面也就一个分页查询操作,稍微地隐式一点的确是可以简化dao无关层的接口。 当然,我现在的做法也是传递这个对象到各个层,最终到dao. |
|
返回顶楼 | |
发表时间:2006-02-28
hongliang 写道 你的意思是不支持楼主的ThreadLocal的做法? 给你看我现在的BaseDao类,其中大概有这样几个方法: public interface BaseDao { //... List findListByClass(Class clazz, QueryMeta qm);; List findListByHql(String hql, Object value, QueryMeta qm);; List findListByHql(String hql, Object[] values, QueryMeta qm);; List findListByHql(String hql, QueryMeta qm);; //... } 每个方法里都要套个QueryMeta参数,如果用楼主的方法,代码就可以变成: public interface BaseDao { //... List findListByClass(Class clazz);; List findListByHql(String hql, Object value);; List findListByHql(String hql, Object[] values);; List findListByHql(String hql);; //... } 就简洁许多叻,QueryMeta对象由实现类在实现代码中用ThreadLocal取得,应该没什么不妥吧? 如下,岂不是更“简洁”? public interface BaseDao { List find(Query query);; } 我只推荐在纯粹的查询中使用这样的方式。 业务处理中的查询就没必要了,因为不需要分页,参数也稳定,显式的提供各个参数,接口含义明确。 public interface CustomerDao { Customer find(String code);; } 另外在DAO接口中传递HQL,也值得商榷。那毕竟是数据层专用的语言啊! |
|
返回顶楼 | |
发表时间:2006-02-28
buaawhl 写道 hongliang 写道 楼主的意思应该是每次调用action,页面都会把分页相关的参数传进来,用ThreadLocal保存后,就不需要在action层和service层做处理,由dao层直接拿到ThreadLocal保存的分页信息就可以叻。楼主解决的不是跨页面、多次请求的问题,而是处理一个分页请求时的参数传递问题。
没错。是我没有理解到位。thanks hongliang. ThreadLocal 转手 总觉得有点别扭 |
|
返回顶楼 | |
发表时间:2006-02-28
我的想法是,分页是一个页面显示的需求,用户不管你后面是一次查出所有数据还是只查出当前页的数据。对于service层中的一个查询操作,我认为他的含义就是查询满足条件的记录。如果性能允许的情况下,最简单的就是不管三七二十一返回所有查询结果,然后在显示层作分页,一页一页的显示给用户看。这样service和dao都不要管分页。 但是实际情况下,不能不考虑性能问题,所以需要在查询数据库时获得分页参数,当前页不显示的就不去查询。我觉得这是一个实现方式上的选择(查出所有,还是只查出用户能够看到的), 不应该出现在接口上,特别是service的接口上。
比如一个service方法 List findUser(Date birthday , Pagination p ), User 和 birthday都是业务逻辑中的概念,而Pagination是系统实现中的概念,不应该出现在service中,在这个接口中出现Pagination只是因为dao需要这个对象,所以要从service传下去。 |
|
返回顶楼 | |
发表时间:2006-02-28
Prentice 写道 我的想法是,分页是一个页面显示的需求,用户不管你后面是一次查出所有数据还是只查出当前页的数据。对于service层中的一个查询操作,我认为他的含义就是查询满足条件的记录。如果性能允许的情况下,最简单的就是不管三七二十一返回所有查询结果,然后在显示层作分页,一页一页的显示给用户看。这样service和dao都不要管分页。 但是实际情况下,不能不考虑性能问题,所以需要在查询数据库时获得分页参数,当前页不显示的就不去查询。我觉得这是一个实现方式上的选择(查出所有,还是只查出用户能够看到的), 不应该出现在接口上,特别是service的接口上。
比如一个service方法 List findUser(Date birthday , Pagination p ), User 和 birthday都是业务逻辑中的概念,而Pagination是系统实现中的概念,不应该出现在service中,在这个接口中出现Pagination只是因为dao需要这个对象,所以要从service传下去。 如果你认为findUser是业务逻辑的概念的话,那么Pagination也是业务逻辑概念。因为出现findUser方法,也只是dao需要find。 |
|
返回顶楼 | |
发表时间:2006-02-28
partech 写道 如下,岂不是更“简洁”? public interface BaseDao { List find(Query query);; } 我只推荐在纯粹的查询中使用这样的方式。 业务处理中的查询就没必要了,因为不需要分页,参数也稳定,显式的提供各个参数,接口含义明确。 public interface CustomerDao { Customer find(String code);; } 另外在DAO接口中传递HQL,也值得商榷。那毕竟是数据层专用的语言啊! 我没表达清楚。BaseDao实际上是一个服务于其它DAO接口的底层接口,该接口的实现类不被service层调用,而是一个抽象类,被它的子类调用。 例如, public class UserDaoImpl extends BaseDaoImpl implements UserDao { public List searchUser(String name); { return findListByHql("from User a where a.username like ?", name, QueryMeta.DEFAULT_QUERY_META);; } } 所以HQL不是从service传出来的,它还在DAO层,没有破坏层次架构。当然叻,如果希望从接口上严格避免HQL从service层传入,只要让UserDao接口不继承BaseDao接口即可。 |
|
返回顶楼 | |
发表时间:2006-02-28
引用 比如一个service方法 List findUser(Date birthday , Pagination p ), User 和 birthday都是业务逻辑中的概念,而Pagination是系统实现中的概念,不应该出现在service中,在这个接口中出现 Pagination只是因为dao需要这个对象,所以要从service传下去。
看来你没进过厨房帮手,老妈让我拿两根葱给她,我就拿两根. 要是按你的理论,我就应该把所有的葱都给她,然后告诉她,你是service,我是dao. |
|
返回顶楼 | |