论坛首页 Java企业应用论坛

一种传递分页参数的方法

浏览 30767 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-02-28  
感觉这样做,接口变得晦涩,完全没有必要。
极端情况,不是啥参数都可以放到threadLocal里传递?
对于常变化的参数,象hongliang说的,传递一个通用Query对象,比较好。就算不考虑分页,这样处理也是有理由的,其他查询条件的变化通常也会比较频繁。
0 请登录后投票
   发表时间:2006-02-28  
反对这种做法,我一次web request过程中,可能牵涉n个Service的m个DAO调用,可能涉及x种domain对象的分页处理,你要在ThreadLocal里面分别传递好多个分页参数,而且还必须清楚的区分哪个参数是哪个DAO用到的。这种大量隐式契约的编程味道太坏了。

其实分页很简单,封装一个Pagination对象,所有需要传入传出的参数都封装在里面就OK了,Hibernate版我贴过代码的,用起来很方便。
0 请登录后投票
   发表时间: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取得,应该没什么不妥吧?
0 请登录后投票
   发表时间:2006-02-28  
robbin 写道
反对这种做法,我一次web request过程中,可能牵涉n个Service的m个DAO调用,可能涉及x种domain对象的分页处理,你要在ThreadLocal里面分别传递好多个分页参数,而且还必须清楚的区分哪个参数是哪个DAO用到的。这种大量隐式契约的编程味道太坏了。


n个Service、m个dao、x个domain对象,的确复杂,不适合这种方法。不过对于一般的应用,一个页面也就一个分页查询操作,稍微地隐式一点的确是可以简化dao无关层的接口。

当然,我现在的做法也是传递这个对象到各个层,最终到dao.
0 请登录后投票
   发表时间: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,也值得商榷。那毕竟是数据层专用的语言啊!
0 请登录后投票
   发表时间:2006-02-28  
buaawhl 写道
hongliang 写道
楼主的意思应该是每次调用action,页面都会把分页相关的参数传进来,用ThreadLocal保存后,就不需要在action层和service层做处理,由dao层直接拿到ThreadLocal保存的分页信息就可以叻。楼主解决的不是跨页面、多次请求的问题,而是处理一个分页请求时的参数传递问题。


没错。是我没有理解到位。thanks hongliang.


ThreadLocal 转手 总觉得有点别扭
0 请登录后投票
   发表时间:2006-02-28  
我的想法是,分页是一个页面显示的需求,用户不管你后面是一次查出所有数据还是只查出当前页的数据。对于service层中的一个查询操作,我认为他的含义就是查询满足条件的记录。如果性能允许的情况下,最简单的就是不管三七二十一返回所有查询结果,然后在显示层作分页,一页一页的显示给用户看。这样service和dao都不要管分页。 但是实际情况下,不能不考虑性能问题,所以需要在查询数据库时获得分页参数,当前页不显示的就不去查询。我觉得这是一个实现方式上的选择(查出所有,还是只查出用户能够看到的), 不应该出现在接口上,特别是service的接口上。
比如一个service方法  List findUser(Date birthday , Pagination p ), User 和 birthday都是业务逻辑中的概念,而Pagination是系统实现中的概念,不应该出现在service中,在这个接口中出现Pagination只是因为dao需要这个对象,所以要从service传下去。
0 请登录后投票
   发表时间: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。
0 请登录后投票
   发表时间: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接口即可。
0 请登录后投票
   发表时间:2006-02-28  
引用
比如一个service方法 List findUser(Date birthday , Pagination p ), User 和 birthday都是业务逻辑中的概念,而Pagination是系统实现中的概念,不应该出现在service中,在这个接口中出现 Pagination只是因为dao需要这个对象,所以要从service传下去。

看来你没进过厨房帮手,老妈让我拿两根葱给她,我就拿两根.
要是按你的理论,我就应该把所有的葱都给她,然后告诉她,你是service,我是dao.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics