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参数替换工具html
<plugin interceptor="com.zheling.interceptor.FullSQLInterceptor"/>
标题 "mybatissql_mybatis解决sql注入" 暗示了我们正在讨论MyBatis框架如何处理SQL注入问题。SQL注入是一种常见的安全漏洞,攻击者可以通过恶意输入篡改SQL查询,获取、修改或删除数据库中的敏感数据。MyBatis,作为...
把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -> MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt+O" 启用。 点击窗口左边的 "Filter" ...
MyBatis是一款优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射,极大地简化了传统Java开发中的数据库操作。SQLServer是微软公司推出的关系型数据库管理系统,广泛应用于企业级应用开发。本教程将通过...
MyBatis是一个强大的持久层框架,它允许开发者直接编写SQL语句,简化了数据库操作。在本文中,我们将深入探讨如何使用MyBatis直接执行SQL查询以及如何进行数据的批量插入。 **一、直接执行SQL查询** 在MyBatis中,...
这里,`sqlSessionFactory`是MyBatis的会话工厂,`params`可以是用于占位符替换的参数对象。使用这种方式,我们可以在代码中动态构建和执行SQL。 执行自定义SQL而不是XML配置文件中的SQL有以下优点: 1. 动态性:在...
标题 "idea插件mybaits log 打印sql语句" 涉及的是一个针对IntelliJ IDEA的MyBatis日志插件,它的主要功能是帮助开发者在开发过程中实时查看并打印出MyBatis执行的SQL语句。这个功能对于调试和优化数据库查询非常...
在本文中,我们将深入探讨如何在SpringBoot项目中结合Mybatis框架进行XML方式的SQL配置。SpringBoot以其简洁的配置和强大的自动配置能力,极大地简化了应用开发过程,而Mybatis作为一款轻量级的持久层框架,允许...
`会被实际的参数值所替换,而SQL语句本身则提前编译好了。由于预编译SQL只允许合法的SQL语法,因此可以有效防止SQL注入。 ##### 2. 避免使用脚本变量(Scripting Variables) 在MyBatis中,除了`#{}`之外还可以使用...
Mybatis日志参数快速替换占位符工具是一个实用的辅助工具,它可以帮助开发者在调试过程中更方便地查看和理解Mybatis执行的SQL语句。在默认的日志输出中,Mybatis使用占位符(?)表示传入的参数,这在某些情况下可能...
MyBatis是一个流行的Java持久层框架,它简化了与数据库之间的交互,允许开发者将SQL查询直接集成到Java代码中。本教程将引导你通过JDBC连接到SQL Server 2005数据库,创建一个最小的例子来展示MyBatis的基本用法。 ...
还原MyBatis输出的日志为完整的SQL语句。 把SQL日志里面的?替换为真正的参数值。 选中要还原的MyBatis日志,右键点击菜单Restore Sql,还原SQL语句. Java接口方法与Mapper xml文件互相跳转。 按钮作用 Text: 从文本...
mybatis修改了mapper xml不用重启tomcat,热发布热更新.zip
在MyBatis框架中,拦截器(Interceptor)是一种强大的工具,可以用来在SQL执行的生命周期内插入自定义逻辑。在本主题中,我们将探讨如何利用MyBatis拦截器实现分页查询、动态修改SQL以及调整参数值。这些功能对于...
这里,我们创建了一个名为`copyFromMappedStatement`的方法,它使用MappedStatement.Builder来构建一个新的MappedStatement对象,同时保持原有配置不变,只是替换掉SQL源。 在实际应用中,这个SqlInterceptor可以...
在MyBatis框架中,SQL查询拦截修改是一种高级特性,它允许开发者在SQL执行的特定阶段插入自定义的逻辑,如添加额外的日志记录、性能分析、安全性检查等。这主要是通过实现`Interceptor`接口来完成的。 `Interceptor...
把 mybatis 输出的sql日志还原成完整的sql语句。 将日志输出的sql语句中的问号 ? 替换成真正的参数值。 通过 "Tools -> MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt+O" 启用。 点击窗口左边的 "Filter" ...
通过mybatis拦截器将查询语句、更新语句、删除语句、插入语句中指定表明替换为另一个表名
在Spring Boot应用中,MyBatis作为持久层框架,通常会使用XML文件来定义SQL映射。然而,当开发过程中需要频繁修改这些XML文件时,每次改动都需要重启服务才能看到效果,这无疑降低了开发效率。为了解决这个问题,...