环境准备
- 具体实现
什么是拦截器
SpringBoot mybatis interceptor拦截器是你在执行SQL语句之前对执行的SQL语句进行修改
分页的原理是通过拦截器在执行SQL语句执行改变SQL语句实现物理的分页 limit
为什么要这样写
<select id="getFileInfoMapPage" parameterType="java.lang.String" resultType="java.util.Map">
<![CDATA[
select rowguid,filepath from my_fileinfo where 1=1 limit #{pagenum},#{pagesize}
]]>
</select>
我想通上面的方式实现对分页,但是在执行的过程中 limit ‘50’,‘20’
在limit中总是多了一个单引号
如果我的入参是Java.lang.Integer
这样就没有办法增加搜索条件
具体实现
首先controller
@CrossOrigin("*")
@RequestMapping("/index")
public String index() {
Map<String,String> map=new HashMap<String, String>();
PageConfig config=new PageConfig();
config.setEnd(3);
config.setStart(0);
String hsql=" and istoali=1 and filesize>=30388";
config.setHsql(hsql);
List<Map<?,?>> map_file=fileInfoService.getFileInfoMapByConditionMap(config);
return "index";
}
PageConfig是我自己写的一个类:
package com.muyan.util;
public class PageConfig {
private Integer end;
private Integer start;
private String hsql;
public Integer getEnd() {
return end;
}
public void setEnd(Integer end) {
this.end = end;
}
public Integer getStart() {
return start;
}
public void setStart(Integer start) {
this.start = start;
}
public String getHsql() {
return hsql;
}
public void setHsql(String hsql) {
this.hsql = hsql;
}
}
其实实现分页的是方法:fileInfoService.getFileInfoMapByConditionMap(config)
我们来看对应的fileService中的方法:
public List<Map<?,?>> getFileInfoMapByConditionMap(PageConfig config) {
return myFileInfoMapper.getFileInfoMapPage(config);
}
FileInfoMapper
<Map<?, ?>> getFileInfoMapPage(PageConfig config);
mapper.xml
<select id="getFileInfoMapPage" parameterType="java.lang.String" resultType="java.util.Map">
<![CDATA[
select rowguid,filepath from my_fileinfo where 1=1
]]>
</select>
然后是拦截器
package com.muyan.filter;
import java.sql.Connection;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;
import com.muyan.util.PageConfig;
@Component
@Intercepts({@Signature(method = "prepare", type = StatementHandler.class,args = {Connection.class,Integer.class})})
public class PageInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
if(invocation.getTarget() instanceof StatementHandler) {
StatementHandler statementHandler=(StatementHandler)invocation.getTarget();
BoundSql boundSql=statementHandler.getBoundSql();
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,new DefaultReflectorFactory());
MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");
// 配置文件中SQL语句的ID
String id = mappedStatement.getId();
if(id.endsWith("page") || id.endsWith("Page")) {
//通过BoundSql获得原始的sql语句之后,再次使用的是BoundSql的getParameterObject()来获取配置文件中的参数,因为得到的参数是一个map,调用对象的get方法得到Page对象,得到page对象之后就可以拼接分页sql了。metaObject.setValue(“delegate.boundSql.sql”,pageSql)修改原本不可以修改的值,修改原来的属性值为新的sql。
PageConfig config=(PageConfig)boundSql.getParameterObject();
String limitsql=" limit "+config.getStart()+","+config.getEnd();
metaObject.setValue("delegate.boundSql.sql", boundSql.getSql()+config.getHsql()+limitsql);
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
上面拦截器的功能就是在执行语句执行对SQL语句进行修改,加上条件和limit
希望对你有所帮助