这里提供两种springboot+mybatis+通用mapper的整合方式,一种springboot自动配置,一种代码配置。
1、首先我们要知道一些基本知识:
① mybatis不是一个orm框架,他里面的实体类实际作用都是sql语句查询之后自动装配的结果集
②tk.mybatis.mapper是一个开源的mybatis插件,是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及Example 相关的单表操作。通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作,使用它可以很方便的进行开发,可以节省开发人员大量的时间。
③通用 Mapper 有很多种集成方式,这里只会介绍springboot情况下的两种配置方式。Java 编码方式集成是最少见的一种情况,但是通过这种集成方式可以很容易让大家看清通用 Mapper 集成的入口。和 Spring 集成是最常见的,Spring Boot 也在慢慢成为主流,为了便于在集成通用 Mapper 的情况下仍然可以和第三方的工具集成,这里也会有很多种集成的方式。
2、集成方式一:
①、mapper-spring-boot-starter
在 starter 的逻辑中,如果你没有使用 @MapperScan 注解,你就需要在你的接口上增加 @Mapper 注解,否则 MyBatis 无法判断扫描哪些接口。
这里的第一种用法没有用 @MapperScan 注解,所以你需要在所有接口上增加 @Mapper 注解。
你只需要添加通用 Mapper 提供的 starter 就完成了最基本的集成,依赖如下:
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>版本号</version>
</dependency>
注意:引入该 starter 时,和 MyBatis 官方的 starter 没有冲突,但是官方的自动配置不会生效!
如果你需要对通用 Mapper 进行配置,你可以在 Spring Boot 的配置文件中配置 mapper. 前缀的配置。
例如在 yml 格式中配置:
mapper:
mappers:
- tk.mybatis.mapper.common.Mapper
- tk.mybatis.mapper.common.Mapper2
notEmpty: true
在 properties 配置中:
mapper.mappers=tk.mybatis.mapper.common.Mapper,tk.mybatis.mapper.common.Mapper2
mapper.notEmpty=true
由于 Spring Boot 支持 Relax 方式的参数,因此你在配置 notEmpty 时更多的是用 not-empty,也只有在 Spring Boot 中使用的时候参数名不必和配置中的完全一致。
如果你对 Spring Boot 的 Environment 了解,你可以用 Spring Boot 支持的所有方式进行配置。
②、代码方式进行配置
注意:Spring Boot集成MyBatis打包成jar时,setTypeAliasesPackage(“xxx”)找不到类的问题
解决方式:
MyBatis扫描通过VFS来实现
在Spring Boot中,由于是嵌套Jar,导致Mybatis默认的VFS实现DefaultVFS无法扫描嵌套Jar中的类。
解决办法,实现自定义的VFS,参考DefaultVFS增加对Spring Boot嵌套JAR的处理。
以下为SpringBootVFS
package com.zhibi.xiuba.mgr.conf;
import org.apache.ibatis.io.VFS;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by QinHe on 2018-08-07.
*/
public class SpringBootVFS extends VFS {
@Override
public boolean isValid() {
return true;
}
@Override
protected List<String> list(URL url, String path) throws IOException {
ClassLoader cl = this.getClass().getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
Resource[] resources = resolver.getResources(path + "/**/*.class");
List<Resource> resources1 = Arrays.asList(resources);
List<String> resourcePaths = new ArrayList<String>();
for (Resource resource : resources1) {
resourcePaths.add(preserveSubpackageName(resource.getURI(), path));
}
return resourcePaths;
}
private static String preserveSubpackageName(final URI uri, final String rootPath) {
final String uriStr = uri.toString();
final int start = uriStr.indexOf(rootPath);
return uriStr.substring(start, uriStr.length());
}
}
1、MyBatis基础配置
package com.zhibi.xiuba.mgr.conf;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;
/**
* MyBatis基础配置
*/
@Configuration
@EnableTransactionManagement
public class MyBatisJpaConfig implements TransactionManagementConfigurer {
@Autowired
@Qualifier("dataSource")
private DataSource dataSource;
@Resource(name = "transactionManager")
private PlatformTransactionManager txManagerJpa;
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean() {
//解决myBatis下 不能嵌套jar文件的问题
VFS.addImplClass(SpringBootVFS.class);
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.zhibi.xiuba.task.spi.domain,; \t\ncom.zhibi.xiuba.order.spi.model,; \t\ncom.zhibi.xiuba.mgr.model,; \t\n" +
"com.zhibi.xiuba.user.spi.model,; \t\ncom.zhibi.xiuba.schedule.spi.domain,; \t\ncom.zhibi.xiuba.pay.spi.model");
//分页插件
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
//添加插件
bean.setPlugins(new Interceptor[]{pageHelper});
//添加XML目录
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
bean.setMapperLocations(resolver.getResources("classpath:mapper/*/*.xml"));
return bean.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "txManagerMybatis")
public PlatformTransactionManager txManagerMybatis(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "transactionManager")
public PlatformTransactionManager txManagerJpa(EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManagerJpa;
}
}
2、通用mapper扫描配置类
package com.zhibi.xiuba.mgr.conf;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;
import java.util.Properties;
/**
* MyBatis扫描接口,使用的tk.mybatis.spring.mapper.MapperScannerConfigurer
*/
@Configuration
//TODO 注意,由于MapperScannerConfigurer执行的比较早,所以必须有下面的注解
@AutoConfigureAfter(MyBatisJpaConfig.class)
public class MyBatisMapperScannerConfig {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
mapperScannerConfigurer.setBasePackage("com.zhibi.xiuba.mgr.mapper");
Properties properties = new Properties();
properties.setProperty("mappers", "com.zhibi.xiuba.mgr.util.CustomerMapper");
properties.setProperty("notEmpty", "false");
properties.setProperty("IDENTITY", "MYSQL");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
}