增加拦截器
import java.lang.reflect.Field; 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; /** * 1. 打印mysql完整的执行语句 * 2. 打印mysql语句执行时间 * 这里我们拦截Executor里面的query和update方法 *JDKversionused:<JDK1.8> *Author:简 */ @Intercepts({ @Signature( type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class} ) // @Signature( // type = Executor.class, // method = "update", // args = {MappedStatement.class, Object.class} // ) }) public class MyBatisInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); BoundSql boundSql = statementHandler.getBoundSql(); String originalSql = boundSql.getSql(); System.out.println("执行前的SQL:" + originalSql); // 获取原始 SQL // 修改 SQL String modifiedSql = originalSql.replace(" GROUP_CONCAT(", " wm_concat("); modifiedSql = modifiedSql.replace(" group_concat(", " wm_concat("); // 使用反射修改 BoundSql 中的 SQL Field field = BoundSql.class.getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, modifiedSql); System.out.println("执行后的SQL:" + boundSql.getSql()); // 继续执行后续操作 return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { // 可以接收配置的属性 } }
bean注入
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.zxlhdata.module.api.filter.MyBatisInterceptor; @Configuration public class MyBatisConfig { //拦截器bean注入 @Bean public ConfigurationCustomizer mybatisConfigurationCustomizer() { return configuration -> { configuration.addInterceptor(new MyBatisInterceptor()); }; } //redis bean注入 @Bean public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); //设置工厂链接 redisTemplate.setConnectionFactory(redisConnectionFactory); //设置自定义序列化方式 setSerializeConfig(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 设置redis过期监听事件 * @Description TODO * @param connectionFactory * @return * @return RedisMessageListenerContainer * @Author 何湘简 * @Date 2021年8月19日 上午10:54:35 */ @Bean RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); // 监听所有库的key过期事件 container.setConnectionFactory(connectionFactory); return container; } private void setSerializeConfig(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory redisConnectionFactory) { //对字符串采取普通的序列化方式 适用于key 因为我们一般采取简单字符串作为key StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); //普通的string类型的key采用 普通序列化方式 redisTemplate.setKeySerializer(stringRedisSerializer); //普通hash类型的key也使用 普通序列化方式 redisTemplate.setHashKeySerializer(stringRedisSerializer); //解决查询缓存转换异常的问题 大家不能理解就直接用就可以了 这是springboot自带的jackson序列化类,但是会有一定问题 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); //普通的值采用jackson方式自动序列化 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); //hash类型的值也采用jackson方式序列化 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); //属性设置完成afterPropertiesSet就会被调用,可以对设置不成功的做一些默认处理 redisTemplate.afterPropertiesSet(); } }
接口介绍
@Intercepts({@Signature(type = StatementHandler.class, method = “prepare”, args = {Connection.class, Integer.class})}),表示在 SQL 执行之前进行拦截处理。 @Intercepts 的作用:声明这是一个拦截器。 属性:Signature(注解) @Signature:要拦截的具体方法 属性: type-拦截接口(四种类型 ), method-拦截的方法(update,insert,select), args-重载时根据参数列表确定要拦截的方法。 Executor:拦截执行器的方法,例如 update、query、commit、rollback 等。可以用来实现缓存、事务、分页等功能。 ParameterHandler:拦截参数处理器的方法,例如 setParameters 等。可以用来转换或加密参数等功能。 ResultSetHandler:拦截结果集处理器的方法,例如 handleResultSets、handleOutputParameters 等。可以用来转换或过滤结果集等功能。 StatementHandler:拦截语句处理器的方法,例如 prepare、parameterize、batch、update、query 等。可以用来修改 SQL 语句、添加参数、记录日志等功能。
本文由 admin 创作,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:2024-08-22 17:48:49