写点什么

springboot+mybatisPlus+dynamic-datasource-spring-boot-starter+druid 集成 shardingsphere

用户头像
勤~
关注
发布于: 1 小时前
springboot+mybatisPlus+dynamic-datasource-spring-boot-starter+druid集成shardingsphere

##简单实用

概述

最近公司要某业务要实现分表分库,根据目前公司的技术栈进行了选型,选择 shardingsphere,接下来记录下这次集成的过程,希望对需要做这块业务的开发人员有所帮助。

依赖的框架以及版本

实现步骤

1,先添加 shardingsphere 依赖,shardingsphere 的 4.x 版本较之前变化蛮大的。


<dependency>    <groupId>org.apache.shardingsphere</groupId>    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>    <version>4.1.1</version></dependency><!-- for spring namespace --><dependency>    <groupId>org.apache.shardingsphere</groupId>    <artifactId>sharding-jdbc-spring-namespace</artifactId>    <version>4.1.1</version></dependency>
复制代码


2,添加依赖后,接下来新建 DataSourceConfiguration 这个配置类去将这个 shardingsphere 的数据源交给 dynamic-datasource 去维护。


import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;import lombok.extern.slf4j.Slf4j;import org.apache.tomcat.util.buf.StringUtils;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.EnvironmentAware;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.DependsOn;import org.springframework.context.annotation.Primary;import org.springframework.core.env.Environment;import javax.annotation.Resource;import javax.sql.DataSource;import java.util.HashMap;import java.util.Map;
@Configuration@DependsOn("shardingDataSource")@Slf4jpublic class DataSourceConfiguration implements EnvironmentAware {
private final DynamicDataSourceProperties properties;
public DataSourceConfiguration(DynamicDataSourceProperties properties) { this.properties = properties; }
@Resource(name = "shardingDataSource") private DataSource shardingDataSource;
@Value("${spring.shardingsphere.datasource.names:}") private String shardingDataSourceName;
@Bean public DynamicDataSourceProvider dynamicDataSourceProvider() { return new AbstractDataSourceProvider() {
@Override public Map<String, DataSource> loadDataSources() { Map<String, DataSource> dataSourceMap = new HashMap<>(); if (org.springframework.util.StringUtils.isEmpty(shardingDataSourceName)){ return dataSourceMap; } dataSourceMap.put(shardingDataSourceName, shardingDataSource); return dataSourceMap; } }; }
@Primary @Bean public DataSource dataSource() { DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource(); dataSource.setPrimary(properties.getPrimary()); dataSource.setStrict(properties.getStrict()); dataSource.setStrategy(properties.getStrategy()); dataSource.setP6spy(properties.getP6spy()); dataSource.setSeata(properties.getSeata()); return dataSource; }
@Override public void setEnvironment(Environment environment) { log.error(StringUtils.join(environment.getActiveProfiles())); }}
复制代码


3,再接下来,在配置文件中添加如下配置,其中可以看到我们使用 primary 为主数据源,默认的数据库操作都会找这个数据源。其他的分库分表操作走 sharding0 等等数据源即可。之所以这样配置主要是因为老项目介入发表分库业务,不希望影响太大。


#默认数据源spring.datasource.dynamic.primary=primary
#mysql1数据源配置spring.datasource.dynamic.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.dynamic.datasource.primary.url=jdbc:mysql://xxxxx:3306/sample?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=falsespring.datasource.dynamic.datasource.primary.username=xxxxxspring.datasource.dynamic.datasource.primary.password=xxxxx
# 数据源 sharding0spring.shardingsphere.datasource.names=sharding0
# 分库分表数据库spring.shardingsphere.datasource.sharding0.type=com.alibaba.druid.pool.DruidDataSourcespring.shardingsphere.datasource.sharding0.driver-class-name=com.mysql.cj.jdbc.Driverspring.shardingsphere.datasource.sharding0.url=jdbc:mysql://xxxxx:3306/sample?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCspring.shardingsphere.datasource.sharding0.username=xxxxxspring.shardingsphere.datasource.sharding0.password=xxxxxspring.shardingsphere.sharding.tables.book.actual-data-nodes=sharding0.book,sharding0.book_historyspring.shardingsphere.sharding.tables.book.table-strategy.standard.sharding-column=count1spring.shardingsphere.sharding.tables.book.table-strategy.standard.precise-algorithm-class-name=com.diligence.shardingsphere.algoritm.MyPreciseShardingAlgorithmspring.shardingsphere.sharding.binding-tables=book
# 打印执行的数据库以及语句spring.shardingsphere.props..sql.show=truespring.main.allow-bean-definition-overriding=truemybatis-plus.mapper-locations=classpath*:mapper/**/*Mapper.xml
复制代码


4,增加 MyPreciseShardingAlgorithm 分片策略实现分表逻辑。


public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
@Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) { Optional<Integer> shardingValueOpl = Optional.ofNullable(shardingValue.getValue()); if (shardingValueOpl.get()==1) return "book" ; return "book_history"; }}
复制代码


5,增加 ShardDS 方便数据源统一维护。


@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@DS(value = "sharding0")public @interface ShardDS {}
复制代码


6,至此,集成完毕。使用的时候只需要在相应的需要分表分库的数据库操作的地方使用 ShardDS 注解做数据源切换。例如:


@ShardDS@Overridepublic List<SampleResponse> getBookList() {    return sampleMapper.selectSampleList("88888");}
复制代码

异常报错

集成过程中遇到了如下异常:

  1. java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

解决方法:添加上面的 DataSourceConfiguration 类,注入数据源

  1. 有时候会遇到,shardingDataSource 为空

解决办法:在 DataSourceConfiguration 类上添加 @DependsOn("shardingDataSource")

注意事项

简单测试了 shardingsphere,使用上需要注意的地方:

  1. 通过子查询实现业务查询当前并不能支持;

  2. 不要使用 update 去修改分片键,这里可以用 delete 后 insert 代替。

参考

例子代码

shardingsphere对哪些SQL的支持

发布于: 1 小时前阅读数: 6
用户头像

勤~

关注

还未添加个人签名 2018.05.18 加入

还未添加个人简介

评论

发布
暂无评论
springboot+mybatisPlus+dynamic-datasource-spring-boot-starter+druid集成shardingsphere