如何在SSM项目中用Mybatis实现分页功能

首先你要想在SSM项目中实现分页功能

  1. 你需要在DAO层先去写两个功能接口
  2. 第一个就是查询你要实现分页的列表(但是这里需要传进来的参数int rowIndex 这个是从第几行开始,,int totalPage 这个是返回多少行数据),因为你在写接口相对应的SQL的xml的映射文件的时候中的SQL语句有这个LIMIT #{rowIndex},#{totalPage };
 * 这里使用到了一个SELECT  * FROM category LIMIT 1,3(1表示开始查询的位置从0开始  (rowIndex),3表示要查询多少条数据 (totalPage ))
        *   页数          每页显示的数据         查询的起始位置
        *   1               10                      0
        *   2                10                     10
        *   3               10                      20
        *   规律就是(当前的的页面-1)*每页固定显示的数据 = 每次查询的起始位置
        *   (currentPage-1)*currentCount = 起始位置(rowIndex )
  /*也是为了根据总共数据的总数除以 当前显示的总页数,来得到一共的页码数
这里用到了一个math函数的一个方法,就是只要这个数是小数,就要让这个数往上加一,如1.2  就是2  0.8  就是1
        *   总数   每页显示的数目   总页数
        *   9           10        0.9      1
        *   14          10        1.4      2
        */
        //要保证ceil跟的是一个double类型
        //这个表示最后一共需要分多少页
        int  totalPage = (int) Math.ceil(1.0*totalCount / currentCount);
  1. 第二个是你要查询的数据一共有多少条数据,这个只是为了辅助第一个SQL需要用到的条件,因为你要实现分页的时候,你就得知道你一共有多少条数据,

根据上面的分析然后去写对应的SQL语句

这个是分页列表的方法,也就是上面第二步的那个方法

 List<Shop> queryShopList(@Param("shopCondition")Shop shopCondition,
                             @Param("rowIndex") int rowIndex,
                             @Param("pageSize") int pageSize);

这个是对应的SQL语句

 <select id="queryShopList" resultMap="shopMap">
    SELECT
    s.shop_id,
    s.owner_id,
    a.area_id,
    a.area_name,
    sc. shop_category_id,
    sc.shop_category_name,
    s.shop_name,
    s.shop_desc,
    s.shop_addr,
    s.phone,
    s.shop_img,
   s. priority,
    s.create_time,
   s. last_edit_time,
    s.  enable_status,
  s. advice
    FROM
        tb_shop s ,
        tb_area a,
        tb_shop_category sc
        <where>
           <!-- <if test="shopCondition.shopId!=null">
                and s.shop_id = #{shopCondition.shopId}
            </if>-->
            <if test="shopCondition.shopCategory!=null
                 and shopCondition.shopCategory.shopCategoryId!=null">
                and sc.shop_category_id =
                #{shopCondition.shopCategory.shopCategoryId}
            </if>
            <if test="shopCondition.area!=null
                 and shopCondition.area.areaId!=null">
                and s.area_id =
                #{shopCondition.area.areaId}
            </if>

            <!-- 写like语句的时候 一般都会写成 like '% %' 在mybatis里面写就是应该是 like '%${name} %' 而不是
                '%#{name} %' ${name} 是不带单引号的,而#{name} 是带单引号的 -->
            <if test="shopCondition.shopName!=null">
                and s.shop_name like '%${shopCondition.shopName}%'
            </if>
            <if test="shopCondition.enableStatus!=null">
                and s.enable_status = #{shopCondition.enableStatus}
            </if>
            <if test="shopCondition.personInfo!=null and shopCondition.personInfo.userId!=null">
                and s.owner_id =#{shopCondition.personInfo.userId}
            </if>
            AND
            s.area_id=a.area_id
            AND
            s.shop_category_id=sc.shop_category_id
        </where>
        ORDER BY
        s.priority DESC
        LIMIT #{rowIndex},#{pageSize};
    </select>

这个是查询你需要的全部的数据

 int queryShopCount(@Param("shopCondition") Shop shopCondition);

这个是对应的SQL语句

<!--这个是对分页所需要的查询一共能查询到多少条数据来进行分页-->
    <select id="queryShopCount" resultType="java.lang.Integer">
        SELECT
        count(1)
        FROM
        tb_shop s,
        tb_area a,
        tb_shop_category sc
        <where>
            <!-- <if test="shopCondition.shopId!=null">
                 and s.shop_id = #{shopCondition.shopId}
             </if>-->
            <if test="shopCondition.shopCategory!=null
                 and shopCondition.shopCategory.shopCategoryId!=null">
                and sc.shop_category_id =
                #{shopCondition.shopCategory.shopCategoryId}
            </if>
            <if test="shopCondition.area!=null
                 and shopCondition.area.areaId!=null">
                and s.area_id =
                #{shopCondition.area.areaId}
            </if>

            <!-- 写like语句的时候 一般都会写成 like '% %' 在mybatis里面写就是应该是 like '%${name} %' 而不是
                '%#{name} %' ${name} 是不带单引号的,而#{name} 是带单引号的 -->
            <if test="shopCondition.shopName!=null">
                and s.shop_name like '%${shopCondition.shopName}%'
            </if>
            <if test="shopCondition.enableStatus!=null">
                and s.enable_status = #{shopCondition.enableStatus}
            </if>
            <if test="shopCondition.personInfo!=null and shopCondition.personInfo.userId!=null">
                and s.owner_id =#{shopCondition.personInfo.userId}
            </if>
            AND
            s.area_id=a.area_id
            AND
            s.shop_category_id=sc.shop_category_id
        </where>

然后去写Service层的方法

  1. 首先你先要想到需要把service的传进来的两个参数 int pageIndex, int pageSize(pageSize就是一页分页数量是多少,pageIndex是页面的下标第几页)给转成你DAO层需要写SQL语句的时候LIMIT的时候需要用到的#{rowIndex},#{totalPage };
  2. 这个时候你可以自己定义一个工具类去把service层的pageSize和pageSize转换成为rowIndex和totalPage 《这里是需要通过一些数学计算加规律的》

通过这个工具类就可以了规律请看上面的

public class PageCalculator {

    public static int calculatePageCount(int totalCount, int pageSize) {
        int idealPage = totalCount / pageSize;
        int totalPage = (totalCount % pageSize == 0) ? idealPage
                : (idealPage + 1);
        return totalPage;
    }

    //这个是根据传进来的页面的下标和每一个页面的大小,来返回的是每次查询的起始位置
    //这个计算返回的是rowIndex
    public static int calculateRowIndex(int pageIndex, int pageSize) {
        return (pageIndex > 0) ? (pageIndex - 1) * pageSize : 0;
    }
}

然后去实现serviceImpl的方法

@Override
    public ShopExecution getShopList(Shop shopCondition, int pageIndex, int pageSize) {
        //这一步就是把pageIndex页面的下标第几页,pageSize就是一页分页数量是多少,
        // 有这两个值就可以转化为分页所需要的参数rowIndex这个就是每次查询的其实位置
        int rowIndex = PageCalculator.calculateRowIndex(pageIndex,pageSize);
        //然后利用这三参数就可以
        List<Shop> shopList = shopDao.queryShopList(shopCondition, rowIndex, pageSize);
        //这步是获取全部shop的列表总数
        int count = shopDao.queryShopCount(shopCondition);
        //这里需要定以一个空的ShopExecution来接受数据
        ShopExecution se = new ShopExecution();
        //判断有没有查询到所需要的店铺数据,如果不为空的话,就把shopList和查询到的全部shop信息的总数设置进去
        if (shopList!=null){
            se.setShopList(shopList);
            se.setCount(count);
        }
        else {
            se.setState(ShopStateEnum.INNER_ERROR.getState());
        }
        //无论是否成功,都会把这个方法返回的ShopExecution给返回回去
        return se;
    }

最后就是去Controller层去写你的业务需要的逻辑

顺便补充一下我写controller的思路,跟这个次的分页无关的
如何把从后台拿到的数据返回给得到shopList的信息的前台的思路
* 1.先定义一个返回数据的模型(可以是model、modelMap、modelAndView)
* 2.到这你先知道你service层需要什么参数,接下来你要一直围绕着service层需要穿进去的参数来考虑问题。然后准备需要的参数
* 3.因为service层需要的是一个shop实体类,而且实体类中还需要把另外一个实体类PersonInfo作为shop实体的属性给set进去* //TODO 下面这步其实不太理解
* 4.然后你还需要为这个PersonInfo实体类set进去一个ID,然后连同这个实体一块把这个实体给set进request的session域中

@RequestMapping(value = "/getshoplist",method = RequestMethod.GET)
    @ResponseBody
    private Map<String,Object>getShopList(HttpServletRequest request){

        Map<String ,Object> modelMap = new HashMap<String, Object>();
        //通过session来获取用户的信息
        /*PersonInfo user = (PersonInfo) request.getSession().getAttribute("user");*/
        PersonInfo user = new PersonInfo();
        //因为没有登录,需要为用户设置一个默认值
         user.setUserId(8);
         request.getSession().setAttribute("user",user);
         int employeeId = user.getUserId();
         List<Shop> shopList = new ArrayList<Shop>();
         try {
            Shop shopCondition = new Shop();
//TODO 这里有问题,本来视频上是这样写的,但是没有setOwner这个方法,其实这里的owner就是PersonInfo实体对象
            shopCondition.setPersonInfo(user);
            ShopExecution se= shopService.getShopList(shopCondition,0,100);
            modelMap.put("shopList",se.getShopList());
            modelMap.put("success",true);
            modelMap.put("user",user);
         }catch (Exception e){
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
         }
         return modelMap;
    }

猜你喜欢

转载自blog.csdn.net/qq_36520235/article/details/80383610