Java使用MyBatis框架分页的5种方式
本文为大家分享了java使用mybatis框架分页的五种方式,供大家参考,具体内容如下
初始准备
1.创建分页对象类,方便模块间传值
//pageinfo.java import lombok.data; @data public class pageinfo { private int pageno; private int pagesize; }
2.定义dao层接口
import org.apache.ibatis.session.rowbounds; import org.springframework.stereotype.repository; import java.util.list; @repository public interface usermapper { user selectbyuser(user user); list<user> selectall(); list<user> selectbypageinfo(pageinfo info); list<user> selectbyinterceptor(pageinfo info); list<user> selectbyrowbounds(rowbounds rowbounds); }
3.mapper中定义结果集合baseresult
<resultmap id="baseresult" type="cn.edu.yau.pojo.user"> <id property="id" column="id" jdbctype="integer"></id> <result property="username" column="username" jdbctype="varchar"></result> <result property="password" column="password" jdbctype="varchar"></result> </resultmap>
一、原始切分:最原始方法,不建议使用
1.mapper代码:查询所有数据
<select id="selectall" resultmap="baseresult"> select * from tb_user </select>
2.业务层代码:利用list的sublist()方法对数据进行切片
public list<user> findbyall(pageinfo info) { list<user> users = usermapper.selectall(); return users.sublist(info.getpageno(), info.getpagesize()); }
3.控制层代码
@requestmapping(value = "/userlist_1", method = requestmethod.get) @responsebody public result finduserbysublist(pageinfo info) { list<user> users = userservice.findbyall(info); if(users.size() == 0) { return resultgenerator.genfailresult("未查找到用户"); } return resultgenerator.gensuccessresult(users); }
二、limit关键字
1.mapper代码:利用limit关键字实现分页
<select id="selectbypageinfo" resultmap="baseresult"> select * from tb_user limit #{pageno}, #{pagesize} </select>
2.业务层直接调用
public list<user> findbypageinfo(pageinfo info) { return usermapper.selectbypageinfo(info); }
3.控制层直接调用
三、rowbounds实现分页
1.在dao层定义好所要传输的分页信息,类型为rowbounds
2.mapper层:查询所有数据
3.业务层:将pageinfo信息封装成rowbounds,调用dao层方法
public list<user> findbyrowbounds(pageinfo info) { return usermapper.selectbyrowbounds(new rowbounds(info.getpageno(), info.getpagesize())); }
4.控制层直接调用
四、mybatis的interceptor实现:实现复杂,需要明白mybatis的实现
1.创建interceptor
import org.apache.ibatis.executor.parameter.parameterhandler; import org.apache.ibatis.executor.statement.statementhandler; import org.apache.ibatis.mapping.mappedstatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.metaobject; import org.apache.ibatis.reflection.systemmetaobject; import java.sql.connection; import java.util.properties; /** * 利用mybatis拦截器进行分页 * * @intercepts 说明是一个拦截器 * @signature 拦截器的签名 * type 拦截的类型 四大对象之一( executor,resultsethandler,parameterhandler,statementhandler) * method 拦截的方法 * args 参数,高版本需要加个integer.class参数,不然会报错 * */ @intercepts({@signature(type = statementhandler.class, method = "prepare", args = {connection.class, integer.class})}) public class definedpageinterceptor implements interceptor { @override public object intercept(invocation invocation) throws throwable { //获取statementhandler,默认的是routingstatementhandler statementhandler statementhandler = (statementhandler) invocation.gettarget(); //获取statementhandler的包装类 metaobject metaobject = systemmetaobject.forobject(statementhandler); //分隔代理对象 while (metaobject.hasgetter("h")) { object obj = metaobject.getvalue("h"); metaobject = systemmetaobject.forobject(obj); } while (metaobject.hasgetter("target")) { object obj = metaobject.getvalue("target"); metaobject = systemmetaobject.forobject(obj); } //获取查看接口映射的相关信息 mappedstatement mappedstatement = (mappedstatement) metaobject.getvalue("delegate.mappedstatement"); string mapid = mappedstatement.getid(); //拦截以byinterceptor结尾的请求,统一实现分页 if (mapid.matches(".+byinterceptor$")) { system.out.println("log:已触发分页拦截器"); //获取进行数据库操作时管理参数的handler parameterhandler parameterhandler = (parameterhandler) metaobject.getvalue("delegate.parameterhandler"); //获取请求时的参数 pageinfo info = (pageinfo) parameterhandler.getparameterobject(); //获取原始sql语句 string originalsql = (string) metaobject.getvalue("delegate.boundsql.sql"); //构建分页功能的sql语句 string sql = originalsql.trim() + " limit " + info.getpageno() + ", " + info.getpagesize(); metaobject.setvalue("delegate.boundsql.sql", sql); } //调用原对象方法,进入责任链下一级 return invocation.proceed(); } @override public object plugin(object target) { //生成object对象的动态代理对象 return plugin.wrap(target, this); } @override public void setproperties(properties properties) { //如果分页每页数量是统一的,可以在这里进行统一配置,也就无需再传入pageinfo信息了 } }
2.将interceptor添加至mybatisconfig中,这里采用javaconfig的方式
@bean public sqlsessionfactorybean sqlsession() { sqlsessionfactorybean sqlsession = new sqlsessionfactorybean(); sqlsession.setdatasource(datasource()); try { resource[] resources = new pathmatchingresourcepatternresolver().getresources("classpath:mapper/*.xml"); sqlsession.setmapperlocations(resources); //配置自定义的interceptro作为mybatis的interceptor,完成分页操作 definedpageinterceptor definedpageinterceptor = new definedpageinterceptor(); sqlsession.setplugins(new interceptor[]{definedpageinterceptor}); return sqlsession; } catch (ioexception e) { e.printstacktrace(); } return null; }
3.dao层接口方法名需要和代码中自定义的".+byinterceptor$"正则表达式相匹配,mapper的书写依然是查询所有数据
<select id="selectbyinterceptor" resultmap="baseresult"> select * from tb_user </select>
4.业务层直接调用
5.控制层直接调用
五、开源项目pagehelper实现:本质还是自己封装了个interceptor
1.引入pagehelper的jar包
<dependency> <groupid>com.github.pagehelper</groupid> <artifactid>pagehelper</artifactid> <version>5.1.10</version> </dependency>
2.配置pageinterceptor
public pageinterceptor initpageinterceptor(){ pageinterceptor pageinterceptor = new pageinterceptor(); properties properties = new properties(); //设置数据库类型 properties.setproperty("helperdialect", "mysql"); //该参数默认为false //设置为true时,会将rowbounds第一个参数offset当成pagenum页码使用 //和startpage中的pagenum效果一样 properties.setproperty("offsetaspagenum", "true"); //该参数默认为false //设置为true时,使用rowbounds分页会进行count查询 properties.setproperty("rowboundswithcount", "true"); pageinterceptor.setproperties(properties); return pageinterceptor; } @bean public sqlsessionfactorybean sqlsession() { sqlsessionfactorybean sqlsession = new sqlsessionfactorybean(); sqlsession.setdatasource(datasource()); try { resource[] resources = new pathmatchingresourcepatternresolver().getresources("classpath:mapper/*.xml"); sqlsession.setmapperlocations(resources); //配置pagehelper作为mybatis的interceptor,完成分页操作 pageinterceptor pageinterceptor = this.initpageinterceptor(); //配置自定义的interceptro作为mybatis的interceptor,完成分页操作 definedpageinterceptor definedpageinterceptor = new definedpageinterceptor(); sqlsession.setplugins(new interceptor[]{pageinterceptor, definedpageinterceptor}); return sqlsession; } catch (ioexception e) { e.printstacktrace(); } return null; }
3.mapper依然是查询所有数据
4.为dao层再封装一次方法
@repository public class pagehelperhandler { @autowired private sqlsessionfactory sqlsessionfactory; public list<user> findbypagehelper(pageinfo info) { sqlsession session = sqlsessionfactory.opensession(); pagehelper.startpage(info.getpageno(), info.getpagesize()); //写到要使用到的类名和方法名 list<user> users = session.selectlist("cn.edu.yau.mapper.usermapper.selectall"); return users; } }
6.业务层直接调用handler
7.控制层直接调用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: springMVC+jersey实现跨服务器文件上传
下一篇: python同步两个文件夹下的内容