`

MyBatis SQL 热替换

阅读更多
MyBatis SQL 热替换
-----------------------
package cn.bisoft.ibatis;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.ibatis.binding.MapperProxyFactory;
import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.builder.annotation.MapperAnnotationBuilder;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.session.Configuration;

import cn.bisoft.util.CollectionUtil;
import cn.bisoft.util.ReflectUtil;

public final class ConfigurationRefactor {

	private static final String FIELD_LOADED_RESOURCES = "loadedResources";
	private static final String FIELD_MAPPER_REGISTRY = "mapperRegistry";
	private static final String FIELD_KNOW_MAPPERS = "knownMappers";
	private static final String FIELD_MAPPED_STATEMENTS = "mappedStatements";
	private static final String FIELD_CACHES = "caches";
	private static final String FIELD_RESULT_MAPS = "resultMaps";
	private static final String FIELD_PARAMETER_MAPS = "parameterMaps";
	private static final String FIELD_KEY_GENERATORS = "keyGenerators";
	private static final String FIELD_SQL_FRAGMENTS = "sqlFragments";

	/**
	 * 热替换MyBatis的SQL.新增加Mapper暂时不适用.
	 * 
	 * @param conf Configuration
	 * @param name Mapper 完全限定类名
	 * @throws Exception
	 */
	public void replaceMapper(Configuration conf, String name) throws Exception {
		Class<?> type = conf.getClass().getClassLoader().loadClass(name);

		if (null != type) {
			// 1. lock configuration

			synchronized (conf.getClass()) {

				// 2. 清除配置的Mapper资源标志
				String resource = type.toString();

				if (conf.isResourceLoaded(resource)) {
					// 利用反射修改
					Set<String> loadedResources = (Set<String>) ReflectUtil
							.get(conf, FIELD_LOADED_RESOURCES);
					loadedResources.remove(resource);
				} else {
					// PASS
				}

				// 3. 清除Mapper资源
				if (conf.hasMapper(type)) {
					MapperRegistry mapperRegistry = (MapperRegistry) ReflectUtil
							.get(conf, FIELD_MAPPER_REGISTRY);
					Map<Class<?>, MapperProxyFactory<?>> knownMappers = (Map<Class<?>, MapperProxyFactory<?>>) ReflectUtil
							.get(conf, FIELD_KNOW_MAPPERS);
					knownMappers.put(type, new MapperProxyFactory(type));
				}

				// 4. 清除语句
				Map<String, MappedStatement> mappedStatements = (Map<String, MappedStatement>) ReflectUtil
						.get(conf, FIELD_MAPPED_STATEMENTS);

				Map<String, MappedStatement> mappedStatementsDup = CollectionUtil
						.cloneMap(mappedStatements);

				ReflectUtil.set(conf, FIELD_MAPPED_STATEMENTS,
						mappedStatementsDup, true);

				// 5. 清除缓存
				Map<String, Cache> caches = (Map<String, Cache>) ReflectUtil
						.get(conf, FIELD_CACHES);

				Map<String, Cache> cachesDup = CollectionUtil.cloneMap(caches);

				ReflectUtil.set(conf, FIELD_CACHES, new HashMap<String, Cache>(), true);

				// 6. 清除结果
				Map<String, ResultMap> resultMaps = (Map<String, ResultMap>) ReflectUtil
						.get(conf, FIELD_RESULT_MAPS);

				Map<String, ResultMap> resultMapsDup = CollectionUtil
						.cloneMap(resultMaps);

				ReflectUtil.set(conf, FIELD_RESULT_MAPS, resultMapsDup, true);

				// 7. 清除参数
				Map<String, ParameterMap> parameterMaps = (Map<String, ParameterMap>) ReflectUtil
						.get(conf, FIELD_PARAMETER_MAPS);

				Map<String, ParameterMap> parameterMapsDup = CollectionUtil
						.cloneMap(parameterMaps);

				ReflectUtil
						.set(conf, FIELD_PARAMETER_MAPS, resultMapsDup, true);

				// 8. 清除主键
				Map<String, KeyGenerator> keyGenerators = (Map<String, KeyGenerator>) ReflectUtil
						.get(conf, FIELD_KEY_GENERATORS);

				Map<String, KeyGenerator> keyGeneratorsDup = CollectionUtil
						.cloneMap(keyGenerators);

				ReflectUtil
						.set(conf, FIELD_KEY_GENERATORS, resultMapsDup, true);

				// 9. 清除SQL
				Map<String, XNode> sqlFragments = (Map<String, XNode>) ReflectUtil
						.get(conf, FIELD_SQL_FRAGMENTS);

				Map<String, XNode> sqlFragmentsDup = CollectionUtil
						.cloneMap(sqlFragments);

				ReflectUtil.set(conf, FIELD_SQL_FRAGMENTS, resultMapsDup, true);

				// 10. 重新加载配置
				MapperAnnotationBuilder parser = new MapperAnnotationBuilder(
						conf, type);
				parser.parse();

			}

		}

	}

}
 
 
分享到:
评论

相关推荐

    mybatis 日志 sql参数替换工具

    非常好用的,就是你们所要的 Mybatis日志参数快速替换占位符 sql参数替换工具html

    mybatis替换问号完整Sql插件

    &lt;plugin interceptor="com.zheling.interceptor.FullSQLInterceptor"/&gt;

    ideal mybatis打印sql插件

    把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -&gt; MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt+O" 启用。 点击窗口左边的 "Filter" ...

    SpringBoot +Mybatis xml方式配置SQL Demo源码下载

    SpringBoot +Mybatis xml方式配置SQL Demo源码下载,仅供新手参考

    Mybatis日志参数快速替换占位符工具的详细步骤

    主要介绍了Mybatis日志参数快速替换占位符工具的详细步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

    mybatis-log-plugin:将Mybatis SQL日志还原到原始的整个可执行SQL

    还原MyBatis输出的日志为完整的SQL语句。 把SQL日志里面的?替换为真正的参数值。 选中要还原的MyBatis日志,右键点击菜单Restore Sql,还原SQL语句. Java接口方法与Mapper xml文件互相跳转。 按钮作用 Text: 从文本...

    idea插件mybaits log 打印sql语句

    亲测可用,jar包直接拖到idea窗口即可

    MyBatis拦截器分页与动态修改SQL及其参数值

    MyBatis拦截器分页与动态修改SQL及其参数值 提取SQL Like 字段

    mybatis拦截器修改执行sql语句

    通过mybatis拦截器将查询语句、更新语句、删除语句、插入语句中指定表明替换为另一个表名

    mybatis自动生成

    把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -&gt; MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt+O" 启用。 点击窗口左边的 "Filter" ...

    mybatis 实现 SQL 查询拦截修改详解

    主要介绍了mybatis 实现 SQL 查询拦截修改详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring boot+mybatis+druid+SQL监控

    本文使用Druid的连接池,然后配置Druid的相关属性,完成对Spring web工程的JDBC监控。...其实,我采用Druid替换其它连接池,最关键的一个理由是Druid有对SQL执行的监控统计功能。 druid 实现 SQL、URI 等监控

    MyBatis SQL xml处理小于号与大于号正确的格式

    当我们需要通过xml格式处理sql语句时,经常会用到&lt; ,&lt;=,&gt;,&gt;=等符号,但是很容易引起xml格式的错误,这样会导致后台将xml字符串转换为xml文档时报错,从而导致程序错误。 这样的问题在iBatiS中或者自定义的...

    mybatis-log-plugin.zip

    mybatis log plugin离线版本支持idea2020.1把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -&gt; MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt...

    Mybatis现学现用

    字符串替换 默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像...

    mybatis-plus配置控制台打印完整带参数SQL语句的实现

    主要介绍了mybatis-plus配置控制台打印完整带参数SQL语句,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    mybatis-log-plugin.jar--支持最新idea2020.2

    mybatis log plugin离线版本支持idea2020.1把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -&gt; MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt...

    MyBatis Generator

    -- &lt;generatedKey column="ID" sqlStatement="oracle" identity="true" /&gt; --&gt; &lt;/table&gt; &lt;/context&gt; &lt;/generatorConfiguration&gt; 4、右击generatorConfig.xml 点击Generate MyBatis/iBATIS Artifacts 生成...

    springboot+mybatis配置控制台打印sql日志的方法

    主要介绍了springboot+mybatis配置控制台打印sql日志的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    mybatis笔记.zip

    MyBatis是一个支持自定义SQL、存储过程和高级映射的持久层框架。 MyBatis通过XML或注解的方式将Java对象映射到数据库中的SQL语句。 2. 配置文件和配置项: mybatis-config.xml是MyBatis的主配置文件,其中包含了...

Global site tag (gtag.js) - Google Analytics