之前在项目中用到了sharding-proxy作为分表中间件,就顺便去看了下sharding-jdbc怎么结合在项目中使用
使用的版本为
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>4.0.0-RC3</version>
</dependency>
这边是结合mybatis使用的sharding。
首先在properties中配置相应的数据源信息
spring.datasource.wjw.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.wjw.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.wjw.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
spring.datasource.wjw.username=root
spring.datasource.wjw.password=1754
spring.datasource.wjw.initial-size=10
spring.datasource.wjw.max-active=100
spring.datasource.wjw.min-idle=10
spring.datasource.wjw.max-wait=60000
spring.datasource.wjw.pool-prepared-statements=true
spring.datasource.wjw.max-pool-prepared-statement-per-connection-size=20
spring.datasource.wjw.time-between-eviction-runs-millis=60000
spring.datasource.wjw.min-evictable-idle-time-millis=300000
spring.datasource.wjw.validation-query=SELECT 1 FROM DUAL
接着使用java配置数据源,引入sharding
@Configuration
//扫描接口文件
@MapperScan(basePackages = "com.example.demo.mapper.wjw", sqlSessionTemplateRef = "wjwSqlSessionTemplate")
public class WjwDataSourceConfig {
@ConfigurationProperties(prefix = "spring.datasource.wjw")
@Bean(name = "wjwDataSource")
@Primary
public DruidDataSource druidDataSource(){
return new DruidDataSource();
}
//配置sql会话工厂
@Bean(name = "wjwSqlSessionTemplate")
@Primary
public SqlSessionTemplate setSqlSessionTemplate(@Qualifier("wjwSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
sharding的配置
@Configuration
public class ShardJdbcConfig {
/**
* JDBC操作配置
*/
@Bean(name = "dataOneTemplate")
public JdbcTemplate dataOneTemplate(@Autowired DruidDataSource dataOneSource) {
return new JdbcTemplate(dataOneSource);
}
/**
* Shard-JDBC 配置
*/
@Bean(name = "shardingwjw")
public DataSource createDataSourceMap(@Autowired WjwDataSourceConfig wjwDataSourceConfig) throws Exception {
ShardingRuleConfiguration shardJdbcConfig = new ShardingRuleConfiguration();
//配置分片规则中的 ->表规则getTableRule01
shardJdbcConfig.getTableRuleConfigs().add(getTableRule01());
shardJdbcConfig.setDefaultDataSourceName("test");
//设置分库规则
// shardJdbcConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("id","test.table_one${1..2}"));
//设置默认分表规则
// shardJdbcConfig.setDefaultTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "table_one${id % 3}"));
shardJdbcConfig.setDefaultTableShardingStrategyConfig(new ComplexShardingStrategyConfiguration("id",new ComplexSharding()));
Map<String, DataSource> dataMap = new LinkedHashMap<>();
dataMap.put("test", wjwDataSourceConfig.druidDataSource());
//3、属性配置项,可以为以下属性
Properties propertie = new Properties();
//是否打印SQL解析和改写日志
propertie.setProperty("sql.show", Boolean.TRUE.toString());
//用于SQL执行的工作线程数量,为零则表示无限制
propertie.setProperty("executor.size", "4");
//每个物理数据库为每次查询分配的最大连接数量
propertie.setProperty("max.connections.size.per.query", "1");
//是否在启动时检查分表元数据一致性
propertie.setProperty("check.table.metadata.enabled", "false");
//dataMap为数据源
return ShardingDataSourceFactory.createDataSource(dataMap, shardJdbcConfig, propertie);
}
/**
* Shard-JDBC 分表配置
*/
private static TableRuleConfiguration getTableRule01() {
// 配置表规则。需要划分的表
TableRuleConfiguration tableRuleConfiguration = new TableRuleConfiguration("table_one","test.table_one0,test.table_one1,test.table_one2");
tableRuleConfiguration.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id"));
// tableRuleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "test.table_one${id % 2}"));
//关系到表名 test.table_one${id % 2} $取值运算,计算ID模二的值 为实际表名
// tableRuleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "test.table_one${id % 3}"));
tableRuleConfiguration.setTableShardingStrategyConfig(new ComplexShardingStrategyConfiguration("id,phone",new ComplexSharding()));
return tableRuleConfiguration;
}
//配置bean工厂并扫描xml文件
@Bean(name = "wjwSqlSessionFactory")
@Primary
public SqlSessionFactory setSqlSessionFactory(@Qualifier("shardingwjw") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:sumMapper/wjwMapper/*.xml"));
return bean.getObject();
}
//配置事务
@Bean(name = "wjwTransactionManager")
@Primary
public DataSourceTransactionManager setTransactionMapper(@Qualifier("shardingwjw") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
复合分片策略的配置
public class ComplexSharding implements ComplexKeysShardingAlgorithm<String> {
@Override
public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<String> shardingValue) {
//获取= in 键的值
Map<String, Collection<String>> map= shardingValue.getColumnNameAndShardingValuesMap();
//获取范围 4.0.0-RC3才有这个方法,之前用4.0.0-RC1的时候一直获取不到范围
Map<String, Range<String>> rangeMap = shardingValue.getColumnNameAndRangeValuesMap();
Set<String> settable=new HashSet<>();
System.out.println("map="+map);
System.out.println("rangeMap="+rangeMap);
System.out.println("collection="+collection);
return settable;
}
这边只是进行一个简单的demo,具体使用,需要根据场景的具体需求。
使用一项新技术时,可能需要进行一些源码的查看,看看引用方法需要使用哪些类,还需要注意版本的更替问题。
不懂版本也会有一些差异,我并不知道之前4.0.0-RC1是如何获取范围值的,但我对比了下我使用proxy时的版本为4.0.0-RC3,就替换了过来,也解决了我所遇到的问题。
最后共同进步,有不足的地方望指出!!!
查找资料所得:
4.0.0-RC3,作为ShardingSphere进入Apache基金会后发布的第三个版本,做了以下调整。
新功能
-
ShardingSphere治理管控平台 Sharding-UI 正式上线。
-
除支持MySQL,Oracle,SQLServer,PostgreSQL等数据库SQL语法外,还支持使用遵循SQL92标准的SQL语法。
增强
-
支持使用 “>” ,"<" ,">=" ,"<=" 符号进行分片数据查询。
-
在读写分离的场景下,SELECT FOR UPDATE 语句路由至主数据源。
-
支持在Sharding-Proxy端使用Hint。
-
完成对MySQL的DAL语法的解析。
-
Sharding-JDBC和Sharding-Proxy的治理配置信息兼容优化。