一般来说应该是MybatisPlus和common模块 一起放在一个common模块上,方便演示则将MybatisPlus拆出来单独为一个模块
骨架图演示
依赖maven
< dependencies>
< dependency>
< groupId> com. xk100< / groupId>
< artifactId> xk- practice- common< / artifactId>
< version> 1.0 - SNAPSHOT< / version>
< / dependency>
< dependency>
< groupId> com. xk100< / groupId>
< artifactId> xk- practice- entity< / artifactId>
< version> 1.0 - SNAPSHOT< / version>
< / dependency>
< ! -- https: / / mvnrepository. com/ artifact/ org. springframework/ spring- jdbc -- >
< dependency>
< groupId> org. springframework< / groupId>
< artifactId> spring- jdbc< / artifactId>
< version> 5.3 .14 < / version>
< / dependency>
< dependency>
< groupId> mysql< / groupId>
< artifactId> mysql- connector- java< / artifactId>
< scope> runtime< / scope>
< / dependency>
< dependency>
< groupId> com. zaxxer< / groupId>
< artifactId> HikariCP < / artifactId>
< / dependency>
< ! -- https: / / mvnrepository. com/ artifact/ org. springframework/ spring- tx -- >
< dependency>
< groupId> org. springframework< / groupId>
< artifactId> spring- tx< / artifactId>
< / dependency>
< / dependencies>
config配置包
在实体类新增/更新到数据库时 对特定属性值做自动填充操作 实体类上加以下注解
@TableField (
value = "gmt_create" ,
fill = FieldFill . INSERT
)
private LocalDateTime gmtCreate;
@TableField (
value = "create_by" ,
fill = FieldFill . INSERT
)
private String createBy;
@TableField (
value = "gmt_update" ,
fill = FieldFill . INSERT_UPDATE
)
private LocalDateTime gmtUpdate;
@TableField (
value = "update_by" ,
fill = FieldFill . INSERT_UPDATE
)
private String updateBy;
GlobalMetaObjectHandler.class(属性填充配置类)
package com. xk. practice. mybatisplus. config ;
import com. baomidou. mybatisplus. core. handlers. MetaObjectHandler ;
import lombok. extern. slf4j. Slf4j ;
import org. apache. ibatis. reflection. MetaObject ;
import org. springframework. stereotype. Component ;
import java. time. LocalDateTime ;
@Component
@Slf4j
public class GlobalMetaObjectHandler implements MetaObjectHandler {
private final String gmtCreate = "gmtCreate" ;
private final String gmtUpdate = "gmtUpdate" ;
@Override
public void insertFill ( MetaObject metaObject) {
setInsertFieldValByName ( gmtCreate, LocalDateTime . now ( ) , metaObject) ;
setInsertFieldValByName ( gmtUpdate, LocalDateTime . now ( ) , metaObject) ;
}
@Override
public void updateFill ( MetaObject metaObject) {
setUpdateFieldValByName ( gmtUpdate, LocalDateTime . now ( ) , metaObject) ;
}
}
MybatisPlusConfig.clas
import com. baomidou. mybatisplus. extension. plugins. OptimisticLockerInterceptor ;
import com. baomidou. mybatisplus. extension. plugins. PaginationInterceptor ;
import com. baomidou. mybatisplus. extension. plugins. SqlExplainInterceptor ;
import com. xk. practice. common. constant. EnvConstant ;
import org. springframework. boot. autoconfigure. AutoConfigureAfter ;
import org. springframework. boot. autoconfigure. condition. ConditionalOnBean ;
import org. springframework. boot. autoconfigure. jdbc. DataSourceAutoConfiguration ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. context. annotation. Profile ;
import org. springframework. transaction. annotation. EnableTransactionManagement ;
import javax. sql. DataSource ;
@EnableTransactionManagement
@Configuration
@ConditionalOnBean ( { DataSource . class } )
@AutoConfigureAfter ( DataSourceAutoConfiguration . class )
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor ( ) {
return new PaginationInterceptor ( ) ;
}
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor ( ) {
return new OptimisticLockerInterceptor ( ) ;
}
@Bean
@Profile ( { EnvConstant . LOCAL, EnvConstant . DEV, EnvConstant . TEST } )
public SqlExplainInterceptor sqlExplainInterceptor ( ) {
return new SqlExplainInterceptor ( ) ;
}
}
PracticeMyBatisPlusConfig.class
import com. xk. practice. mybatisplus. constant. PackageConstant ;
import org. mybatis. spring. annotation. MapperScan ;
import org. springframework. context. annotation. Configuration ;
@MapperScan ( value = { PackageConstant. Mapper_PACKAGE } )
@Configuration
public class PracticeMyBatisPlusConfig extends MybatisPlusConfig {
public PracticeMyBatisPlusConfig ( ) {
System . out. println ( "*** PracticeMyBatisPlusConfig.init ***" ) ;
}
}
多数据源配置(重要细节)
多数据源要通过类上面的注解@MapperScan
区分不同数据源对应扫描的包(演示的是v1
和v1second
两个数据源对应扫描的路径) 若多数据源扫描同一个包,则以主数据源为主进行操作 两个数据源配置是一样的,区别在于扫描mapper包路径不同,以及引用文件的账号密码等参数不同,以及主数据源必须贴@Primary
注解
DataSourceConfig1.class
import com. baomidou. mybatisplus. extension. spring. MybatisSqlSessionFactoryBean ;
import com. xk. practice. mybatisplus. constant. PackageConstant ;
import org. apache. ibatis. session. SqlSessionFactory ;
import org. mybatis. spring. SqlSessionTemplate ;
import org. mybatis. spring. annotation. MapperScan ;
import org. springframework. beans. factory. annotation. Qualifier ;
import org. springframework. boot. context. properties. ConfigurationProperties ;
import org. springframework. boot. jdbc. DataSourceBuilder ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. context. annotation. Primary ;
import org. springframework. context. annotation. PropertySource ;
import org. springframework. core. io. support. PathMatchingResourcePatternResolver ;
import javax. sql. DataSource ;
@Configuration
@PropertySource ( "classpath:mybatis.properties" )
@MapperScan ( value = PackageConstant. Mapper_PACKAGE , sqlSessionTemplateRef = "db1SqlSessionTemplate" )
public class DataSourceConfig1 {
@Primary
@Bean ( name= "db1DataSource" )
@ConfigurationProperties ( prefix = "spring.datasource.one" )
public DataSource DataSource ( ) {
return DataSourceBuilder . create ( ) . build ( ) ;
}
@Primary
@Bean ( name= "db1SqlSessionFactory" )
public SqlSessionFactory db1SqlSessionFactory ( @Qualifier ( "db1DataSource" ) DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean ( ) ;
bean. setDataSource ( dataSource) ;
bean. setMapperLocations ( new PathMatchingResourcePatternResolver ( ) . getResources ( "classpath*:mapper/**/*.xml" ) ) ;
return bean. getObject ( ) ;
}
@Primary
@Bean ( name= "db1SqlSessionTemplate" )
public SqlSessionTemplate db1SqlSessionTemplate ( @Qualifier ( "db1SqlSessionFactory" ) SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate ( sqlSessionFactory) ;
}
}
DataSourceConfig2.class
import com. baomidou. mybatisplus. extension. spring. MybatisSqlSessionFactoryBean ;
import com. xk. practice. mybatisplus. constant. PackageConstant ;
import org. apache. ibatis. session. SqlSessionFactory ;
import org. mybatis. spring. SqlSessionTemplate ;
import org. mybatis. spring. annotation. MapperScan ;
import org. springframework. beans. factory. annotation. Qualifier ;
import org. springframework. boot. context. properties. ConfigurationProperties ;
import org. springframework. boot. jdbc. DataSourceBuilder ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. context. annotation. PropertySource ;
import org. springframework. core. io. support. PathMatchingResourcePatternResolver ;
import javax. sql. DataSource ;
@Configuration
@PropertySource ( "classpath:mybatis.properties" )
@MapperScan ( basePackages = PackageConstant. Mapper_PACKAGE_SECOND , sqlSessionTemplateRef = "db2SqlSessionTemplate" )
public class DataSourceConfig2 {
@Bean ( "db2DataSource" )
@ConfigurationProperties ( prefix = "spring.datasource.second" )
public DataSource DataSource ( ) {
return DataSourceBuilder . create ( ) . build ( ) ;
}
@Bean ( "db2SqlSessionFactory" )
public SqlSessionFactory db1SqlSessionFactory ( @Qualifier ( "db2DataSource" ) DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean ( ) ;
bean. setDataSource ( dataSource) ;
bean. setMapperLocations ( new PathMatchingResourcePatternResolver ( ) . getResources ( "classpath*:mapper/**/*.xml" ) ) ;
return bean. getObject ( ) ;
}
@Bean ( "db2SqlSessionTemplate" )
public SqlSessionTemplate db1SqlSessionTemplate ( @Qualifier ( "db2SqlSessionFactory" ) SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate ( sqlSessionFactory) ;
}
}
mybatis.properties
spring. datasource. one. driver- class - name = com. mysql. cj. jdbc. Driver
spring. datasource. one. jdbcUrl = jdbc: mysql: / / ip地址/ 数据库名? useUnicode= true & useSSL= false & characterEncoding= utf8& serverTimezone= Asia / Shanghai
spring. datasource. one. username = xxxxx
spring. datasource. one. password = xxxx
spring. datasource. second. driver- class - name = com. mysql. cj. jdbc. Driver
spring. datasource. second. jdbcUrl = jdbc: mysql: / / xxxxx
spring. datasource. second. username = xxxxx
spring. datasource. second. password = xxxx
constant常量包
PackageConstant.class
public interface PackageConstant {
String BASE_PACKAGE = "com.edt.practice.mybatisplus." ;
String EENTITY_PACKAGE = BASE_PACKAGE + ".**.entity" ;
String Mapper_PACKAGE = BASE_PACKAGE + "**.mapper.v1" ;
String Mapper_PACKAGE_SECOND = BASE_PACKAGE + "**.mapper.v1second" ;
}
事务管理配置包
TransactionManagerConfig.class
import org. springframework. aop. aspectj. AspectJExpressionPointcut ;
import org. springframework. aop. support. DefaultPointcutAdvisor ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
import org. springframework. transaction. PlatformTransactionManager ;
import org. springframework. transaction. interceptor. TransactionInterceptor ;
import javax. annotation. Resource ;
import java. util. Properties ;
@Configuration
public class TransactionManagerConfig {
public static final String transactionExecution = "execution(* com.xk..service..*(..))" ;
@Resource
private PlatformTransactionManager transactionManager;
@Bean
public TransactionInterceptor transactionInterceptor ( ) {
Properties attributes = new Properties ( ) ;
attributes. setProperty ( "get*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "select*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "list*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "page*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "find*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "has*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "locate*" , "PROPAGATION_REQUIRED,-Exception,readOnly" ) ;
attributes. setProperty ( "register*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "save*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "insert*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "update*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "batch*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "do*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "lock*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "add*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "del*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "modify*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "auth*" , "PROPAGATION_REQUIRED,-Exception" ) ;
TransactionInterceptor txAdvice = new TransactionInterceptor ( transactionManager, attributes) ;
return txAdvice;
}
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor ( ) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut ( ) ;
pointcut. setExpression ( transactionExecution) ;
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor ( ) ;
advisor. setPointcut ( pointcut) ;
Properties attributes = new Properties ( ) ;
attributes. setProperty ( "get*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "select*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "list*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "page*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "find*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "has*" , "PROPAGATION_SUPPORTS,-Exception,readOnly" ) ;
attributes. setProperty ( "locate*" , "PROPAGATION_REQUIRED,-Exception,readOnly" ) ;
attributes. setProperty ( "register*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "save*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "insert*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "update*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "batch*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "do*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "lock*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "add*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "del*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "modify*" , "PROPAGATION_REQUIRED,-Exception" ) ;
attributes. setProperty ( "auth*" , "PROPAGATION_REQUIRED,-Exception" ) ;
TransactionInterceptor txAdvice = new TransactionInterceptor ( transactionManager, attributes) ;
advisor. setAdvice ( txAdvice) ;
return advisor;
}
}
启动类
import com. xk. practice. config. apiversion. EnableApiVersioning ;
import org. springframework. boot. SpringApplication ;
import org. springframework. boot. autoconfigure. SpringBootApplication ;
import org. springframework. cloud. client. discovery. EnableDiscoveryClient ;
import org. springframework. cloud. openfeign. EnableFeignClients ;
import springfox. documentation. swagger2. annotations. EnableSwagger2 ;
@EnableFeignClients ( basePackages = "com.xk" )
@EnableDiscoveryClient
@SpringBootApplication ( scanBasePackages = { "com.edt.practice" } )
@EnableSwagger2
@EnableApiVersioning
public class ApiApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( ApiApplication . class , args) ;
}
}