楔子:其实我见你,是想听你说自己的故事。你之前没有告诉其他人的故事,你一个人承担的往事,你逃亡的岁月,你销声匿迹的岁月,你一点一滴累积的人生故事。- 宫部美雪《火车》
SpringBoot 集成 MyBatis 的项目中,怎么一次性注解并扫描多包下的 DAO 接口类呢?
或者说,怎么使用 @MapperScan 注解多个不同包路径下的 DAO 映射类?
亦或者说,@MapperScan 注解扫描接口类有哪三种设置方式?
项目技术栈升级 SpringBoot 2 + MyBatis 3,说一说踩过的坑,我们梦里挑灯看剑。
如果想要在每个 DAO 接口类上加 @Mapper
注解,这不但麻烦,也很繁琐。在 SpringBoot 集成 MyBatis 的项目中,用 @MapperScan
注解,即可实现多路径多包扫描。
1) 可以使用 @MapperScan(basePackages = {"", ""})
,如:
@Configuration
@MapperScan(basePackages = {"com.meiwei.tan.dao.mall", "com.meiwei.ping.dao.crm"})
public class MyBatisConfiguration {
2) 也可以使用 @MapperScan(value = {"", ""})
,效果一样:
@Configuration
@MapperScan(value = {"com.meiwei.tan.dao.mall", "com.meiwei.ping.dao.crm"})
public class MyBatisConfiguration {
3) 还有一种通过使用 @MapperScan(basePackageClasses = {xx1.class, xx2.class})
来指定多类进行扫描,虽然这种方式不常使用:
@Configuration
@MapperScan(basePackageClasses = {OrderDao.class, UserDao.class})
public class MyBatisConfiguration {
上面一种 @MapperScan 注解,三种设置方式
,最终都能达到目标被扫描的效果,看下源码一清二楚,这里贴一段:
如果还是扫描不到配置包路径下的接口类,请确认以下配置是否 OK:
1)org.mybatis.spring.boot 是否依赖
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.1version>
dependency>
2)Mybatis 依赖版本与 SpringBoot 的版本是否兼容
比如:org.mybatis.spring.boot 的依赖版本是 1.3.2,springboot 使用的是 2.0.2 版本,在 POJO 实体类中使用 @mapper 注解时,能正常起作用,而注掉 @mapper 并使用 @mapperScan 可能就会报错。
3)系统配置或实例是否被加载和被创建
如果是使用测试用例在本地跑,要先确保系统配置是否正常被加载和初始化,较 SpringMVC 的各环境和系统配置,SpringBoot 零配置的特性使有些地方的配置容易被忽视或遗忘。检查清单:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class JUnitTestBase {
@BeforeClass
public static void beforeClass(){
System.setProperty("app.id","meiwei");
System.setProperty("apollo.bootstrap.enabled","true");
System.setProperty("apollo.bootstrap.namespaces","application,db,dubbo,redis,mq");
}
}
@EnableAutoConfiguration()
@Configuration()
@ComponentScan(value = {"com.meiwei.tan.service", "com.meiwei.*.service"})
@EnableTransactionManagement
@EnableAspectJAutoProxy
public class App {
}
public class OrderServiceTest extends JUnitTestBase {
@Autowired
IOrderService iOrderService;
@Test
public void testOrderDetail() {
OrderDetailQuery orderDetailQuery = new OrderDetailQuery();
orderDetailQuery.setBizChannel(0);
OrderDO orderDO = iOrderService.orderDetail(orderDetailQuery);
System.out.println(JSON.toJSONString(orderDO));
}
}