解决mapper重名问题
问题
公司有一个集成开发平台,导入数据库表会自动生成实体类、mapper和xml等文件,这是一件很方便的事,可以省去很多没有技术性的重复工作。
但是最近我在使用这个平台的时候遇到了一个问题,那就是mapper冲突问题。当老表进行导入的时候,会生成与之前项目中已有mapper一样的名字,比如原项目中有个PersonMapper.java的文件,导入后就会有两个PersonMapper.java,这样就会冲突报错,导致项目无法启动。
怎么解决呢?将原先的mapper命名进行修改?显然是不现实的,也违背了开放封闭原则。
原因
首先需要明确,为什么两个一样命名的mapper文件会冲突,因为在在进行对象注入的时候,@Mapper在生成beanName的时候默认把首字母小写之后返回类名,如果存在两个命名完全一样的文件返回的beanName也是一样的,因此@Resource会不知道注入哪一个从而冲突。
清楚原因后,要做的就是当注入的时候怎么区分这两个mapper文件,进行不同的注入。
解决
在思考一番后,决定使用@MapperScan去解决这个问题,核心在于使用其中的nameGenerator字段。
@MapperScan中的nameGenerator继承于BeanNameGenerator

而在Spring的容器中,是使用BeanNameGenerator去命名检测到的组件,可以通过重写nameGenerator方法去重命名检测到的组件,具体解决代码如下所示:
@Configuration
@MapperScan(
value = {"xxx", "xxx"},
sqlSessionFactoryRef = "sqlSessionFactory",
nameGenerator = ComposerNameGenerator.class
)
public class ComposerNameGenerator implements BeanNameGenerator {
public ComposerNameGenerator() {
}
// definition 是被生成名字的BeanDefinition实例;
// registry是生成名字后注册进的BeanDefinitionRegistry。
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
// 拿到Bean定义信息里面的BeanClassName全类名
// 注意这个不是必须的,因为如果是继承关系,配上父类的依旧行了
String generatedBeanName = definition.getBeanClassName();
if (generatedBeanName == null) {
// 若没有配置本类全类名,去拿到父类的全类名+$child"俩表示自己
if (definition.getParentName() != null) {
generatedBeanName = definition.getParentName() + "$child";
}
// 工厂Bean的 就用方法的名字+"$created"
else if (definition.getFactoryBeanName() != null) {
generatedBeanName = definition.getFactoryBeanName() + "$created";
}
}
// 若一个都没找到,抛错
if (!StringUtils.hasText(generatedBeanName)) {
throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
} else {
return generatedBeanName;
}
}
}
这样配置后,即使是一样命名的mapper文件,只要不在同一个包中依旧可以正常注入。
解决mapper重名问题的更多相关文章
- C#显示声名接口就是为了解决方法重名的问题
class class1 { public static void Main(string[] args) { Person ps = new Person(); ps.KouLan(); IFlya ...
- JS重名解决方案
一个页面如果引用多个JS,或者像ASP.NET MVC,一个视图包含多个子视图,每个子视图有自己的JS,那么变量.函数的重名冲突机会将会大增. 如何解决? 这里有一个方案: 1.用类来封装子页的JS代 ...
- 4.4 ROS节点名称重名
4.4 ROS节点名称重名 场景:ROS 中创建的节点是有名称的,C++初始化节点时通过API:ros::init(argc,argv,"xxxx");来定义节点名称,在Pytho ...
- android - 解决“应用自定义权限重名”
背景 现场的开发今天跟我说,测试包装不上!报错"应用自定义权限重名"!!! 网上百度下关键字,发现魅族手机有这个毛病,顺藤摸瓜:"http://bbs.flyme.cn/ ...
- com.google.gson的SerializedName解决实体类与关键字的重名
使用google的gson包,解决实体类中字段与java关键字的重名: // 比如 当实体类中有switch关键字时,解决冲突如下 @SerializedName("switch" ...
- java 实现多个接口 方法重名的解决办法——内部类
package com.kk.innerClass; /** * 通过内部类实现接口 * 解决多个接口中方法重名问题 * */interface Machine { void run();} clas ...
- Mybatis中多表联查,查询出来的字段出现重名,造成数据异常的解决方法!
在做一对多出现的问题,引发的思考:当数据库表中,主表的主键id和明细表的中的字段名相同时怎么办?Mybatis进行自动映射赋值的时候会不会出现异常? 注意:M ...
- db2 v9.5迁移至v10.5,及遇重名节点数据库无法创建db的解决办法
同系统同版本可以使用备份恢复,本文前提是不同系统不同版本,使用db2move命令. 1.db2move db db_name export 此处注意,先建个目录放文件,因为文件比较多,如果上来直接ex ...
- MySql 外键重名问题
在使用mysql workbench 来设计数据库模型时可能一不注意就会出现外键约束重名的情况,并在执行sql语句是会报这样的错误: Error 1022 - Can't write; duplica ...
- Django中上传图片---避免因图片重名导致被覆盖
上一篇文章中(https://www.cnblogs.com/lutt/p/10640412.html),我们以图片文件夹+图片名字的方式来储存图片,这样的做法会导致有重名的图片会导致之前的图片被覆盖 ...
随机推荐
- NIO和传统IO
传统 IO 基于字节流或字符流(如 FileInputStream.BufferedReader 等)进行文件读写,以及使用 Socket 和 ServerSocket 进行网络传输. NIO 使用通 ...
- 数据分析(matplotlib pyplot)
文章目录 1.导入pyplot 库 2.绘出直线图 3.绘出实心点 4.绘出折线图 5.绘制正余弦函数 Pyplot 是 Matplotlib 的子库,提供了和 MATLAB 类似的绘图 API. P ...
- OpenGL常用函数整理
常用函数 颜色设置 glClear(GL_COLOR_BUFFER_BIT); //清空颜色,GL_COLOR_BUFFER_BIT是颜色缓冲区 glClearColor(R,G,B,A); //设置 ...
- 【笔记】 STL容器
[笔记] STL容器 vector vector<int> v; v.push_back(x); v.emplace(x); v.size(); v.erase(v.begin(),v.b ...
- .NET云原生应用实践(五):使用Blazor WebAssembly实现前端页面
本章目标 使用Blazor WebAssembly实现管理"贴纸"页面 集成认证与授权机制 如果你对Blazor WebAssembly的使用不感兴趣,可以跳过本章的阅读.你也可以 ...
- 推荐一个Star超过2K的.Net轻量级的CMS开源项目
推荐一个具有模块化和可扩展的架构的CMS开源项目. 01 项目简介 Piranha CMS是一个轻量级且跨平台的CMS库,专为.NET 8设计. 该项目提供多种模板,具备CMS基本功能,也有空模板方便 ...
- FFmpeg转码音视频时间戳设置分析
音频时间戳设置 以下代码基于FFmpeg n5.1.2进行分析 以下文档中有关音频的具体时间戳数据来自以下转码命令: ./ffmpeg_g -rw_timeout 5000000 -i 'rtmp:/ ...
- Redis究竟为什么这么快?
Redis为什么这么快? 完全基于内存,数据存在内存中,绝大部分请求是纯粹的内存操作,非常快速,跟传统的磁盘文件数据存储相比,避免了通过磁盘IO读取到内存这部分的开销. 数据结构简单,对数据操作也简单 ...
- apache tomcat 6集群负载和session复制
无意间看到tomcat 6集群的内容,就尝试配置了一下,还是遇到很多问题,特此记录.apache服务器和tomcat的连接方法其实有三种:JK.http_proxy和ajp_proxy.本文主要介绍最 ...
- python语言实现_通过端口转发实现跨网络(多网络之间)通信_science_network
本文使用python语言实现了一个端口转发的程序,该程序可以实现多网络之间的信息通信,当然这里有个前提,那就是多个网络都在一台主机上有可以连通的端口. 之所以有这个编写代码的需求,是因为最近使用的sc ...