Compare commits
1 Commits
main
...
separationdemo
Author | SHA1 | Date |
---|---|---|
dearlin | caf33a8743 |
|
@ -2,6 +2,7 @@ package com.zcloud.config;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zcloud.plugins.DynamicDataSource;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
|
@ -16,6 +17,9 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
|||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 说明:第一数据源配置
|
||||
* 作者:luoxiaobao
|
||||
|
@ -29,21 +33,31 @@ public class MasterDataSourceConfig {
|
|||
static final String MAPPER_LOCATION = "classpath:mybatis/datasource/*/*.xml"; //扫描的 xml 目录
|
||||
static final String CONFIG_LOCATION = "classpath:mybatis/datasource/mybatis-config.xml"; //自定义的mybatis config 文件位置
|
||||
static final String TYPE_ALIASES_PACKAGE = "com.zcloud.entity"; //扫描的 实体类 目录
|
||||
|
||||
|
||||
@Value("${datasource.no1.url}")
|
||||
private String url;
|
||||
|
||||
|
||||
@Value("${datasource.no1.username}")
|
||||
private String user;
|
||||
|
||||
|
||||
@Value("${datasource.no1.password}")
|
||||
private String password;
|
||||
|
||||
|
||||
@Value("${datasource.no1.driver-class-name}")
|
||||
private String driverClass;
|
||||
|
||||
|
||||
|
||||
|
||||
@Value("${datasource.slave.no1.driver-class-name}")
|
||||
private String no1DataSourceSlaveDriver;
|
||||
@Value("${datasource.slave.no1.url}")
|
||||
private String no1DataSourceSlaveUrl;
|
||||
@Value("${datasource.slave.no1.username}")
|
||||
private String no1DataSourceSlaveUser;
|
||||
@Value("${datasource.slave.no1.password}")
|
||||
private String no1DataSourceSlavePassword;
|
||||
|
||||
@Bean(name = "masterDataSource")
|
||||
@Primary
|
||||
public DataSource masterDataSource() {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(driverClass);
|
||||
|
@ -52,18 +66,37 @@ public class MasterDataSourceConfig {
|
|||
dataSource.setPassword(password);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean(name = "masterDataSourceSlave")
|
||||
public DataSource masterDataSourceSlave() {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(no1DataSourceSlaveDriver);
|
||||
dataSource.setUrl(no1DataSourceSlaveUrl);
|
||||
dataSource.setUsername(no1DataSourceSlaveUser);
|
||||
dataSource.setPassword(no1DataSourceSlavePassword);
|
||||
return dataSource;
|
||||
}
|
||||
@Bean(name = "masterTransactionManager")
|
||||
@Primary
|
||||
public DataSourceTransactionManager masterTransactionManager() {
|
||||
return new DataSourceTransactionManager(masterDataSource());
|
||||
}
|
||||
|
||||
@Bean(name = "dynamicDataSourceNo1")
|
||||
public DataSource dynamicDataSource(
|
||||
@Qualifier("masterDataSource") DataSource masterDataSource,
|
||||
@Qualifier("masterDataSourceSlave") DataSource masterDataSourceSlave) {
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
Map<Object, Object> dataSourceMap = new HashMap<>();
|
||||
dataSourceMap.put("no1DataSource", masterDataSource);
|
||||
dataSourceMap.put("no1DataSourceSlave", masterDataSourceSlave);
|
||||
dynamicDataSource.setTargetDataSources(dataSourceMap);
|
||||
dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
|
||||
return dynamicDataSource;
|
||||
}
|
||||
@Bean(name = "masterSqlSessionFactory")
|
||||
@Primary
|
||||
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)throws Exception {
|
||||
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("dynamicDataSourceNo1") DataSource dynamicDataSource)throws Exception {
|
||||
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
|
||||
sessionFactory.setDataSource(masterDataSource);
|
||||
sessionFactory.setDataSource(dynamicDataSource);
|
||||
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MasterDataSourceConfig.MAPPER_LOCATION));
|
||||
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(MasterDataSourceConfig.CONFIG_LOCATION));
|
||||
sessionFactory.setTypeAliasesPackage(MasterDataSourceConfig.TYPE_ALIASES_PACKAGE);
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.zcloud.config;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zcloud.plugins.DynamicDataSource;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
|
@ -15,6 +16,9 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
|||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 说明:第二数据源配置
|
||||
* 作者:luoxiaobao
|
||||
|
@ -28,19 +32,27 @@ public class No2DataSourceConfig {
|
|||
static final String MAPPER_LOCATION = "classpath:mybatis/dsno2/*/*.xml"; //扫描的 xml 目录
|
||||
static final String CONFIG_LOCATION = "classpath:mybatis/dsno2/mybatis-config.xml"; //自定义的mybatis config 文件位置
|
||||
static final String TYPE_ALIASES_PACKAGE = "ocom.zcloud.entity"; //扫描的 实体类 目录
|
||||
|
||||
|
||||
@Value("${datasource.no2.url}")
|
||||
private String url;
|
||||
|
||||
|
||||
@Value("${datasource.no2.username}")
|
||||
private String user;
|
||||
|
||||
|
||||
@Value("${datasource.no2.password}")
|
||||
private String password;
|
||||
|
||||
|
||||
@Value("${datasource.no2.driver-class-name}")
|
||||
private String driverClass;
|
||||
|
||||
@Value("${datasource.slave.no2.driver-class-name}")
|
||||
private String no2DataSourceSlaveDriver;
|
||||
@Value("${datasource.slave.no2.url}")
|
||||
private String no2DataSourceSlaveUrl;
|
||||
@Value("${datasource.slave.no2.username}")
|
||||
private String no2DataSourceSlaveUser;
|
||||
@Value("${datasource.slave.no2.password}")
|
||||
private String no2DataSourceSlavePassword;
|
||||
|
||||
@Bean(name = "no2DataSource")
|
||||
public DataSource no2DataSource() {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
|
@ -50,19 +62,41 @@ public class No2DataSourceConfig {
|
|||
dataSource.setPassword(password);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@Bean(name = "no2DataSourceSlave")
|
||||
public DataSource no2DataSourceSlave() {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(no2DataSourceSlaveDriver);
|
||||
dataSource.setUrl(no2DataSourceSlaveUrl);
|
||||
dataSource.setUsername(no2DataSourceSlaveUser);
|
||||
dataSource.setPassword(no2DataSourceSlavePassword);
|
||||
return dataSource;
|
||||
}
|
||||
@Bean(name = "no2TransactionManager")
|
||||
public DataSourceTransactionManager no2TransactionManager() {
|
||||
return new DataSourceTransactionManager(no2DataSource());
|
||||
}
|
||||
|
||||
@Bean(name = "dynamicDataSourceNo2")
|
||||
public DataSource dynamicDataSource(
|
||||
@Qualifier("no2DataSource") DataSource no2DataSource,
|
||||
@Qualifier("no2DataSourceSlave") DataSource no2DataSourceSlave) {
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
Map<Object, Object> dataSourceMap = new HashMap<>();
|
||||
dataSourceMap.put("no2DataSource", no2DataSource);
|
||||
dataSourceMap.put("no2DataSourceSlave", no2DataSourceSlave);
|
||||
dynamicDataSource.setTargetDataSources(dataSourceMap);
|
||||
dynamicDataSource.setDefaultTargetDataSource(no2DataSource);
|
||||
return dynamicDataSource;
|
||||
}
|
||||
@Bean(name = "no2SqlSessionFactory")
|
||||
public SqlSessionFactory no2SqlSessionFactory(@Qualifier("no2DataSource") DataSource no2DataSource)throws Exception {
|
||||
public SqlSessionFactory no2SqlSessionFactory(@Qualifier("dynamicDataSourceNo2") DataSource dynamicDataSource)throws Exception {
|
||||
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
|
||||
sessionFactory.setDataSource(no2DataSource);
|
||||
sessionFactory.setDataSource(dynamicDataSource);
|
||||
// sessionFactory.setPlugins(new Interceptor[]{new SeparationN2Plugin()});
|
||||
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(No2DataSourceConfig.MAPPER_LOCATION));
|
||||
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(No2DataSourceConfig.CONFIG_LOCATION));
|
||||
sessionFactory.setTypeAliasesPackage(No2DataSourceConfig.TYPE_ALIASES_PACKAGE);
|
||||
return sessionFactory.getObject();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.zcloud.plugins;
|
||||
|
||||
/**
|
||||
* 说明:TODO
|
||||
* 作者:wangxuan
|
||||
* 官网:www.zcloudchina.com
|
||||
*/
|
||||
public class DataSourceContextHolder {
|
||||
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
|
||||
|
||||
public static void setDataSourceType(String dataSourceType) {
|
||||
contextHolder.set(dataSourceType);
|
||||
}
|
||||
|
||||
public static String getDataSourceType() {
|
||||
return contextHolder.get();
|
||||
}
|
||||
|
||||
public static void clearDataSourceType() {
|
||||
contextHolder.remove();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.zcloud.plugins;
|
||||
|
||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||
|
||||
/**
|
||||
* 说明:动态数据源
|
||||
* 作者:wangxuan
|
||||
* 官网:www.zcloudchina.com
|
||||
*/
|
||||
public class DynamicDataSource extends AbstractRoutingDataSource {
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey() {
|
||||
return DataSourceContextHolder.getDataSourceType();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.zcloud.plugins;
|
||||
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlCommandType;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 说明:分页插件
|
||||
* 作者:luoxiaobao
|
||||
* 官网:www.qdkjchina.com
|
||||
*/
|
||||
@Intercepts(
|
||||
{
|
||||
// @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
|
||||
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
|
||||
})
|
||||
public class SeparationN1Plugin implements Interceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
// if (invocation.getMethod().getName().equals("prepare")) {
|
||||
// StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
|
||||
// MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
|
||||
// MappedStatement ms = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
||||
// SqlCommandType sqlCommandType = ms.getSqlCommandType();
|
||||
// if (sqlCommandType == SqlCommandType.SELECT) {
|
||||
// DataSourceContextHolder.setDataSourceType("no2DataSourceSlave");
|
||||
// }
|
||||
// }
|
||||
if (invocation.getMethod().getName().equals("query")) {
|
||||
boolean isReadOnly = isReadOnlySql(invocation.getArgs());
|
||||
if (isReadOnly) {
|
||||
DataSourceContextHolder.setDataSourceType("no1DataSourceSlave");
|
||||
} else {
|
||||
DataSourceContextHolder.setDataSourceType("no1DataSource");
|
||||
}
|
||||
}
|
||||
// return invocation.proceed();
|
||||
// boolean isReadOnly = isReadOnlySql(invocation.getArgs());
|
||||
// if (isReadOnly) {
|
||||
// DataSourceContextHolder.setDataSourceType("no2DataSourceSlave");
|
||||
// } else {
|
||||
// DataSourceContextHolder.setDataSourceType("no2DataSource");
|
||||
// }
|
||||
try {
|
||||
return invocation.proceed();
|
||||
} finally {
|
||||
DataSourceContextHolder.clearDataSourceType();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isReadOnlySql(Object[] args) {
|
||||
// 获取 SQL 语句
|
||||
MappedStatement ms = (MappedStatement) args[0];
|
||||
SqlCommandType sqlCommandType = ms.getSqlCommandType();
|
||||
// 判断是否为查询操作
|
||||
return sqlCommandType == SqlCommandType.SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.zcloud.plugins;
|
||||
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.executor.statement.StatementHandler;
|
||||
import org.apache.ibatis.mapping.*;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.reflection.DefaultReflectorFactory;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.apache.ibatis.reflection.SystemMetaObject;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 说明:分页插件
|
||||
* 作者:luoxiaobao
|
||||
* 官网:www.qdkjchina.com
|
||||
*/
|
||||
@Intercepts(
|
||||
{
|
||||
// @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
|
||||
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
|
||||
})
|
||||
public class SeparationN2Plugin implements Interceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public Object intercept(Invocation invocation) throws Throwable {
|
||||
// if (invocation.getMethod().getName().equals("prepare")) {
|
||||
// StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
|
||||
// MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
|
||||
// MappedStatement ms = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
||||
// SqlCommandType sqlCommandType = ms.getSqlCommandType();
|
||||
// if (sqlCommandType == SqlCommandType.SELECT) {
|
||||
// DataSourceContextHolder.setDataSourceType("no2DataSourceSlave");
|
||||
// }
|
||||
// }
|
||||
if (invocation.getMethod().getName().equals("query")) {
|
||||
boolean isReadOnly = isReadOnlySql(invocation.getArgs());
|
||||
if (isReadOnly) {
|
||||
DataSourceContextHolder.setDataSourceType("no2DataSourceSlave");
|
||||
} else {
|
||||
DataSourceContextHolder.setDataSourceType("no2DataSource");
|
||||
}
|
||||
}
|
||||
// return invocation.proceed();
|
||||
// boolean isReadOnly = isReadOnlySql(invocation.getArgs());
|
||||
// if (isReadOnly) {
|
||||
// DataSourceContextHolder.setDataSourceType("no2DataSourceSlave");
|
||||
// } else {
|
||||
// DataSourceContextHolder.setDataSourceType("no2DataSource");
|
||||
// }
|
||||
try {
|
||||
return invocation.proceed();
|
||||
} finally {
|
||||
DataSourceContextHolder.clearDataSourceType();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isReadOnlySql(Object[] args) {
|
||||
// 获取 SQL 语句
|
||||
MappedStatement ms = (MappedStatement) args[0];
|
||||
SqlCommandType sqlCommandType = ms.getSqlCommandType();
|
||||
// 判断是否为查询操作
|
||||
return sqlCommandType == SqlCommandType.SELECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
|
||||
#主库
|
||||
datasource.no1.driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
datasource.no1.url=jdbc:mysql://39.101.130.96:33068/qa-gwj-prevention?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8
|
||||
datasource.no1.username=root
|
||||
|
@ -8,6 +7,16 @@ datasource.no2.driver-class-name: com.mysql.cj.jdbc.Driver
|
|||
datasource.no2.url=jdbc:mysql://39.101.130.96:33068/qa-gwj-regulatory?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8
|
||||
datasource.no2.username=root
|
||||
datasource.no2.password=Mysql@zcloud88888
|
||||
#从库
|
||||
datasource.slave.no1.driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
datasource.slave.no1.url=jdbc:mysql://192.168.0.17:3306/qa-gwj-prevention?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8
|
||||
datasource.slave.no1.username=root
|
||||
datasource.slave.no1.password=root
|
||||
datasource.slave.no2.driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
datasource.slave.no2.url=jdbc:mysql://192.168.0.17:3306/qa-gwj-regulatory?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf-8
|
||||
datasource.slave.no2.username=root
|
||||
datasource.slave.no2.password=root
|
||||
|
||||
|
||||
|
||||
#druid???
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
|
||||
|
@ -11,17 +11,18 @@
|
|||
<typeAlias type="com.zcloud.entity.system.Role" alias="role"/>
|
||||
<typeAlias type="com.zcloud.entity.system.Dictionaries" alias="dictionaries"/>
|
||||
<typeAlias type="com.zcloud.entity.system.Department" alias="Department"/>
|
||||
|
||||
|
||||
<!-- 这里添加实体类 -->
|
||||
|
||||
|
||||
</typeAliases>
|
||||
|
||||
|
||||
<plugins>
|
||||
<plugin interceptor="com.zcloud.plugins.SeparationN1Plugin"/>
|
||||
<plugin interceptor="com.zcloud.plugins.PagePlugin">
|
||||
<property name="dialect" value="mysql"/>
|
||||
<property name="pageSqlId" value=".*listPage.*"/>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
|
||||
</configuration>
|
||||
|
||||
|
||||
</configuration>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
|
||||
|
@ -10,16 +10,18 @@
|
|||
<typeAlias type="com.zcloud.entity.system.Menu" alias="menu"/>
|
||||
<typeAlias type="com.zcloud.entity.system.Role" alias="role"/>
|
||||
<typeAlias type="com.zcloud.entity.system.Dictionaries" alias="dictionaries"/>
|
||||
|
||||
|
||||
<!-- 这里添加实体类 -->
|
||||
|
||||
|
||||
</typeAliases>
|
||||
|
||||
|
||||
<plugins>
|
||||
<plugin interceptor="com.zcloud.plugins.SeparationN2Plugin"/>
|
||||
|
||||
<plugin interceptor="com.zcloud.plugins.PagePlugin">
|
||||
<property name="dialect" value="mysql"/>
|
||||
<property name="pageSqlId" value=".*listPage.*"/>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</configuration>
|
||||
|
||||
</configuration>
|
||||
|
|
Loading…
Reference in New Issue