Java开发中,通过sql来实现过滤以及分页

我们通过一个需求来引入问题。

首先,简单介绍一下需求:实现一个下图的页面,包含了过滤以及分页。数据是后台数据库获得到的。

那么关于如何实现过滤以及分页,考虑到通过前台实现或者后台实现,我们不妨来分析一下两种方法。

首先,前台实现:无非就是后台获取所有的list,传给前台暂存,然后前台按照用户的过滤或者分页,来处理list,展示给前台。

后台实现:前台要什么过滤,要第几页,我们就返回什么list。

那么在我看来,前台实现劣势有三

1. 传输问题:现在开发过程数据库中的案例数很少,十几个案例没啥问题。可是当数据库中案例数增加后,几百甚至几千条的数据同时传输,传输速率肯定有所降低,前台加载一个页面可能要很久,用户体验极差。

2. 内存占用问题:同样是 当数据量过大时,不论后台还是前台,都需要一大片空间来存储,占据大量内存。其中又有很多是暂时用不上的数据,造成资源浪费。

3. 时效性问题:我们举个例子,按照后台一次性获取所有案例给前台,而这个获取过程可能是通过外部的一个点击事件触发,如果此时有用户对案例进行了修改,那么不论是翻页还是过滤,都看不出来用户的修改。而如果每次过滤或者翻页都是即时的从后台获取,就可以保证每次过滤或者分页都是最新的内容。

当然这只是我所认为分析出来的前台实现劣势,如果有什么前台的优化方法还请指出:)

====================================================================

所以接下来我们就考虑利用后台来进行实现,那么思考一下,前台告诉我们对哪些字段进行过滤,进行怎样的分页(每页有几个案例,第几页),然后我们根据这些参数来实现过滤或者分页。

最直接的方法,还是数据库直接获取所有案例,然后按照字段筛选,按照分页条件筛选。咦?直接获取的数据又不是我全都要,这样不还是占用了很多内存。那怎么办呢,我们不妨从数据库访问过程入手,通过sql来实现过滤分页呢。

那么就有了下面的方法: 关于过滤,前台传给我们一个包含过滤字段以及过滤字段关键字的json就可以啦,如下的<if></if>,判断对应字段是否存在,如果存在,那就利用like进行过滤。(代码使用Mybatis作为持久层框架,所以代码直接贴啦)

<select id="getCaseView" resultType="com.common.bean.CaseInfo">
		select id, type, title, create_user as user, status
		    from t_tbl_case_info where
		<choose>
			<when test="tableBaseRequest.filter.viewType==0">
				status = '3'
			</when>
			<when test="tableBaseRequest.filter.viewType==1">
				status != '4' and create_user = #{curUser}
			</when>
		</choose>
		<if test="tableBaseRequest.filter.title!=null">
			and title like concat('%',#{tableBaseRequest.filter.title},'%')
		</if>
		<if test="tableBaseRequest.filter.type!=null">
			and type in 
			<foreach collection="tableBaseRequest.filter.type" item="item"
				open="(" separator="," close=")">
				#{item}
			</foreach>
		</if>
		<if test="tableBaseRequest.filter.user!=null">
			and user like concat('%',#{tableBaseRequest.filter.user},'%')
		</if>
		order by create_time desc
		limit #{tableBaseRequest.offset}, #{tableBaseRequest.pageSize}
	</select>

关于分页,可以看到实现在sql的最后,limit #{tableBaseRequest.offset}, #{tableBaseRequest.pageSize},使用limit即可,在一个经过计算的偏移量offset之后,选择 一页展示的数据,offset可以前台计算传到后台,也可以前台只传页码以及一页中案例数量 后台来计算。

tableBaseRequest.setOffset((tableBaseRequest.getCurPage() - 1) * tableBaseRequest.getPageSize())

如此一来,前台实现传递过滤字段以及过滤内容、页码以及每页条数,便可以完成通过sql来在后台实现过滤以及分页

附一下前台传递的参数,一个自定义类

public class TableBaseRequest
{
    /**
     * 表格分页信息,当前是第几页
     */
    @Min(1)
    @Max(Integer.MAX_VALUE)
    private int curPage;
    
    /**
     * 表格分页信息,每页展示多少条数据
     */
    @IntPattern(regexp = ValidatorConstants.TABLE_PAGESIZE_REGEXP)
    private int pageSize;
    
    /**
     * 表格分页信息,查询数据库的偏移量
     */
    private int offset;
    
    /**
     * 过滤参数 filter:{ "text":"XXX", "select":["0", "1"], "time":{"startTime":"2018-02-01 00:00:00", "endTime":
     * "2018-02-02 23:59:59"} }
     */
    private JSONObject filter;


    /**
     * 排序列,如不为空即需要对此字段进行排序
     */
    @Length(max = 100)
    private String sortName;
    
    /**
     * 排序类型,默认desc,枚举包括:增序asc或降序desc
     */
    @Pattern(regexp = ValidatorConstants.TABLE_SORT_REGEXP)
    private String sortValue;
}

猜你喜欢

转载自blog.csdn.net/VeastLee/article/details/83443296