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;
}
本文介绍如何在Spring Boot项目中配置MyBatis和Druid数据源,包括数据源参数设置、SQL防火墙、慢日志、实体类配置、Mapper扫描及事物管理。
1817

被折叠的 条评论
为什么被折叠?



