PageHelper的简单使用

分页查询

需求:查询所有数据 方法1:采用Map传递参数查询

<select id="selectByMap" parameterType="map" resultMap="BaseResultMap">
select
        <include refid="Base_Column_List"/>
       from t_users where 1=1
        <if test="(rowsPerPage!=null) and (rowsPerPage > 0)">
           limit
            <if test="begin!=null">
               ${begin},
            </if>
           ${rowsPerPage}
        </if>
</select>
<select id="countByMap" parameterType="map" resultType="int">
       select count(id) from t_users
</select>

修改映射接口

public interface UserMapper{
 List<UserBean> selectByMap(Map<String,Object> map);
 int countByMap(Map<String,Object> map);
}

业务实现

public class UserServImpl implmenets IUserServ{
 public List<UserBean> getByPage(PageBean pages){
 List<UserBean> res=new ArrayList<>();
 Map<String,Object> map=new HashMap<>();
 UserMapper
userMapper=MyBatisSessionFactory.getMapper(UserMapper.class);
 if(pages!=null && pages.getRowsPerPage()>0){
 if(pages.getPageNum()<1)
 pages.setPageNum(1);
 if(pages.getMaxPage()<1){
 int rowsNum=userMapper.countByMap(map);
 if(rowsNum<1)
 return res;
 int maxPage=(rowsNum1+pages.getRowsPerPage())/pages.getRowsPerPage();
 pages.setRowsNum(rowsNum);
 pages.setMaxPage(maxPage);
 }
 if(pages.getPageNum()>pages.getMaxPage())
 pages.setPageNum(pages.getMaxPage());
 int begin=(pages.getPageNum()-1)*pages.getRowsPerPage();
 map.put("begin",begin);
 map.put("rowsPerPage",pages.getRowsPerPage());
 }
 res.addAll(userMapper.selectByMap(map));
 return res;
 }
}

方法2:使用MyBatis提供的RowBounds 软分页 没有自行拼接limit语句

<select id="selectAll" resultMap="BaseResultMap">
       select
        <include refid="Base_Column_List"/>
       from t_users where 1=1
</select>

需要在声明的Mapper接口中添加一个额外的参数

List<User> selectAll(RowBounds rowBounds);

注意这里的声明的方法和xml中的配置不一致,会多一个参数rowbounds

UserMapper userMapper= MybatisSessionFactory.getMapper(UserMapper.class);
List<User> userList=userMapper.selectAll(new RowBounds(0,3));//参数1为起始行
好,参数2为每页行数
for (User user : userList) {
   System.out.println(user);
}

方法3:PageHelper PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件

1、添加依赖

<dependency>
       <groupId>com.github.pagehelper</groupId>
       <artifactId>pagehelper</artifactId>
       <version>5.2.0</version>
</dependency>

2、分页插件配置

<plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"> 注意版
本的问题
            <!--配置数据库方言-->
            <property name="helpDialect" value="mysql"/>
            <!--要求进行分页参数的合理化处理-->
            <property name="reasonable" value="true"/>
        </plugin>
</plugins> 注意版本的问题

3、编码调用

UserMapper userMapper= MybatisSessionFactory.getMapper(UserMapper.class);
//设置分页相关参数,参数1为查询的页码值,参数2为每页行数
PageHelper.startPage(-200,3);
List<User> userList=userMapper.selectAll();  //紧邻的查询语句中自动添加了分页处理

4、获取分页相关数据

UserMapper userMapper= MybatisSessionFactory.getMapper(UserMapper.class);
        PageHelper.startPage(-200,3);
        List<User> userList=userMapper.selectAll();
        userList.forEach(System.out::println);
        
Page<User> pageInfo=(Page)userList;        
System.out.println("当前页码值:"+pageInfo.getPageNum());
System.out.println("最大页码值:"+pageInfo.getPages());
System.out.println("总行数:"+pageInfo.getTotal());
System.out.println("每页行数:"+pageInfo.getPageSize());

5、如何需要进行排序

//设置分页的相关参数,参数1为页码值,参数2为每页行数,参数3为排序处理,也就是order by子句
后面的内容
Page<Student> info=PageHelper.startPage(1,3,"id desc,name asc");

实现分页的原理–plugin的开发

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执 行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。 举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0, 10 使用方言和MyBatis的拦截器来实现分页 1:配置插件

<plugins>
 <plugin interceptor="com.yan.StatmentHandlerInterceptor"/>
</plugins>

2:写拦截器 Mybatis支持对Executor、StatementHandler、PameterHandler和ResultSetHandler 接口进行拦截, 也就是说会对这4种对象进行代理。所谓的PageHelper分页工具实际上就是自定义拦截器

@Intercepts({//通过注解配置拦截目标,也就是定义什么时候进行拦截处理,因为拦截接口只有
一个
 @Signature(type = StatementHandler.class, //拦截StatementHandler对象中的
方法
   method = "prepare", //拦截prepare这个方法
        args = { Connection.class, Integer.class }) })//对应方法的参数
public class StatmentHandlerInterceptor implements Interceptor {
 //具体的拦截处理逻辑
 public Object intercept(Invocation invocation) throws Throwable {
 System.out.println("intercept");
 if (invocation.getTarget() instanceof StatementHandler) {//获取拦截
目标对象的类型
 StatementHandler sh = (StatementHandler)
invocation.getTarget();//获取拦截目标对象
 BoundSql bs = sh.getBoundSql();//获取StatementHandler中包含的SQL
对象
 System.out.println(bs.getSql());
            //如果需要修改bs中所存放的SQL语句,则必须通过反向映射实现
 Class clz = bs.getClass();
 Field field = clz.getDeclaredField("sql");
 field.setAccessible(true);
 field.set(bs, bs.getSql()+"修改的地方");
 }
 return invocation.proceed(); //继续向后执行,拦截器还是责任链模式,类似过
滤器,执行过程executor--statementhandler--parameterhandler--Typehander---
preparedStatement---ResultSethandler---statementhandler---executor
 }
 public Object plugin(Object arg0) {  //用于实现将当前拦截器对象通过plugin方
式添加到MyBatis中
 System.out.println("plugin");
 return Plugin.wrap(arg0, this);
 }
    //接收在配置文件中的配置参数
    public void setProperties(Properties properties) {
        System.out.println(properties);
        /*
        <plugin interceptor="com.yan.interceptor.MyInterceptor">
            <property name="name" value="tttt"/>
        </plugin>
         */
   }
}

样例:统计SQL语句的执行时间

//具体的拦截处理逻辑
public Object intercept(Invocation invocation) throws Throwable {
    long start=System.currentTimeMillis();
    String sql=null;
    if (invocation.getTarget() instanceof StatementHandler) { //获取拦截目标
对象的类型
        StatementHandler sh = (StatementHandler)
invocation.getTarget();获取拦截目标对象
        BoundSql bs = sh.getBoundSql();//获取StatementHandler中包含的SQL对象
        sql=bs.getSql();
        //如果需要修改bs中所存放的SQL语句,则必须通过反向映射实现
     }
     Object res= invocation.proceed();  //继续向后执行
     long end=System.currentTimeMillis();
     System.out.println(sql+"执行时间为:"+(end-start)+"ms");
     return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值