七、常见问题
1. mappers 参数导致的各种错误
主要针对 Mapper 3.x 版本,升级到 4.x 能解决常见的 mappers 参数问题
常见症状:
Error invoking SqlProvider method (tk.mybatis.mapper.provider.SpecialProvider.dynamicSQL)
java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.SpecialProvider.<init>()
出现这个问题的原因是因为你用到了 tk.mybatis.mapper.common.Mapper<T>
之外的其他接口,例如:
MySqlMapper
SqlServerMapper
InsertListMapper
InsertUseGeneratedKeysMapper
当你没有配置 mappers
参数的时候,通用 Mapper 只会解析 tk.mybatis.mapper.common.Mapper<T>
中提供的方法,所以你使用不包含在内的其他方法时就会报错。
通常在使用接口时,都会创建自己的 BaseMapper<T>
接口,例如:
package x.y.z;
//import ...
public interface BaseMapper<T> extends Mapper<T>, MySqlMapper<T> {
}
这种情况下,如果你不正确配置 mappers
参数,你就无法使用 MySqlMapper<T>
中提供的几个方法。
配置方法如下
在使用 Spring XML 方式配置时,配置如下:
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="tk.mybatis.mapper.xml"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="properties">
<value>
mappers=x.y.z.BaseMapper
</value>
</property>
</bean>
想要配置其他属性时,一行配置一个 key=value 即可。
在 Spring Boot 中,可以直接在配置文件中按照下面方式指定:
mapper.mappers=x.y.z.BaseMapper
在1.集成通用 Mapper 文档中有很多种集成方式,文档中详细介绍了如何进行配置。
1.1 使用 Devtools 时也会引发上面的问题
由于 Devtools 使用不同的类加载器实现的动态加载,经过测试发现 Spring Boot 使用 Devtools 的时候,@RegisterMapper
等类会使用 RestarClassLoader
进行加载,而 AppClassLoader
会加载不需要重启的类,
而前者的 parent 是后者,这就导致 AppClassLoader
加载的 XXMapper
,在初始化时,由于获取不到另一个类加载器加载的注解类,导致获取失败,因而导致了初始化失败,后续方法都无法调用(包括Example创建)。
目前的解决版本就是先禁用 Devtools,后续更新会尝试解决该问题。
该问题影响的版本为:4.0.0~4.0.2。
2. Example 无法获取实体类xxx.Yyy对应的表名!
常见异常:
- java.lang.RuntimeException: 无法获取实体类xxx.Yyy对应的表名!`
出现这个问题的原因有两种。
第一种情况通常是通用 Mapper 没有配置好,没有对 MyBatis 方法初始化造成的。常见的判断方法就是看看其他非 Example
的通用方法能否执行,如果不能执行就是配置的问题。如果能正常执行,可能就是第二种情况。
第二种情况就是调用方法的位置或者时机早于通用 Mapper 初始化,这种情况下可以通过升级到 4.x 版本解决,4.x 版本的所有配置方式理论上都是在 MyBatis 初始化的同时进行的,也就是在你能使用 MyBatis 的时候,通用 Mapper 就已经准备好了。如果还存在这种问题,就可以使用 XML 配置方式中的 Configuration
方式,参考这里XML 配置使用 Configuration。Spring Boot 参考下面的代码:
3. Spring Boot 中注解注意事项
如果你使用了 @tk.xxx.MapperScan
注解(包名必填),通用 Mapper 就会自动处理所有通用方法。
如果不使用该注解,你没有别的办法设置包名,所以通用 Mapper 就无法判断哪些接口属于 DAO 层,因此你需要给所有的 Mapper 接口增加 @org.xxx.Mapper
注解,否则 MyBatis 就扫描不到任何接口。
4. 集成 Activiti BPM 出错
通过查找依赖发现 activiti 中存在下面的依赖:
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>x.x.x</version>
</dependency>
这个依赖和 Mapper 中的 JPA 依赖有冲突:
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>x.x.x</version>
</dependency>
按照类加载顺序,persistence-api-1.0.jar 会更早的加载,因此会出错。
解决办法就是排除 Mapper 自带的这个依赖,使用 hibernate 这个 JPA 就能解决。
排除方式如下:
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>x.x.x</version>
<exclusions>
<exclusion>
<artifactId>persistence-api</artifactId>
<groupId>javax.persistence</groupId>
</exclusion>
</exclusions>
</dependency>