Java泛型之分页

21 篇文章 0 订阅
10 篇文章 0 订阅

一、 需求描述

在JavaWeb开发中,分页是很常见的功能,在一个系统中,根据需求可能存在不同模块的分页,但是如果对每一个分页都写一个具体的类,这样做重复度太高,会造成代码冗余,因为分页处理的内容只不过是实体类型不同而已,其他的都大同小异。类型不同,自然想到Java泛型的类型参数,关于Java泛型,贴一篇不错的博客

二、具体实现

  1. 首先,根据分页的功能需要抽象出一个泛型基类PageModel,该类应至少包含如下内容:

pageNumber: 代表是第几页,用户可以点击看指定的页码
pageSize: 用户可以指定每页显示多少数据
startRow: pageNumber和pageSize都是由与系统交互的使用用户设定的,实际去数据库查询的时候应指定从哪一行开始,startRow的值可以通过pageNumber和pageSize获取到!
queryObj:一个泛型类参数,用户在分页时往往是有查询条件的,通过queryObj封装查询对象,再对应的使用MyBatis的动态sql进行查询
rows: 查询结果返回的数据集
total: 分页时显示一共有多少条记录
综上,可以得到PageModel的泛型类为:


import java.util.List;

// 将分页的pageNumber和pageSize等有关的抽象出来,让具体业务有关的继承该类,同时具体的功能要有各自独立的部分!
// 注意这里使用了泛型!
public class PageModel<T> {

    private Integer pageNumber = 1; //当前页数
    private Integer pageSize = 10;   //一页显示数量
    private Integer startRow;   //查询起始行
    private Integer total;      //总记录行数
    // 泛型的使用!
    private List<T> rows;       //查询结果返回数据
    private T queryObj;         //查询对象

    @Override
    public String toString() {
        return String.format("[pageNumber=%d, pageSize=%d]",
                pageNumber, pageSize) ;
    }

    // pageNumber有-1的操作,可能会出现负值,所以需要进行整数判断!
    public Integer getStartRow() {
        if (pageNumber != null && pageSize != null && pageNumber >= 1) {
            return (pageNumber - 1) * pageSize;
        } else {
            return 0;
        }
    }

    public Integer getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(Integer pageNumber) {
        this.pageNumber = pageNumber;
    }

    public Integer getPageSize() {
        return pageSize;
    }

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

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        this.total = total;
    }

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }

    public void setQueryObj(T queryObj) {
        this.queryObj = queryObj;
    }

    public T getQueryObj() {
        return queryObj;
    }

    public void setStartRow(Integer startRow) {
        this.startRow = startRow;
    }
}

  1. 根据业务需求设定具体的PageModel类
    一个常见的需求是管理员查看当前系统中的用户,对他们进行某些操作,这个时候就需要分页了,此时除了PageModel中的属性外,也可以加上一些该类独有的属性。
public class UserPageModel<T> extends PageModel<T>{
    private String curUserId;

    public String getCurUserId() {
        return curUserId;
    }

    public void setCurUserId(String curUserId) {
        this.curUserId = curUserId;
    }
}

Controller层:设定好查询的PageModel对象或其子类,同时设定好查询条件
用户分页的Controller层代码:

// 注意参数UserPageModel已经传入了User类参数!
@RequestMapping("listUserWithPageForJson.action")
@ResponseBody
public Map<String, Object> listUserWithPageForJson(HttpSession session, UserPageModel<User> userPageModel, User user) {
    Map<String, Object> map = new HashMap<>();
    // 封装查询条件
    String userId = (String) session.getAttribute("userId");
    user.setUserId(userId);
    userPageModel.setQueryObj(user);
    adminService.listUserWithPage(userPageModel);
    map.put("total", userPageModel.getTotal());
    map.put("rows", userPageModel.getRows());
    map.put("userAccount", user.getUserAccount());
    return map;
}

Service层:Service层是为Controller层服务的,在这里设定好查询返回的数据集对象和总的查询记录条数!
用户分页的Service层代码:

@Override
public void listUserWithPage(UserPageModel userPageModel) {
	// 设定好rows和total
	userPageModel.setRows(userDao.selectUserListWithPage(userPageModel));
	userPageModel.setTotal(userDao.selectUserCountWithPage(userPageModel));
}

Dao层:Dao层是为Service层服务的,数据库查询返回具体的内容结果
用户分页的数据库查询代码

<select id="selectUserListWithPage" parameterType="com.shaogang.model.UserPageModel" resultMap="BaseResultMap">
        select user.*, role.name, role.description from user, role
        <where>
            user.role_id = role.role_id
            <if test="queryObj.userId != null">
                AND user_id != #{queryObj.userId,jdbcType=VARCHAR}
            </if>
            <if test="queryObj.userAccount != null and queryObj.userAccount != ''">
                And user_account like concat('%', #{queryObj.userAccount,jdbcType=VARCHAR}, '%')
            </if>
        </where>
        order by register_time desc, login_time desc
        <if test="pageNumber != null and pageSize!= null">
            limit #{startRow},#{pageSize}
        </if>
  </select>

  <select id="selectUserCountWithPage" parameterType="com.shaogang.model.UserPageModel" resultType="Integer">
       select count(*) from user, role
       <where>
           user.role_id = role.role_id
           <if test="queryObj.userId != null">
               AND user_id != #{queryObj.userId,jdbcType=VARCHAR}
           </if>
           <if test="queryObj.userAccount != null and queryObj.userAccount != ''">
               And user_account like concat('%', #{queryObj.userAccount,jdbcType=VARCHAR}, '%')
           </if>
       </where>
   </select>

三、总结

泛型广泛用在设计模式和JDK容器类中,高级Java程序猿绝不是去写CRUD,而是应该思考如何写出“像诗一样优雅的"的代码!泛型的合理使用可以大大提高程序的灵活和可扩展性,减少重复、冗余代码!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值