Spring学习笔记-Mybatis中Mapper和MapperScan注解&一些不是 mapper 的 interface 也会被处理成 mapper 而被创建成一个bean,启动报错

关于 mybatis 的 @MapperScan 用法心得

1.必需引用 mybatis-spring-boot-starter, 否则不能扫描生效。可以用 mybatis-plus 的 mybatis-plus-boot-starter 替代。

2.从网上搜 MapperScan,大部分说是通过 basePackage 指定扫描多个包,本身没问题,但不是一个完美的方案。原因如下:

(1)如果扫描的包名是一个较顶级的,那么,一些不是 mapper 的 interface 也会被处理成 mapper 而被创建成一个 spring bean,造成系统无法启动,这肯定不行。

(2)只有缩小包的范围,最好是只配置 mapper 对应包,但如果把所有包含 mapper 的包罗列出来,则也存在不足

- 其一,会导致列表变得比较长。用通配符解决一部分问题,但需要包包满足一些统一的规则。另外,对于层级不同的情况,不好处理。

- 其二,则降低了扩展性,因为每增加或调整 mapper 包,都要到 @MapperScan 中去注册。业务代码的变更影响了框架性的代码。尤其是对于多模块的情况,这个问题变得越发隐晦:谁能想到多引用一个模块就需要配置一下 @MapperScan?

- 其三,违背依赖的原则,本来框架不依赖业务,现在变成了框架反过来要因业务变化而调整代码。

重点:
3.因此,我认为最好的方式是,在 @MapperScan 中,使用 basePackage + annotationClass 组件解决问题。

(1)所有的 mapper 上加上 @Mapper 注解。这是合理的,因为本身 mapper 属于一类特殊的接口,理应该要通过特殊注册进行区分。

(2)有了第1条,basePackage 就可以指定一个较顶级的包名了

通过上面两条,一方面解决了 mapper 包动态变化的问题,因为业务上的代码一般会有一个统一的包前缀,典型的如 com.cortName, 那么就可以把它作为 basePackage,只需要配置一次,后面的变化都不受影响。

示例:

@MapperScan(basePackages = {
    
    "com.package1", "com.package2"}, annotationClass = Mapper.class)

@Mapper和@MapperScan两个注解是在Spring和Mybatis结合中会使用的注解。

那这两个注解到底有什么不同的用法呢?我们来看一下

@Mapper

1.作用:在接口类上添加了@Mapper,会自动的把 @Mapper 注解的接口生成动态代理类

添加位置:接口类上面

2.在每个需要实现类的接口上都添加@Mapper注解,相对比较繁琐

@MapperScan

1.作用:配置一个或多个包路径,自动的扫描这些包路径下的类,自动的为它们生成代理类。

添加位置:是在Springboot启动类上面添加

2.@MapperScan注解后可自定义扫描包,比如@MapperScan(“com.xxx.x x”),有了这个注解,可不用一个一个添加@Mapper注解

3.@MapperScan有很多属性,最常用的是:

annotationClass : 这个是基于包下面扫描所有的接口类并注册,也有指定的属性。   
markInterface : 基于包下面扫描所有接口类并注册,也可以指定特殊的接口为父类。
sqlSessionTemplateRef: 在指定使用sqlSessionTemplateRef的情况下,这里有一个或多个的Spring的容器。经常我们会使用一个或多个的数据库.
sqlSessionFactoryRef : 在指定使用sqlSessionFactoryRef的情况下,这里有一个或多个的Spring的容器。经常我们会使用一个或多个的数据库.
​nameGenerator :Spring的容器中,将使用BeanNameGenerator去命名检测到的组件。basePackageClasses : 这是一个安全替代basePackages()作为指定组件的扫描包。包下面的所有接口都将会被扫描。
basepackages : 基于包下面的扫描MyBatis的接口。注意是,只有是接口的将会被扫描注册,如果是具体的类将会被忽略。

猜你喜欢

转载自blog.csdn.net/qq_43842093/article/details/132639217