当前位置: 首页 > 面试题库 >

如何实现一般分页

程俊力
2023-03-14
问题内容

我不是在寻找Hibernate / JPA / JDBC实现,而是在寻求一种通用的设计模式。

谷歌搜索“分页”为我提供了大量信息,许多有趣的文章解释了如何在UI上实现分页以及各种或多或少都执行相同操作的实现。

简单的bean:

public class Person{
     private String personName;
     private int age;
     // ...
}

一个简单的DAO界面:

public interface PersonDAO{
   Set<Person> getAllPersons(int start, int limit,String orderBy);
   Set<Person> findPersonsByName(String name, int start, int limit,String orderBy);
}

和hibernate实现

   @Repository
   public class PersonDAOImpl implements PersonDAO {

        @Autowired(required = true)
    private SessionFactory sessionFactory;

        public Set<Person> getAllPersons(int start, int limit, String orderBy){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.setFirstResult(start);
                crit.setMaxResults(limit);
                crit.addOrder(Order.asc("personName"));
                return new LinkedHashSet<Person>(crit.list());
        }


        public Set<Person> findPersonsByName(String name, int start, int limit, String orderBy){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.add(Restrictions.eq("name", name));
                crit.setFirstResult(start);
                crit.setMaxResults(limit);
                crit.addOrder(Order.asc(orderBy));
                return new LinkedHashSet<Person>(crit.list());
         }

现在,我在考虑是否必须在所有接口中都包含相似的参数,那么这里确实有问题。我可以将请求包装在请求bean对象中,然后将此bean传递给方法,就像这样

public class PersonRequest{
   private int start;
   private int limit;
   private String orderBy;
   private String name;
   // ...
}

然后

public interface PersonDAO{
   Set<Person> getAllPersons(PersonRequest request);
   Set<Person> findPersonsByName(PersonRequest request);
}

但是出于某种原因,这似乎也不自然。然后我在想Java中的varargs

public interface PersonDAO{
   Set<Person> getAllPersons(Object... params);
   Set<Person> findPersonsByName(String name,Object... params);
}


   @Repository
   public class PersonDAOImpl implements PersonDAO {

        @Autowired(required = true)
    private SessionFactory sessionFactory;



        public Set<Person> getAllPersons(Object... params){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.setFirstResult((Integer)params[0]);
                crit.setMaxResults((Integer)params[1]);
                crit.addOrder(Order.asc("personName"));
                return new LinkedHashSet<Person>(crit.list());
        }


        public Set<Person> findPersonsByName(String name, Object... params){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.add(Restrictions.eq("name", name));
                crit.setFirstResult((Integer)params[0]);
                crit.setMaxResults((Integer)params[1]);
                crit.addOrder(Order.asc((String)params[2]));
                return new LinkedHashSet<Person>(crit.list());
         }

这似乎也有些脆弱,出于某种原因,我一直认为桥接模式可能会有所帮助,但仍然遥不可及。

知道您将如何处理吗?


问题答案:

如果您是我,我将不返回结果(Set)本身,而是返回封装结果检索的内容。某种ResultBuilder。看:

public interface ResultBuilder<T> {

    ResultBuilder<T> withOffset(int offset);

    ResultBuilder<T> withLimit(int limit);

    ResultBuilder<T> orderedBy(String property);

    List<T> result();
}

然后更改DAO方法签名:

ResultBuilder<Person> findPersonsByName(String name);

这样,您就可以从查找族方法中排除与业务无关的参数。如果您不想让客户指定此参数,则不要让他指定。

只是要清楚:

public final class HibernateGenericResultBuilder<T> implements ResultBuilder<T> {

    private final Criteria criteria;

    public HibernateGenericResultBuilder(Criteria criteria) {
        this.criteria = criteria;
    }

    @Override public ResultBuilder<T> withOffset(int offset) {
        criteria.setFirstResult(offset);
        return this;
    }

    @Override public ResultBuilder<T> withLimit(int limit) {
        criteria.setMaxResults(limit);
        return this;
    }

    @Override public ResultBuilder<T> orderedBy(String property) {
        criteria.addOrder(Order.asc(property));
        return this;
    }

    @Override public List<T> result() {
        return new LinkedHashSet<T>(criteria.list());
    }
}


 类似资料:
  • The easiest way to internationalize PHP software is by using array files and using those strings in templates, such as <h1><?=$TRANS['title_about_page']?></h1>. This is, however, hardly a recommended

  • 绑定于 FuelPHP 的应用程序分析器是基于 PHP Quick Profiler。 分析是什幺? 分析器提供分析及除错相关资讯而不须添加大量方案的开销到程式码。 你只需要切换一个配置设定为 true,你就有一个自动化工具的入口, 以帮助建立一个更快更一致的审查经验。因为任何人都可以使用它, 分析器也在审查前给你一个程式码定位的想法。 分析器提供一个页籤介面,你可以在其中找到以下资讯: Cons

  • 表现控件 表现控件是什幺? A Presenter is a class that contains the logic that is needed to generate your view (or views). When the controller is done with your user input and is done with whatever actions it need

  • 问题内容: 我是ReactJS的新手,正在其中创建一个简单的TODO应用程序。实际上,这是一个非常基本的应用程序,没有数据库连接,任务存储在数组中。我现在想添加分页功能,并添加了“编辑和删除”功能。如何实施?任何帮助将不胜感激。谢谢…!! 问题答案: 我最近在纯React JS中实现了分页。这是一个工作示例:http : //codepen.io/PiotrBerebecki/pen/pEYPbY

  • 本文向大家介绍请说明一下Hibernate如何实现分页查询?相关面试题,主要包含被问及请说明一下Hibernate如何实现分页查询?时的应答技巧和注意事项,需要的朋友参考一下 考察点:框架 参考回答: 通过Hibernate实现分页查询,开发人员只需要提供HQL语句(调用Session的createQuery()方法)或查询条件(调用Session的createCriteria()方法)、设置查询

  • 前言 我们都知道当单库系统遇到性能瓶颈时,读写分离是首要优化手段之一。因为绝大多数系统读的比例远高于写的比例,并且大量耗时的读操作容易引起锁表导致无发写入数据,这时读写分离就更加重要了。 EF Core如何通过代码实现读写分离,我们可以搜索到很多案例。总结起来一种方法是注册一个DbContextFactory,读操作注入ReadDcontext,写操作注入WriteDbcontext;另外一种是动