一、SSH实现分页查询

1.1 原理分析

1.2 PageBean<T>

  • 由于不知道查出来的是什么类型,最好加个泛型
  • 每一个页面都存在以下的元素

    1. totalCount:总记录数。查询数据库得到
    2. totalPage:总页数。根据总记录数和每页显示计算得出
    3. pageSize:每页容量。前端给

      • 如果前端没给,需要设定默认值
    4. currentPage:当前页面。前端给

      • 如果前端没给,需要设定默认值
    5. list:页面内容。查询数据库得到
  • <font color="red">注意点:总页数的计算方式</font>

    • this.totalPage = (this.totalCount + this.pageSize - 1) / this.pageSize;
package com.ruki.crm.util;

import java.util.List;

import com.ruki.crm.bean.Customer;

public class PageBean<T> {
    private int pageSize;//前端给
    private int currentPage;//前端给
    private int totalCount;//数据库查出来
    private int totalPage;//计算出来
    private List<T> list;//查出来后注入
    public PageBean(int pageSize, int currentPage, int totalCount) {
        super();
        this.pageSize = pageSize;
        //如果前端没给,需要默认值
        if(pageSize == 0) {
            this.pageSize = 3;//默认每页显示条数
        }
        this.currentPage = currentPage;
        //如果前端没给,需要默认值
        if(currentPage == 0) {
            this.currentPage = 1;// 默认当前页数1
        }
        this.totalCount = totalCount;
        this.totalPage = (this.totalCount + this.pageSize - 1) / this.pageSize;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public int getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }
    public int getTotalCount() {
        return totalCount;
    }
    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }
    public int getTotalPage() {
        return totalPage;
    }
    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }
    public List<T> getList() {
        return list;
    }
    public void setList(List<T> list) {
        this.list = list;
    }
}

1.3 CustomerAction

  1. 设定模拟查询离线查询条件:DetachedCriteria
  2. 在搜索框汇总输入的查询条件,会以对象的形式传入,因此需要使用模型驱动,重写getModel()方法,以及对象初始化不要忘记

    • getModel()
    • private Customer customer = new Customer();
package com.ruki.crm.web.action;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.ruki.crm.bean.Customer;
import com.ruki.crm.service.CustomerService;
import com.ruki.crm.util.PageBean;

public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{
    
    private CustomerService customerService;
    //筛选条件也会封装成对象,由模型驱动将对象传入
    private Customer customer = new Customer();
    //属性驱动,将前端的当前页面和每页容量传入
    private int currentPage;
    private int pageSize;
    
    public String list() {
        /*
         * List<Customer> customerList = customerService.listAllCustomer();
         * ActionContext.getContext().getSession().put("customerList", customerList);
         */
        
        //1. 接收请求,查询条件 cust_name
        //当前页数、每页显示条数
        //2. 封装对象,装配条件
        DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
        if(customer.getCust_name() != null) {
            dc.add(Restrictions.like("cust_name", "%" + customer.getCust_name()+"%"));
        }
        
        //3. 调用service
        PageBean<Customer> pageBean = customerService.findPageBean(dc, currentPage, pageSize);
        System.out.println(pageBean);
        //4. 将pageBean存入域中,指派JSP显示
        ActionContext.getContext().put("pageBean", pageBean);
        return "list";
    }
    
    public String add() {
        customerService.addCustomer(customer);
        System.out.println(customer);
        return "addSuccess";
    }
    
    @Override
    public Customer getModel() {
        return customer;
    }

    public CustomerService getCustomerService() {
        return customerService;
    }
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
}

1.4 CustomerServiceImpl

  • 主要是装配pageBean,它需要什么就查什么
    @Override
    public PageBean<Customer> findPageBean(DetachedCriteria dc, int currentPage, int pageSize) {
        //1. 查询所有记录条数
        int totalCount = customerDao.getTotalCount(dc);
        
        //2. 创建PageBean对象
        //pageSize前端给
        //currentPage前端给
        //totalCount数据库查询
        PageBean<Customer> pb = new PageBean<Customer>(pageSize, currentPage, totalCount);
        
        //3. 查询客户列表,该页需要的数据,条件、页大小、当前页
        List<Customer> list = customerDao.getList(dc, pb.getCurrentPage(), pb.getPageSize());
        System.out.println(list.toString());
        //4. 给PageBean注入list
        pb.setList(list);
        
        //5. 返回完整的PageBean
        return pb;
    }

1.5 CustomerDaoImpl(BaseDaoImpl)实现

  • 查询总记录的离线条件需要注入组函数

    • dc.setProjection(Projections.count("cust_id"));
  • 返回结果前,也要记得将组函数清除,不然其他查询也会出现组函数条件,引用类型传参传的是引用,对象是相同的对象。

    • dc.setProjection(null);
  • 分页条件:计算当前页第一条数据的小算法

    • int firstResult = (currentPage - 1)*pageSize;
    • List<T> list = (List<T>) getHibernateTemplate().findByCriteria(dc, firstResult, pageSize);
package com.ruki.crm.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import com.ruki.crm.bean.Customer;
import com.ruki.crm.dao.BaseDao;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
    private Class clazz;
    
    public BaseDaoImpl() {
        // this指当前对象,而在实际调用中,this可以表示xxDaoImpl
        // 获得父类型中泛型参数类型
        ParameterizedType types = (ParameterizedType) this.getClass().getGenericSuperclass();
        //获得实际调用中真正的泛型对应的类型
        Type[] ts = types.getActualTypeArguments();
        clazz = ts[0].getClass();
    }

    @Override
    public void add(T t) {
        getHibernateTemplate().saveOrUpdate(t);;        
    }

    @Override
    public int getTotalCount(DetachedCriteria dc) {
        //1. 添加组函数
        dc.setProjection(Projections.count("cust_id"));
        
        //2. 使用HibernateTemplate查询
        List<Long> list = (List<Long>) getHibernateTemplate().findByCriteria(dc);
        
        // 4.清除组函数 - 清除不掉,回到service,组函数依然在
        dc.setProjection(null);
        
        // 3.返回数值
        return (int)(long)list.get(0);
    }

    @Override
    public List<T> getList(DetachedCriteria dc, int currentPage, int pageSize) {
        // 1.设置分页条件 pageSize=3   2页
        int firstResult = (currentPage - 1)*pageSize;
        List<T> list = (List<T>) getHibernateTemplate().findByCriteria(dc, firstResult, pageSize);
        return list;
    }

    @Override
    public void deleteById(Serializable id) {
        T t = getById(id);
        getHibernateTemplate().delete(t);
    }

    @Override
    public void update(T t) {
        getHibernateTemplate().update(t);
        
    }

    @Override
    public T getById(Serializable id) {
        return (T) getHibernateTemplate().get(clazz, id);
    }


    public Class getClazz() {
        return clazz;
    }


    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }
}
Last modification:September 11th, 2019 at 11:47 am