springboot druid mybatis 通过注解配置实现配置即可使用

application-dev.yml文件内容:
spring:
  datasource:
    enabled: true
    url: jdbc:mysql://127.0.0.1:3306/lt-iot?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
    username: root
    password: root
    # 使用druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    # 初始化大小,最小,最大
    initialSize: 1
    minIdle: 1
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true #是否缓存preparedStatement,也就是PSCache  官方建议MySQL下建议关闭   个人建议如果想用SQL防火墙 建议打开
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    # 是否显示输出慢日志
    logSlowSql: false
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true
  db:
    mybatis:
      typeAliasesPackage: com.lenovo.esim.cloud.order.*.dao
      mapperLocations: classpath:mappers/*Mapper.xml
      configLocation: classpath:mybatis-config.xml

配置相关的实体类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 设置配置扫描实体类的路径相关的
 */
@ConfigurationProperties(prefix = "spring.db.mybatis")
@Component
@Data
public class MybatisConfigurationProperties {
    public String typeAliasesPackage;
    public String mapperLocations;
    public String configLocation;

}

配置数据源和事物

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import com.lenovo.esim.cloud.database.mybatis.Mapper;
import com.lenovo.esim.cloud.database.mybatis.MyMapperScan;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(MybatisConfigurationProperties.class)
@MyMapperScan(basePackages = "${spring.db.mybatis.typeAliasesPackage}", annotationClass = Mapper.class, sqlSessionFactoryRef = "sqlSessionFactory")
public class MybatisDataSourceConfiguration {
   @Autowired
   MybatisConfigurationProperties mybatisConfigurationProperties;

   @Bean
   @ConfigurationProperties(prefix = "spring.datasource")
   public DataSource druidDataSource() {
      return new DruidDataSource();
   }

   @Bean
   public DataSourceTransactionManager transactionManager() {
      DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(druidDataSource());
      return transactionManager;
   }

   @Bean
   public SqlSessionFactory sqlSessionFactory() throws Exception {
      System.out.println(JSON.toJSON(mybatisConfigurationProperties));
      SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
      sessionFactory.setDataSource(druidDataSource());
      PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
      sessionFactory.setConfigLocation(resolver.getResource(mybatisConfigurationProperties.configLocation));
      sessionFactory.setMapperLocations(resolver.getResources(mybatisConfigurationProperties.mapperLocations));
      SqlSessionFactory resultSessionFactory = sessionFactory.getObject();
      return resultSessionFactory;
   }

   @Bean(name = "txAdvice")
   public TransactionInterceptor getAdvisor() throws Exception {
      DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(druidDataSource());
      Properties properties = new Properties();
      properties.setProperty("get*", "PROPAGATION_REQUIRED,-Exception,readOnly");
      properties.setProperty("add*", "PROPAGATION_REQUIRED");
      properties.setProperty("save*", "PROPAGATION_REQUIRED");
      properties.setProperty("insert*", "PROPAGATION_REQUIRED");
      properties.setProperty("update*", "PROPAGATION_REQUIRED");
      properties.setProperty("delete*", "PROPAGATION_REQUIRED");
      TransactionInterceptor tsi = new TransactionInterceptor(transactionManager,properties);
      return tsi;
   }
   @Bean
   public BeanNameAutoProxyCreator txProxy() {
      BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
      creator.setInterceptorNames("txAdvice");
      creator.setBeanNames("*Service", "*ServiceImpl");
      creator.setProxyTargetClass(true);
      return creator;
   }
}
import com.lenovo.esim.cloud.database.mybatis.MyMapperScan;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.mapper.ClassPathMapperScanner;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义重新扫描支持${}取值
 */
@Slf4j
@EnableConfigurationProperties(MybatisConfigurationProperties.class)
public class MybatisScannConfig implements ImportBeanDefinitionRegistrar,EnvironmentAware  {
    private Environment env;

    private ResourceLoader resourceLoader;
     public MybatisScannConfig(){

    }
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MyMapperScan.class.getName()));
        ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
        if(this.resourceLoader != null) {
            scanner.setResourceLoader(this.resourceLoader);
        }

        Class annotationClass = annoAttrs.getClass("annotationClass");
        if(!Annotation.class.equals(annotationClass)) {
            scanner.setAnnotationClass(annotationClass);
        }

        Class markerInterface = annoAttrs.getClass("markerInterface");
        if(!Class.class.equals(markerInterface)) {
            scanner.setMarkerInterface(markerInterface);
        }

        Class generatorClass = annoAttrs.getClass("nameGenerator");
        if(!BeanNameGenerator.class.equals(generatorClass)) {
            scanner.setBeanNameGenerator((BeanNameGenerator) BeanUtils.instantiateClass(generatorClass));
        }

        Class mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
        if(!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
            scanner.setMapperFactoryBean((MapperFactoryBean)BeanUtils.instantiateClass(mapperFactoryBeanClass));
        }

        scanner.setSqlSessionTemplateBeanName(annoAttrs.getString("sqlSessionTemplateRef"));
        scanner.setSqlSessionFactoryBeanName(annoAttrs.getString("sqlSessionFactoryRef"));
         List<String> basePackages = new ArrayList<String>();
        for (String pkg : annoAttrs.getStringArray("value")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(parsePlaceHolder(pkg));
            }
        }
        for (String pkg : annoAttrs.getStringArray("basePackages")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(parsePlaceHolder(pkg));
            }
        }
        for (Class<?> clazz : annoAttrs.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }

        scanner.registerFilters();
        scanner.doScan(StringUtils.toStringArray(basePackages));
    }

    private  String parsePlaceHolder(String pro) {
        if (pro != null && pro.contains(PropertySourcesPlaceholderConfigurer.DEFAULT_PLACEHOLDER_PREFIX)) {
            String proGetKeys=pro.substring(2, pro.length() - 1);
            String value = env.getProperty(proGetKeys);
            if (log.isDebugEnabled()) {
                log.debug("find placeholder value " + value + " for key " + pro);
            }
            if (null == value) {
                throw new IllegalArgumentException("property " + pro + " can not find!!!");
            }
            return value;
        }
        return pro;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.env = environment;
    }
}
/**
 * 注解开启扫描路径
 */
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.lenovo.esim.cloud.database.config.MybatisScannConfig;
import org.mybatis.spring.annotation.MapperScannerRegistrar;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.Import;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({MybatisScannConfig.class})
public @interface MyMapperScan {
    String[] value() default {};

    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    Class<? extends Annotation> annotationClass() default Annotation.class;

    Class<?> markerInterface() default Class.class;

    String sqlSessionTemplateRef() default "";

    String sqlSessionFactoryRef() default "";

    Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
}

猜你喜欢

转载自blog.csdn.net/liqi_q/article/details/85322949