Spring整合Mybatis

Maven

        <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>

###application.yml配置

spring:
  profiles:
    active: druid

# MyBatis
mybatis:
  # 搜索指定包别名
  #  typeAliasesPackage: com.pv3.springboot_base.Domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/*Mapper.xml
  # 加载全局的配置文件
  configLocation: classpath:mybatis/mybatis-config.xml

application-druid.yml配置

# 数据源配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # 主库数据源
      master:
        url: jdbc:mysql://192.168.168.10:3306/evaluation?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: evaluation
        password: x1pEJVNLZLnj66XI
      # 初始连接数
      initialSize: 5
      # 最小连接池数量
      minIdle: 10
      # 最大连接池数量
      maxActive: 20
      # 配置获取连接等待超时的时间
      maxWait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      # 配置一个连接在池中最大生存的时间,单位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # 配置检测连接是否有效
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
	<settings>
		<setting name="cacheEnabled"             value="true" />  <!-- 全局映射器启用缓存 -->
		<setting name="useGeneratedKeys"         value="true" />  <!-- 允许 JDBC 支持自动生成主键 -->
		<setting name="defaultExecutorType"      value="REUSE" /> <!-- 配置默认的执行器 -->
		<setting name="logImpl"                  value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
		<!-- <setting name="mapUnderscoreToCamelCase" value="true"/>  驼峰式命名 -->
	</settings>
	
</configuration>

DruidProperties.java

/** druid 配置属性 */
@Configuration
public class DruidProperties {
  @Value("${spring.datasource.druid.initialSize}")
  private int initialSize;

  @Value("${spring.datasource.druid.minIdle}")
  private int minIdle;

  @Value("${spring.datasource.druid.maxActive}")
  private int maxActive;

  @Value("${spring.datasource.druid.maxWait}")
  private int maxWait;

  @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
  private int timeBetweenEvictionRunsMillis;

  @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
  private int minEvictableIdleTimeMillis;

  @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
  private int maxEvictableIdleTimeMillis;

  @Value("${spring.datasource.druid.validationQuery}")
  private String validationQuery;

  @Value("${spring.datasource.druid.testWhileIdle}")
  private boolean testWhileIdle;

  @Value("${spring.datasource.druid.testOnBorrow}")
  private boolean testOnBorrow;

  @Value("${spring.datasource.druid.testOnReturn}")
  private boolean testOnReturn;

  public DruidDataSource dataSource(DruidDataSource datasource) {
    /** 配置初始化大小、最小、最大 */
    datasource.setInitialSize(initialSize);
    datasource.setMaxActive(maxActive);
    datasource.setMinIdle(minIdle);

    /** 配置获取连接等待超时的时间 */
    datasource.setMaxWait(maxWait);

    /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
    datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

    /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
    datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);

    /**
     * 用来检测连接是否有效的sql,要求是一个查询语句,常用select
     * 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
     */
    datasource.setValidationQuery(validationQuery);
    /**
     * 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
     */
    datasource.setTestWhileIdle(testWhileIdle);
    /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
    datasource.setTestOnBorrow(testOnBorrow);
    /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
    datasource.setTestOnReturn(testOnReturn);
    return datasource;
  }
}

ApplicationConfig.java

package com.pv3.springboot_base.Config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.pv3.springboot_base.Mapper")
public class ApplicationConfig {}

DruidConfig.java

package com.pv3.springboot_base.Config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.pv3.springboot_base.Config.properties.DruidProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/** druid 配置多数据源 */
@Configuration
public class DruidConfig {
  @Bean
  @ConfigurationProperties("spring.datasource.druid.master")
  public DataSource masterDataSource(DruidProperties druidProperties) {
    DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
    return druidProperties.dataSource(dataSource);
  }
}

MyBatisConfig.java

package com.pv3.springboot_base.Config;

import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/** Mybatis支持*匹配扫描包 */
@Configuration
public class MyBatisConfig {
  @Autowired private Environment env;

  static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

  public static String setTypeAliasesPackage(String typeAliasesPackage) {
    ResourcePatternResolver resolver =
        (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
    MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
    List<String> allResult = new ArrayList<String>();
    try {
      for (String aliasesPackage : typeAliasesPackage.split(",")) {
        List<String> result = new ArrayList<String>();
        aliasesPackage =
            ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim())
                + "/"
                + DEFAULT_RESOURCE_PATTERN;
        Resource[] resources = resolver.getResources(aliasesPackage);
        if (resources != null && resources.length > 0) {
          MetadataReader metadataReader = null;
          for (Resource resource : resources) {
            if (resource.isReadable()) {
              metadataReader = metadataReaderFactory.getMetadataReader(resource);
              try {
                result.add(
                    Class.forName(metadataReader.getClassMetadata().getClassName())
                        .getPackage()
                        .getName());
              } catch (ClassNotFoundException e) {
                e.printStackTrace();
              }
            }
          }
        }
        if (result.size() > 0) {
          HashSet<String> hashResult = new HashSet<String>(result);
          allResult.addAll(hashResult);
        }
      }
      if (allResult.size() > 0) {
        typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
      } else {
        throw new RuntimeException(
            "mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:"
                + typeAliasesPackage
                + "未找到任何包");
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return typeAliasesPackage;
  }

  @Bean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    //    String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
    String mapperLocations = env.getProperty("mybatis.mapperLocations");
    String configLocation = env.getProperty("mybatis.configLocation");
    //    typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
    VFS.addImplClass(SpringBootVFS.class);

    final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    //    sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
    sessionFactory.setMapperLocations(
        new PathMatchingResourcePatternResolver().getResources(mapperLocations));
    sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
    return sessionFactory.getObject();
  }
}

IUserService.java

package com.pv3.springboot_base.Service;

import java.util.List;
import java.util.Map;

public interface IUserService {
  public List<Map<String, Object>> select();
}

UserServiceImpl.java

package com.pv3.springboot_base.Service.impl;

import com.pv3.springboot_base.Mapper.UserMapper;
import com.pv3.springboot_base.Service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements IUserService {

  @Autowired UserMapper userMapper;

  @Override
  public List<Map<String, Object>> select() {
    return userMapper.select();
  }
}

演示

package com.pv3.springboot_base.Controller;

import com.pv3.springboot_base.Service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class DemoController {

  @Autowired private UserServiceImpl userService;

  @RequestMapping("/mybatis")
  public String mybatis() {
    List<Map<String, Object>> select = userService.select();
    System.out.println(select);
    return "mybatis演示";
  }
}