如果controller请求的service使用的是BaseService写的方法,那么最终代码不会走到mapper接口的映射文件——换句话说,resource包下有没有映射文件都不影响查询
在把自动生成的文件复制到自己的项目时,要将接口和java文件放在java包下,将mapper包的映射文件放在resource包下
根据映射文件放置在resource下的位置,有两种情况
所谓的同包同目录不是说接口和映射文件都在一个包内,而是两个文件分开在不同包内,但包的名字以及层级完全相同
完全相同的情况下不用特别去做什么操作
映射文件从resource下开始看包名和层级
mapper接口从java下开始看包名和层级
经过测试发现,在springboot工程中,如果接口放在mapper包下(或者子包下),而映射文件也放在resource/mapper包下,那么此时springboot可以找到这些映射文件,在springboot看来,两者算同包同目录,估计是在springboot的哪个内置类中定义了这个默认路径(并且设置了扫描这个包和子包)
此时项目中的接口和映射文件放在两个不同的包下并且包名不完全相同
不完全相同的情况下,就需要在yml文件中说明映射文件的路径,让spring容器能找到这些文件
具体操作
通过AutoConfigure类找mybatis,最后找到mybatisproperties类,在里面找属性和方法,知道可以通过mapper-locations去配置映射文件地址,然后到springboot的配置文件中配置(或者简单的办法——百度)
举例
java项目中的classpath到底是什么 - SegmentFault 思否
下面只是举例了几种情况,要想真正理解classpath后的路径怎么写,可以看看上面的链接
只查询根目录,不深入子目录
图:
代码:
mybatis-plus: mapper-locations: classpath:*.xml
只查询指定的一级目录,不深入一级目录的子目录
图:
代码:
mybatis-plus: mapper-locations: classpath:dao/*.xml
特别的,如果直接放在com包下(一般也没人这样不规范放置吧?),需要加上前置目录(这种情况下只能用**/了 **/代表名称的路径),否则会报错
图:
代码:
mybatis-plus: mapper-locations: classpath:**/com/*.xml
只扫描到指定目录,不会扫描指定目录的子目录
图:
代码:
mybatis-plus: mapper-locations: classpath:**/springboot/*.xml
上面所有的情况,都只是扫描指定目录,如果希望连带子目录一起扫描,就在指定目录后加**/,这就能把指定目录以及所有子目录的文件都扫描到
图:
代码:
mybatis-plus: mapper-locations: classpath:**/springboot/**/*.xml
配置完映射文件,现在要配置接口文件
目前有两种方式让spring容器读取到mapper接口文件——@Mapper注解 和 包扫描
有的mapper自动生成工具会根据使用时的设置自动配好@Mapper注解或者包扫描
如果mapper接口使用@Mapper注解方式,后续开发时新创建的mapper接口,也得在类上使用这个注解
每个接口都要手动添加一个@Mapper太麻烦了,所以有了包扫描@MapperScan
如果希望使用包扫描(或者把@Mapper改为包扫描),需要在springboot启动类上或者自定义一个配置类,在类上使用包扫描注解
一旦使用包扫描,此时所有mapper接口上的@Mapper注解就失效了
@MapperScan(basePackages = {"com.javasm.springboot.mapper"})
在使用包扫描时,如果如图设置目录结构以及mapper的包扫描,有时候会出现只扫描mapper包下的接口,不扫描mapper包下的子包的情况(老师演示时出现的问题)
但是我个人测试了一下 扫描mapper接口时,把MyMapper接口放在mapper/base包下 一样能扫到,没有出现问题
即便把RoleMapper放到base下,依然能正常扫描到,这个包扫描并不是只扫描mapper包,会连带扫描子包