Spring boot + Mybatis plus + sharding jdbc 4.1.1整合的基本分片Demo使用及踩坑记录

Spring boot + Mybatis plus + sharding jdbc 4.1.1整合的基本分片Demo使用及踩坑记录


该文章仅介绍基础的分表,记录过程中整合的关键点及踩坑点。

1.maven引入及相关踩坑

pom文件中部分关键引用展示:

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <spring-cloud-kubernetes.version>2.0.3</spring-cloud-kubernetes.version>

        <mybatis-plus.version>3.4.3</mybatis-plus.version>
        <druid.version>1.1.21</druid.version>

        <fastdfs.client>1.27.0.0</fastdfs.client>

        <fastjson.version>1.2.47</fastjson.version>
        <logstash-logback-encoder.version>5.2</logstash-logback-encoder.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.sun</groupId>
                    <artifactId>tools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun</groupId>
                    <artifactId>jconsole</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>

踩坑点:Druid数据库连接池,使用以下maven引入时,会报错。

	<dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid-spring-boot-starter</artifactId>
         <version>${druid.version}</version>
    </dependency>

目前具体原因暂不清楚,事实上,使用以上方式进行依赖时,项目也没有报任何编译时的错误,也没有出现maven依赖冲突的问题,但就是无法正常启动项目,会抛出以下异常。

Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
	at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:122) ~[mybatis-spring-2.0.4.jar:2.0.4]
	at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73) ~[mybatis-spring-2.0.4.jar:2.0.4]
	at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	... 43 common frames omitted

该处折磨了很久终于解决,还是在github上出现相同问题的帖子中,底下评论中小小的一段回复中看到后才解决的,因此遇到同样问题的老铁们可以参考以上做法进行maven导入的修改,如果有知道原因的,能告知,也万分感谢。

2.配置文件内容即相关分片策略类

spring:
  main:
    allow-bean-definition-overriding: true
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
  shardingsphere:
    datasource:   ##配置datasource数据源,Mybatis plus会自动注入该datasource
      names: ds0  ##数据库别名,如要进行分库,此处可添加多个,以下也根据实际情况添加多个
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource #数据库连接池
        driver-class-name: com.mysql.cj.jdbc.Driver  #数据库驱动
        url: jdbc:mysql://数据库地址:3306/数据库名?allowMultiQueries=true&useUnicode=truecharacterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
        username: 数据库账号名
        password: 数据库账号密码
        ####数据库连接池的其他配置
        initial-size: 10
        max-active: 100
        min-idle: 10
        max-wait: 60000
        pool-prepared-statements: true
        max-pool-prepared-statement-per-connection-size: 20
        time-between-eviction-runs-millis: 60000
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        stat-view-servlet:
          enabled: true
          url-pattern: /druid/*
        filter:
          stat:
            log-slow-sql: true
            slow-sql-millis: 1000
            merge-sql: true
          wall:
            config:
              multi-statement-allow: true
    sharding:
      tables:  ##配置表策略,同样,如果有多张表,下面就进行多张表的配置,查询时,如果不是以下表,就没有分表操作。
        unit_15min: #表名(逻辑表名),即此处的表明对应的是实体类Entity中的@TableName中的名称
          actual-data-nodes: ds0.unit_15min_202109,ds0.unit_15min_202110  ##实际节点,必须是数据库中已存在的表,如需要更佳的动态建表找表方案,需要再查阅其他资料,目前我暂无发现更好的方式,此处仅简单的列了两张表,实际上可使用范围来列表,具体配置可参考官方文档
          table-strategy:  ##表策略配置
            standard:  ##本Demo采用标准分片策略
              sharding-column: stat_time  ##数据库表中用于标记表分片的列,如该列为2021-09-21 00:00:00,那么就找到表unit_15min_202109
              range-algorithm-class-name:   com.hgny.energydata.module.data.sharding.StatTimeRangeShardingAlgorithm ##配置分片算法策略的类,当查询Sql中以sharding-column中设置的stat_time做=,即in条件查询时,会跳入该分片策略,类中具体内容会在下面列出。
              precise-algorithm-class-name: com.hgny.energydata.module.data.sharding.StatTimePreciseAlgorithm ##配置分片算法策略的类,当查询Sql中以sharding-column中设置的stat_time做between条件查询时,会跳入该分片策略,根据官方文档,该项在标准分片策略中时必配项类中具体内容会在下面列出。
    props:
      sql.show: true  #是否打印sql

StatTimeRangeShardingAlgorithm:

public class StatTimeRangeShardingAlgorithm implements RangeShardingAlgorithm<String> {
	@Override
	public Collection<String> doSharding(Collection<String> tableNames, RangeShardingValue<String> rangeShardingValue) {
		Set<String> result = new LinkedHashSet<>();

		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		// between and 的起始值
		LocalDateTime lower = LocalDateTime.parse(rangeShardingValue.getValueRange().lowerEndpoint(),formatter);
		LocalDateTime upper = LocalDateTime.parse(rangeShardingValue.getValueRange().upperEndpoint(),formatter);

		//获取时间列表
		//补充说明:其实tableNames中的值就是配置文件中的actual-data-nodes中配置的所有表,此处返回的是要进行查询的表
		List<String> timeList = packDateStrListByInterval(lower.toLocalDate(),upper.toLocalDate());
		// 循环范围计算分表逻辑
		for(String time : timeList){
			for(String tableName : tableNames){
				if(tableName.endsWith(time)){
					result.add(tableName);
				}
			}
		}
		return result;
	}

	//与Demo的业务相关,不需要具体看清该业务逻辑,只要知道doSharding方法时用于筛选除需要进行查询的所有表即可
	private List<String> packDateStrListByInterval(LocalDate startDate, LocalDate endDate) {
		List<String> list = Lists.newArrayList();
		if (endDate.isBefore(startDate)) {
			return list;
		}

		LocalDate tmp = startDate;
		list.add(tmp.format(DateTimeFormatter.ofPattern("yyyyMM")));
		while (true) {
			tmp = tmp.plusMonths(1);
			if (endDate.isBefore(tmp)) {
				break;
			}
			list.add(tmp.format(DateTimeFormatter.ofPattern("yyyyMM")));
		}

		return list;
	}
}

StatTimePreciseAlgorithm:

public class StatTimePreciseAlgorithm implements PreciseShardingAlgorithm<String> {
	@Override
	public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

		LocalDateTime selectDate = LocalDateTime.parse(preciseShardingValue.getValue(),formatter);
		String yyyyMM = selectDate.format(DateTimeFormatter.ofPattern("yyyyMM"));
		//补充说明:其实tableNames中的值就是配置文件中的actual-data-nodes中配置的所有表,此处返回的是要进行查询的表
		for (String tableName : collection){
			if(tableName.endsWith(yyyyMM)){
				return tableName;
			}
		}
		throw new IllegalArgumentException();
	}
}

总的来说,对上述所有配置来说,最终实现的效果就是,当Mybatis plus执行以下SQL的时候,

select * from unit_15min where stat_time between '2021-07-18 11:45:00' and '2021-09-21 11:45:00';

会跳入到StatTimeRangeShardingAlgorithm类中,根据实现的doSharding方法,将需要进行查询的所有表返回,所以此处实际执行的SQL如下:

select * from unit_15min_202107 where stat_time between '2021-07-18 11:45:00' and '2021-09-21 11:45:00';
select * from unit_15min_202108 where stat_time between '2021-07-18 11:45:00' and '2021-09-21 11:45:00';
select * from unit_15min_202109 where stat_time between '2021-07-18 11:45:00' and '2021-09-21 11:45:00';

当Mybatis plus执行以下SQL时:

select * from unit_15min where stat_time ='2021-07-18 11:45:00';

会跳入到StatTimePreciseAlgorithm类中,根据实现的doSharding方法,计算除实际需要查询的表,执行以下的实际SQL:

select * from unit_15min_202107 where stat_time ='2021-07-18 11:45:00';

本文仅介绍简单的数据库表分表查询,sharding jdbc总的使用上来说并不复杂,主要记录下踩坑点,本文的配置介绍较为简陋,详情可参考官方文档:
https://shardingsphere.apache.org/document/4.1.1/en/overview/

官方spring boot 的数据分片配置文件解释:

spring.shardingsphere.datasource.names= #数据源名称,多数据源以逗号分隔

spring.shardingsphere.datasource.<data-source-name>.type= #数据库连接池类名称
spring.shardingsphere.datasource.<data-source-name>.driver-class-name= #数据库驱动类名
spring.shardingsphere.datasource.<data-source-name>.url= #数据库url连接
spring.shardingsphere.datasource.<data-source-name>.username= #数据库用户名
spring.shardingsphere.datasource.<data-source-name>.password= #数据库密码
spring.shardingsphere.datasource.<data-source-name>.xxx= #数据库连接池的其它属性

spring.shardingsphere.sharding.tables.<logic-table-name>.actual-data-nodes= #由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持inline表达式。缺省表示使用已知数据源与逻辑表名称生成数据节点,用于广播表(即每个库中都需要一个同样的表用于关联查询,多为字典表)或只分库不分表且所有库的表结构完全一致的情况

#分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一

#用于单分片键的标准分片场景
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.sharding-column= #分片列名称
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.precise-algorithm-class-name= #精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.range-algorithm-class-name= #范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器

#用于多分片键的复合分片场景
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.sharding-columns= #分片列名称,多个列以逗号分隔
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.algorithm-class-name= #复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器

#行表达式分片策略
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.inline.sharding-column= #分片列名称
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.inline.algorithm-expression= #分片算法行表达式,需符合groovy语法

#Hint分片策略
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.hint.algorithm-class-name= #Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器

#分表策略,同分库策略
spring.shardingsphere.sharding.tables.<logic-table-name>.table-strategy.xxx= #省略

spring.shardingsphere.sharding.tables.<logic-table-name>.key-generator.column= #自增列名称,缺省表示不使用自增主键生成器
spring.shardingsphere.sharding.tables.<logic-table-name>.key-generator.type= #自增列值生成器类型,缺省表示使用默认自增列值生成器。可使用用户自定义的列值生成器或选择内置类型:SNOWFLAKE/UUID
spring.shardingsphere.sharding.tables.<logic-table-name>.key-generator.props.<property-name>= #属性配置, 注意:使用SNOWFLAKE算法,需要配置worker.id与max.tolerate.time.difference.milliseconds属性。若使用此算法生成值作分片值,建议配置max.vibration.offset属性

spring.shardingsphere.sharding.binding-tables[0]= #绑定表规则列表
spring.shardingsphere.sharding.binding-tables[1]= #绑定表规则列表
spring.shardingsphere.sharding.binding-tables[x]= #绑定表规则列表

spring.shardingsphere.sharding.broadcast-tables[0]= #广播表规则列表
spring.shardingsphere.sharding.broadcast-tables[1]= #广播表规则列表
spring.shardingsphere.sharding.broadcast-tables[x]= #广播表规则列表

spring.shardingsphere.sharding.default-data-source-name= #未配置分片规则的表将通过默认数据源定位
spring.shardingsphere.sharding.default-database-strategy.xxx= #默认数据库分片策略,同分库策略
spring.shardingsphere.sharding.default-table-strategy.xxx= #默认表分片策略,同分表策略
spring.shardingsphere.sharding.default-key-generator.type= #默认自增列值生成器类型,缺省将使用org.apache.shardingsphere.core.keygen.generator.impl.SnowflakeKeyGenerator。可使用用户自定义的列值生成器或选择内置类型:SNOWFLAKE/UUID
spring.shardingsphere.sharding.default-key-generator.props.<property-name>= #自增列值生成器属性配置, 比如SNOWFLAKE算法的worker.id与max.tolerate.time.difference.milliseconds

spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.master-data-source-name= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.slave-data-source-names[0]= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.slave-data-source-names[1]= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.slave-data-source-names[x]= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.load-balance-algorithm-class-name= #详见读写分离部分
spring.shardingsphere.sharding.master-slave-rules.<master-slave-data-source-name>.load-balance-algorithm-type= #详见读写分离部分

spring.shardingsphere.props.sql.show= #是否开启SQL显示,默认值: false
spring.shardingsphere.props.executor.size= #工作线程数量,默认值: CPU核数
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 基于 Spring BootMyBatis Plus和Vue的开发框架是现代Web应用开发的主要选择之一。Spring Boot是一个轻量级的Java开发框架,提供了快速构建独立应用程序所需的所有功能。它简化了传统的Spring应用程序开发过程,让开发者能够更专注于业务逻辑。 MyBatis Plus是一个对MyBatis进行封装的工具,提供了更简单、更方便的方式来操作数据库。它使用注解和代码生成器来减少开发时间,使得数据库操作更加高效和可维护。 Vue是一个流行的JavaScript框架,用于构建用户界面。它的特点是轻量级、易于学习和使用,并且具有非常高的性能。Vue可以与服务器端的后端框架(如Spring Boot)无缝集成,在前后端分离的项目中,提供了极佳的开发体验。 使用基于Spring BootMyBatis Plus和Vue的开发框架,开发者可以快速搭建一个完整的Web应用。首先,使用Spring Boot来创建后端应用,配置数据源和集成MyBatis Plus以简化数据库操作。然后,使用Vue来创建用户界面,通过REST API与后端进行通信。 这个开发框架的优点是集成了强大的Java后端和灵活的JavaScript前端,开发者可以使用多种技术栈来完成各种功能。同时,Spring Boot提供了很好的项目结构和配置管理,MyBatis Plus简化了数据库操作,Vue提供了丰富的界面组件和开发工具,整合后的开发框架提供了高效、可维护和可扩展的开发环境。 总之,基于Spring BootMyBatis Plus和Vue的开发框架提供了一种现代化、高效和灵活的Web应用开发方式。它适用于各种规模的项目,可以提高开发效率,降低维护成本,并且提供良好的开发体验。 ### 回答2: 基于Spring BootMyBatis Plus和Vue框架的开发可以实现一个完整的前后端分离的应用。以下是具体方面的解释: 1. Spring Boot是一个快速开发的Java框架,可以轻松搭建后端服务器。它提供了自动配置、快速开发等功能,大大简化了Java后端开发的步骤。 2. MyBatis Plus是一个基于MyBatis的增强工具,可以简化与数据库的交互。它提供了更简单的API、更强大的查询功能和代码生成等特性,可以极大提高后端开发的效率。 3. Vue是一个流行的前端框架,用于构建用户界面。它具有简单易学、灵活和高性能等特点,可以帮助我们编写交互式、响应式的前端应用。 基于这三个框架的组合,可以实现前后端完全分离的开发模式。后端使用Spring Boot搭建服务器,处理业务逻辑,并与数据库进行交互。MyBatis Plus可以简化与数据库的交互,提供了更简单的CRUD操作和强大的查询功能。 前端使用Vue进行开发,可以实现灵活的用户界面。通过Restful API与后端进行通信,实现数据的交互。 总而言之,基于Spring BootMyBatis Plus和Vue的开发模式,可以高效地实现前后端分离的应用。后端使用Spring Boot提供服务,MyBatis Plus简化数据库交互,前端使用Vue构建用户界面。这种组合可以提高开发效率,让开发人员更专注于业务逻辑的实现。 ### 回答3: 基于Spring BootMyBatis Plus和Vue的开发,可以实现一个全栈的Web应用程序。 Spring Boot是一个基于Spring框架的快速开发工具,它简化了Spring项目的配置,提供了一套约定大于配置的开发模式。使用Spring Boot可以快速搭建一个Web应用程序的后端,处理数据层和业务逻辑。 MyBatis Plus是基于MyBatis框架之上的增强工具,它进一步简化了在Java应用程序中操作数据库的流程。MyBatis Plus提供了很多常用的功能和特性,如代码生成器、自动填充、分页插件等,可以极大地提高开发效率。 Vue是一种现代化的JavaScript框架,用于构建用户界面。它提供了一套响应式组件系统和强大的工具集,可以帮助开发者快速构建单页应用程序。Vue可以与其他后端技术,如Spring BootMyBatis Plus一起使用,实现前后端分离的开发模式。 在基于这些技术的开发过程中,可以将后端的数据处理和业务逻辑实现放在Spring Boot中,使用MyBatis Plus进行数据库操作。前端使用Vue构建用户界面,并通过异步请求与后端进行数据交互。通过这种方式,可以实现一个功能完善的全栈Web应用程序。 使用Spring BootMyBatis Plus可以快速搭建后端框架,并提供强大的数据库操作能力。而Vue作为前端框架,可以提供友好的用户界面和交互体验。通过这些技术的结合,可以实现高效、灵活的全栈开发,为用户提供优质的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值