springboot+mybatis+通用mapper

这里提供两种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;
    }
}

猜你喜欢

转载自blog.csdn.net/u014229652/article/details/81485363