前一阵子在项目中遇到了一个mybatis配置多数据源的坑,调试源码后解决该问题,总的来说,还是对mybatis的熟悉度不够,故踩了这个坑。
因公司项目不便演示,现用本人的一台阿里云服务器和本机mysql作为多数据源的配置,拿来演示:
配置如下:
server:
port: 8081
servlet:
context-path: /
application-display-name: movie
spring:
application:
name: movie
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
jdbcUrl: 'jdbc:mysql://服务器的ip:3306/wuznuan?useUnicode=true&characterEncoding=utf8&autoReconnect=true'
test:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
jdbcUrl: 'jdbc:mysql://192.168.100.117:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true'
mapper:
mappers: tk.mybatis.mapper.common.Mapper
identity: MYSQL
not-empty: false
logging:
level.org.choviwu.movie: debug
然后再配置 配置多数据源
主数据源连接工厂
从数据源连接工厂
项目结构大概为这样子:
生成好mapper代码之后,开始进行启动项目
结果如下,发现查找的服务器上的表居然串了?
没关系,我们来调试模式查看
找到MapperProxy类,我们来看看
public class MapperMethod {
private final SqlCommand command;
private final MethodSignature method;
public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
//获取sql 命令 也就是这一行报的错 ,进入代码
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, mapperInterface, method);
}
}
打开SqlCommand类:
这是因为mybatis再查到mapper没有该方法得时候会做xml和dao所对应得数据源,并刷新数据源 调试之后可得结果
更换包名: 调试MapperScannerRegistrar类,也就是mapperscan注解所引入得组件类 这个类就是再mapperscan扫描包下的所有beandefination信息,如果没有扫描到,则注册进去,如果扫描到,则直接continue
回想一下刚刚配置到mybatisconfig和testmybatisconfig, 前者扫描到的是org.choviwu.movie.mapper,后者则是org.choviwu.movie.mapper.test 很明显,当前者加载并定义好bean之后 后者则不会再加载(spring默认注册的是单例bean)
开始调试源码 中间的方法暂时不调试,自己可以去看看,这里第一个扫描到的mapper是9个,而这里我们也看到了test包下的dao接口了
而扫描到test包后则注册了0个类,这里是因为spring定义类的时候判断是否单例,单例类只被缓存一次 具体到方法可再下面截图:
以上可以得出个结论,我们可以给dao分个包,单独扫描指定的包,即可达到目的