SpringBoot mybatis Interceptor分页实现

什么是拦截器

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

	List<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
希望对你有所帮助

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中手写分页,可以借助MyBatisInterceptor实现。首先,你需要创建一个自定义的Interceptor类,实现MyBatisInterceptor接口。这个类会在执行查询之前对查询语句进行拦截和修改,以实现分页功能。 在你的Mapper类中,需要在需要分页的接口方法中添加一个分页参数Pageable pageable。Pageable是一个接口,它包含了分页所需的信息,例如当前页码、每页显示数量等。你可以根据具体需求选择使用哪些属性。 然后,在mapper.xml文件中,你不需要再手动写"limit 0,10"等语句了。Interceptor会自动根据Pageable参数组装分页的SQL语句,将其添加到原始的查询语句中。 以下是一个实现分页的示例代码: 1. 创建一个自定义的Interceptor类,实现MyBatisInterceptor接口,并重写intercept()方法。在该方法中,可以通过获取Pageable参数,从而修改原始的查询语句,实现分页功能。 ```java public class PaginationStatementInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 获取Mapper方法的参数 Object[] args = invocation.getArgs(); // 遍历参数,找到Pageable参数 for (Object arg : args) { if (arg instanceof Pageable) { Pageable pageable = (Pageable) arg; // 根据Pageable参数修改查询语句,实现分页 // ... break; } } // 执行原始的查询方法 return invocation.proceed(); } // 其他方法... } ``` 2. 在Spring Boot的配置文件中,将自定义的Interceptor配置到MyBatis的配置中。可以通过@Configuration类来实现。 ```java @Configuration public class MyBatisConfiguration { @Autowired private SqlSessionFactory sqlSessionFactory; @Bean public PaginationStatementInterceptor paginationStatementInterceptor() { PaginationStatementInterceptor interceptor = new PaginationStatementInterceptor(); // 配置Interceptor的其他参数... return interceptor; } @PostConstruct public void addInterceptor() { // 获取MyBatis的Configuration对象 Configuration configuration = sqlSessionFactory.getConfiguration(); // 添加自定义的Interceptor configuration.addInterceptor(paginationStatementInterceptor()); } // 其他配置... } ``` 通过以上步骤,你就可以在Spring Boot中实现手写分页功能了。只需要在需要分页的Mapper接口方法中添加Pageable参数,并在mapper.xml中不再需要手动写分页语句,Interceptor会自动帮你实现分页。 希望以上信息对你有所帮助。如果还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值