In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
It is believed that many inexperienced people do not know what to do about how to realize the practice of multi-data source integration in SpringBoot+Mybatis plus. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.
The version of SpringBoot is 1.5.10.RELEASEJ Mybatis plus is 2.1.8.
Step 1: fill in the configuration information: spring: aop: proxy-target-class: true auto: druid: # Database 1 db1: url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true username: root password: root driver-class-name: com.mysql.jdbc.Driver initialSize: 5 minIdle: 5 maxActive: 20 # Database 2 db2: url: jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true username: root password: root driver-class-name: com.mysql.jdbc.Driver initialSize: 5 minIdle: 5 maxActive: 20 step 2: data source configuration: @ Configuration@MapperScan ({"com.warm.system.mapper*"}) public class MybatisPlusConfig { / * mybatis-plus paging plug-in
* documentation: http://mp.baomidou.com
* / @ Bean public PaginationInterceptor paginationInterceptor () {PaginationInterceptor paginationInterceptor = new PaginationInterceptor (); / / paginationInterceptor.setLocalPage (true); / / enable return paginationInterceptor;} / * mybatis-plus SQL execution efficiency plugin for PageHelper [production environment can be closed] * / @ Bean public PerformanceInterceptor performanceInterceptor () {return new PerformanceInterceptor () } @ Bean (name = "db1") @ ConfigurationProperties (prefix = "spring.datasource.druid.db1") public DataSource db1 () {return DruidDataSourceBuilder.create () .build ();} @ Bean (name = "db2") @ ConfigurationProperties (prefix = "spring.datasource.druid.db2") public DataSource db2 () {return DruidDataSourceBuilder.create () .build () } / * * dynamic data source configuration * @ return * / @ Bean @ Primary public DataSource multipleDataSource (@ Qualifier ("db1") DataSource db1, @ Qualifier ("db2") DataSource db2) {DynamicDataSource dynamicDataSource = new DynamicDataSource (); Map
< Object, Object >TargetDataSources = new HashMap (); targetDataSources.put (DBTypeEnum.db1.getValue (), db1); targetDataSources.put (DBTypeEnum.db2.getValue (), db2); dynamicDataSource.setTargetDataSources (targetDataSources); dynamicDataSource.setDefaultTargetDataSource (db1); return dynamicDataSource;} @ Bean ("sqlSessionFactory") public SqlSessionFactory sqlSessionFactory () throws Exception {MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean (); sqlSessionFactory.setDataSource (multipleDataSource (db1 (), db2 () / / sqlSessionFactory.setMapperLocations (new PathMatchingResourcePatternResolver (). GetResources ("classpath:/mapper/*/*Mapper.xml")); MybatisConfiguration configuration = new MybatisConfiguration (); / / configuration.setDefaultScriptingLanguage (MybatisXMLLanguageDriver.class); configuration.setJdbcTypeForNull (JdbcType.NULL); configuration.setMapUnderscoreToCamelCase (true); configuration.setCacheEnabled (false); sqlSessionFactory.setConfiguration (configuration) SqlSessionFactory.setPlugins (new Interceptor [] {/ / PerformanceInterceptor (), OptimisticLockerInterceptor () paginationInterceptor () / / add paging function}); sqlSessionFactory.setGlobalConfig (globalConfiguration ()); return sqlSessionFactory.getObject ();} @ Bean public GlobalConfiguration globalConfiguration () {GlobalConfiguration conf = new GlobalConfiguration (new LogicSqlInjector ()); conf.setLogicDeleteValue ("- 1"); conf.setLogicNotDeleteValue ("1") Conf.setIdType (0); conf.setMetaObjectHandler (new MyMetaObjectHandler ()); conf.setDbColumnUnderline (true); conf.setRefresh (true); return conf }} step 3: use AOP to dynamically switch data sources: @ Component@Aspect@Order (- 100) / / this is to ensure that AOP takes effect before transaction annotations. The lower the value of Order, the higher the priority @ Slf4jpublic class DataSourceSwitchAspect {@ Pointcut ("execution (* com.warm.system.service.db1..*.* (..)"). Private void db1Aspect () {} @ Pointcut ("execution (* com.warm.system.service.db2..*.* (..)") Private void db2Aspect () {} @ Before ("db1Aspect ()") public void db1 () {log.info ("switch to db1 data source..."); DbContextHolder.setDbType (DBTypeEnum.db1);} @ Before ("db2Aspect ()") public void db2 () {log.info ("switch to db2 data source..."); DbContextHolder.setDbType (DBTypeEnum.db2) }} public class DbContextHolder {private static final ThreadLocal contextHolder = new ThreadLocal (); / * set the data source * @ param dbTypeEnum * / public static void setDbType (DBTypeEnum dbTypeEnum) {contextHolder.set (dbTypeEnum.getValue ());} / * get the current data source * @ return * / public static String getDbType () {return (String) contextHolder.get () } / * clear context data * / public static void clearDbType () {contextHolder.remove ();}} public enum DBTypeEnum {db1 ("db1"), db2 ("db2"); private String value; DBTypeEnum (String value) {this.value = value;} public String getValue () {return value }} public class DynamicDataSource extends AbstractRoutingDataSource {/ * get which data source is currently used * @ return * / @ Override protected Object determineCurrentLookupKey () {return DbContextHolder.getDbType ();}}
OK! Write a unit test to verify:
@ SpringBootTest@RunWith (SpringJUnit4ClassRunner.class) public class DataTest {@ Autowired private UserService userService; @ Autowired private OrderService orderService; @ Test public void test () {userService.getUserList () .stream () .forEach (item-> System.out.println (item)); orderService.getOrderList () .stream () .forEach (item-> System.out.println (item));}}
As shown in the figure, it is proved that the data source can be switched dynamically.
Refer to Github for specific project structure and code.
Trampling record:
The service method AOP that calls Mybatis plus directly will not take effect, that is, the data source will not be switched dynamically. The solution: wrap it in your own service layer and call the custom service method AOP to take effect normally, as shown below:
@ Servicepublic class UserServiceImpl extends ServiceImpl implements UserService {@ Override public List getUserList () {return selectList (null);}}
The mybatis plus configuration information defined by application.yml does not take effect, such as:
# MyBatismybatis-plus: mapper-locations: classpath:/mapper/*/*Mapper.xml # entity scan, with multiple package separated by commas or semicolons: com.jinhuatuo.edu.sys.entity global-config: # Primary key type 0: "Database ID self-increment", 1: "user input ID", 2: "globally unique ID (number type unique ID)", 3: "globally unique ID UUID" Id-type: 0 # field policy 0: "ignore judgment", 1: "non-NULL judgment") 2: "non-null judgment" field-strategy: 2 # Hump underline conversion db-column-underline: true # Refresh mapper Debug artifact refresh-mapper: true # Database uppercase underline conversion # capital-mode: true # sequence Interface implementation Class configuration # key-generator: com.baomidou.springboot.xxx # logical deletion configuration # logic-delete-value: 0 # Logic-not-delete-value: 1 # Custom filling Policy API implementation meta-object-handler: com.jinhuatuo.edu.config.mybatis.MyMetaObjectHandler # Custom SQL injector # sql-injector: com.baomidou.springboot.xxx configuration: map-underscore-to-camel-case: true cache-enabled: false
Solution: all these configurations are configured in code in the MybatisPlusConfig class, as is the case with the paging plug-in, otherwise the data for the total number of statistical lists will not be available, just refer to the code.
Configure in application.yml
Logging: level: debug
The console will not print the SQL statements executed by Mybatis. The solution is to customize the log output scheme, such as directly introducing log configuration files such as logback-spring.xml under classpath, while application.yml no longer needs to configure log information.
Logback-spring.xml configuration reference:
True [%-5level] [% date {yyyy-MM-dd HH:mm:ss}]% logger {96} [% line] -% msg%n utf-8 ${LOG_HOME} / ${PROJECT_NAME} -% d {yyyy-MM-dd}.% i.log 50 MB 30 true [%-5level] [% date {yyyy-MM-dd HH:mm:ss}]% logger {96} [% line] -% msg%n utf-8 ${LOG_HOME} / ${PROJECT_NAME}-error-%d {yyyy-MM-dd}.% i.log 50 MB 30 ERROR [ %-5level] [% date {yyyy-MM-dd HH:mm:ss}]% logger {96} [% line] -% msg%n After reading the above content Have you mastered how SpringBoot+Mybatis plus implements the practice of multi-source integration? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.