SpringBoot 开发常见问题记录

MyBatis

多模块下主模块无法注入子模块的 Mapper

假设有 commonshop 两个模块,common 模块里有 MyBatis 的 Mapper 接口和 XML 映射文件,而 shop 模块则依赖了 common 模块,此时若在 shop 模块中无法注入 common 模块的 Mapper,则可以参考以下方法解决问题。

  • 第一步,先确认主模块可以正常扫描到子模块的 XML 映射文件,YML 的内置内容如下:
1
2
mybatis:
mapper-locations: classpath*:/mapper/**/*.xml

提示

值得一提的是,在主模块的 application.yml 里面,配置 MyBatis 的 mapper-locations 时,若使用了 classpath,那么只会扫描当前模块的 XML 映射文件,而使用 classpath* 则会扫描所有 Jar 包下的 XML 映射文件。

  • 第二步,在主模块的启动类上添加 @MapperScan 注解,这是为了可以扫描到子模块的的 Mapper 接口,而且被扫描到的 Mapper 接口,在编译之后都会自动生成相应的实现类。若子模块没有在主模块的启动类可以扫描的包或者子包下面,那么还需要在主模块的启动类上添加 @ComponentScan 注解,这样才能让 SpringBoot 扫描到子模块的其他 Bean 类,示例代码如下:
1
2
3
4
5
6
7
8
package com.shop;

@SpringBootApplication
@MapperScan("com.common.**.mapper")
@ComponentScan(basePackages = {"com.common"})
public class ShopApplication {

}

提示

  • @MapperScan("com.common.mapper"):扫描指定包中的接口
  • @MapperScan("com.common.*.mapper"):一个 * 代表任意字符串,但只代表一级包,比如可以扫到 com.common.aaa.mapper,不能扫到 com.common.aaa.bbb.mapper
  • @MapperScan("com.common.**.mapper"):两个 * 代表任意数量的包,比如可以扫到 com.common.aaa.mapper,也可以扫到 com.common.aaa.bbb.mapper