MybatisPlus的IPage失效的问题解决方案

网友投稿 970 2022-11-06


MybatisPlus的IPage失效的问题解决方案

背景

之前做数据抽取的时候,搭了一个mybatis动态数据源切换的架子。方便他们写抽取的代码。今天同事问我,架子里面的mybatisplus的IPage失效了是什么问题。想了一下,应该是写动态数据源的时候,我自定义的mybatis的配置覆盖了已有的配置。于是我让他先把我写的配置进行删除,看是否正常。得到回复,删除后正常。那么到此问题原因找到,接下来的解决方法,只要在配置中增加分页器即可。

解决方案

建立一个分页器的bean配置

@Bean

public PaginationInterceptor paginationInterceptor() {

return new PaginationInterceptor();

}

我们随便自定义一个类即可,这里主要是将这个类作为一个bean交给spring容器管理。

在sqlSessionFactory中注入

@Bean(name="sessionFactory")

public SqlSessionFactory sessionFactory(

@Qualifier("bigDataDataSource") DataSource bigDataDataSource,

@Qualifier("branchDataSource") DataSource branchDataSource,

@Qualifier("basicDataSource") DataSource basicDataSource,

org.apache.ibatis.session.Configuration config) throws Exception{

SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();

//构造方法,解决动态数据源循环依赖问题。

MybatisConfiguration configuration = new MybatisConfiguration();

configuration.addInterceptor(new PaginationInterceptor());

sessionFactoryBean.setConfiguration(configuration);

sessionFactoryBean.setConfiguration(config);

sessionFactoryBean.setDataSource(this.DataSource(bigDataDataSource,branchDataSource, basicDataSource));

return sessionFactoryBean.getObject();

}

文中总结

至此,我们的mybatisplus的分页插件就好使了。下面给大家提供MyBatis多数据源的解决方案。

动态数据源解决方案

数据库配置文件

我们项目使用的是yml形式的配置文件,采用的是hikari的数据库连接池。第一步我们自然是配置多个数据库源头。

我们找到spring的datasource,在下方配置三个数据源。

spring:

application:

name: dynamicDatasource

datasource:

test1:

driver-class-name: com.mysql.jdbc.Driver

url: jdbc:mysql://127.0.0.1:3306/test1?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

username: root

password: 123456

test2:

driver-class-name: com.mysql.jdbc.Driver

url: jdbc:mysql://127.0.0.1:3306/test2?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

username: root

password: 123456

test3:

driver-class-name: com.mysql.jdbc.Driver

url: jdbc:mysql://127.0.0.1:3306/test3?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

username: root

password: 123456

hikari:

leak-detection-threshold: 2000

定义数据源实体类

我们可以建立个datasourceBean文件夹专门管理数据源的实体类。

我们这里要建立三个实体类。分别对应test1,test2,test3

@Configuration

public class Test1DataSourceBean {

@Value("${spring.datasource.test1.driver-class-name}")

private String test1Driver;

@Value("${spring.datasource.test1.url}")

private String test1Url;

@Value("http://${spring.datasource.test1.username}")

private String test1Username;

@Value("${spring.datasource.test1.password}")

private String test1Password;

@Bean(name="test1DataSource")

public DataSource test1DataSource() throws Exception{

HikariDataSource dataSource = new HikariDataSource();

dataSource.setDriverClassName(test1Driver);

dataSource.setJdbcUrl(test1Url);

dataSource.setUsername(test1Username);

dataSource.setPassword(test1Password);

return dataSource;

}

}

@Configuration

public class Test2DataSourceBean {

@Value("${spring.datasource.test2.driver-class-name}")

private String test2Driver;

@Value("${spring.datasource.test2.url}")

private String test2Url;

@Value("${spring.datasource.test2.username}")

private String test2Username;

@Value("${spring.datasource.test2.password}")

private String test2Password;

@Bean(name="test2DataSource")

public DataSource test2DataSource() throws Exception{

HikariDataSource dataSource = new HikariDataSource();

dataSource.setDriverClassName(test2Driver);

dataSource.setJdbcUrl(test2Url);

dataSource.setUsername(test2Username);

dataSource.setPassword(test2Password);

return dataSource;

}

}

@Configuration

public class Test3DataSourceBean {

@Value("${spring.datasource.test3.driver-class-name}")

private String test3Driver;

@Value("${spring.datasource.test3.url}")

private String test3Url;

@Value("${spring.datasource.test3.username}")

private String test3Username;

@Value("${spring.datasource.test3.password}")

private String test3Password;

@Bean(name="test3DataSource")

public DataSource test3DataSource() throws Exception{

HikariDataSource dataSource = new HikariDataSource();

dataSource.setDriverClassName(test3Driver);

dataSource.setJdbcUrl(test3Url);

dataSource.setUsername(test3Username);

dataSource.setPassword(test3Password);

return dataSource;

}

}

定义一个枚举类管理数据源

public enum DatabaseType {

test1("test1", "test1"),

test2("test2", "test2"),

test3("test3","test3");

private String name;

private String value;

DatabaseType(String name, String value){

this.name = name;

this.value = value;

}

public String getName(){

return name;

}

public String getValue(){

return value;

}

}

定义一个线程安全的数据源容器

public class DatabaseContextHolder {

private static final ThreadLocal contextHolder = new ThreadLocal<>();

public static void setDatabaseType(DatabaseType type){

contextHolder.set(type);

}

public static DatabaseType getDatabaseType(){

return contextHolder.get();

}

}

定义动态数据源

public class DynamicDataSource extends AbstractRoutingDataSource{

protected Object determineCurrentLookupKey() {

return DatabaseContextHolder.getDatabaseType();

}

}

mybatis配置类

网上的很多文章配置出来都会产生数据源循环依赖的问题,这里解决了这个问题。

@Configuration

@MapperScan(basePackages="cn.test.jichi", sqlSessionFactoryRef="sessionFactory")

public class MybatisConfig {

/**

* @Description:设置动态数据源

*/

@Bean(name="dynamicDataSource")

@Primary

public DynamicDataSource DataSource(

@Qualifier("test1DataSource") DataSHCWXzduZoource test1DataSource,

@Qualifier("test2DataSource") DataSource test2DataSource,

@Qualifier("test3DataSource") DataSource test3DataSource){

Map targetDataSource = new HashMap<>();

targetDataSource.put(DatabaseType.test1, test1DataSource);

targetDataSource.put(DatabaseType.test2, test2DataSource);

targetDataSource.put(DatabaseType.test3, test3DataSource);

DynamicDataSource dataSource = new DynamicDataSource();

dataSource.setTargetDataSources(targetDataSource);

dataSource.setDefaultTargetDataSource(test1DataSource);

return dataSource;

}

/**

* @Description:根据动态数据源创建sessionFactory

*/

@Bean(name="sessionFactory")

public SqlSessionFactory sessionFactory(

@Qualifier("test1DataSource") DataSource test1DataSource,

@Qualifier("test2DataSource") DataSource test2DataSource,

@Qualifier("test3DataSource") DataSource test3DataSource) throws Exception{

SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();

//构造方法,解决动态数据源循环依赖问题。

sessionFactoryBean.setDataSource(this.DataSource(test1DataSource,test2DataSource, test3DataSource));

return sessionFactoryBean.getObject();

}

}

提供一个示例

public void testDymnaicDatasource(){

//不切换数据源默认是自己的。

System.out.println("-----默认数据源");

DemoEntity totalCount = demoMapper.getTotalCount();

String nameCount1 = totalCount.getNameCount();

String ageCount2 = totalCount.getAgeCount();

System.out.println("nameCount:"+nameCount1);

System.out.println("ageCount:"+ageCount2);

//数据源切换为branch

System.out.println("-----数据源为test2");

DynamicDataSourceUtils.chooseBranchDataSource();

Integer nameCount = demoMapper.getNameCount();

Integer ageCount = demoMapper.getAgeCount();

System.out.println("nameCount:"+nameCount);

System.out.println("ageCount:"+ageCount);

//数据源为basic

System.out.println("-----数据源为test3");

DynamicDataSourceUtils.chooseBasicDataSource();

Integer ageCount1 = demoMapper.getAgeCount();

System.out.println("ageCount:"+ageCount1);

}

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:查询号码API(查询号码是114吗)
下一篇:Docker 入门 (2) | 基本命令
相关文章

 发表评论

暂时没有评论,来抢沙发吧~