开发者学堂课程【数据库中间件ShardingSphere详解:ShardingSphere-Sharding-JDBC水平分表(最终测试)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/666/detail/11247
ShardingSphere-Sharding-JDBC 水平分表(最终测试)
上节课程完成 Shard ing-jdbc 分片策略配置,配置代码通过官网快速修改为理想效果,官网中也对配置做了详细的说明,其中都有解释,按照官网可以快速修改为实际效果,下面编写测试代码。
一.编写测试代码
首先完成环境配置,在 Course.java 中定义了实体类,在 CourseMap
per 中也添加了 Mapper 包括 MyBatisPlus,还有 Mapper Scan 不要忘记添加,这些完成后,在 spring boot 测试方法中把 mapper 注入进去,调用方法来实现操作。
进行最基本的添加操作,改名为 cddCourse ,添加时调用 cours
eMapper 的 insert 方法,insert中传入一个 course 对象即可,使用语句 Course course= new Course();向 course 中设置id 值,主键不需要设置因为已经设置了策略,使用雪花算法生成随机唯一的数字;使用语句 course.setCname(“java”)设置课程名称;使用 course.setUserId(“100L”),id 值为 100,因为时 Long 类型所以使用 100L 传值; course.setCstatuse(“Normal”)为课程发布状态 Normal,表示已发布;最后把 course 设置到 insert 方法中。这样就完成添加课程的基本操作,课程代码已经编写完成,在执行后会向数据库中添加数据。在添加过程中执行设置策略:如果主键id 如果时偶数把数据添加到 course-1 中,如果主键 id 如果时奇数把数据添加到 course-2 中,下面进行测试,查看能否实现最终效果。添加过程中可能出现错误,如果有错误需要尽快排除问题,下面进行测试。
//添加课程方法
@Test
public void addCourse
(){
course course = new Course();
course.setCname ("java");
course.setUserId(100L);
course.setCstatus ("Normal");
courseMlapper.insert (course);
}
在文件中单击右键把代码执行,第一次编译速度比较慢,需要把 Java 代码编译为 class 文件。加载完成系统报错,出现异常:查看异常一般查看最前面和最后面,先看最后面最后面有名为 Course by 即由什么引起,一行提示很长,如果直接查看并不能准确找到错误;这时可以查看最前面的提示:dataSource 定义了即在里面已经定义,Action 告诉需要解决问题怎么样,overriding 为重启覆盖,需要解决问题为 Bing 已经被覆盖了。需要设置让 setting spring.main.allow-bean-de
finition-overriding 值等于 true,说明问题需要怎么解决。
(1)上面测试代码执行,报错了
在数据库中有两张表一个名为 course_1,一个名为 course_2;而在操作中其中有一个实体类名为 course,这个实体类对应两张表既要对应course_1 又要对应 course_2,但是无法对应因为实体类无法对应两张表,虽然两张表结构相同,目前无法使用一个实体类对应两张表,现在需要解决问题。设置让 setting
spring.main.allow-bean-definition-overriding 值等于 true,因为两张表结构相同,让两张表实体类操作相当于一张表,因为两张表结构相同,需要把 etting
spring.main.allow-bean-deinition-overriding = true 在其中设置。目前问题是一个实体类需要对应两张表,两张表根据规则向其中添加数据,因为实体类无法对应两张表,虽然两张表结构相同。让两张表根据实体类做同一对应,如果相同进行覆盖,例如操作第一个表操作第二个表结构都一样,使用实体类都可以操作。出现问题:一个实体类无法对应两张表,需要进行设置,把etting spring.main.allow-bean-deinition-overriding = true 放入配置文件中,位置并无影响,设置后可以实现所需效果,需要添加这个配置。
#一个实体类无法对应两张表,覆盖
spring.main.allow-bean-deinition-overriding = true
(2)解决方案,在配置文件中添加一行配置
spring.main.allow-bean-definition-overriding=true.
把它添加后再进行测试,再编写时需要特别注意。添加后进行最终测试,再测试代码页面中执行代码,查看执行后的效果:目前没有报错,最后一部分有语句的输出,因为再配置文件中配置 sql 输入日志,所以输出代码;cid 值为 465114047893733377 为奇数,操作 course_2 表,向 m1 中 course_2 中添加 cid数据,证明水平分表完成;
在表中查看结果,首先查看 course_1 ,刷新一下,course_1 表中无数据;查看 course_2,有一条添加的数据,因为 cid 值是奇数,所以把数据添加到 course_2 中。
再次测试,在测试代码中添加 for 循环,循环多次每一次 cid 值随机生成,可能是奇数也可能是偶数;把代码放入 for 循环中
public void addCourse
(){
for(int=0;int<10;int++){
course course = new Course();
course.setCname ("java"+i);
course.setUserId(100L);
course.setCstatus ("Normal"+1);
courseMlapper.insert (course);
}
}
使用雪花算法随机生成唯一的数字,现在会循环十次对数据库添加数据。先把已经添加的数据删除,这么测试 cid 值可能是奇数也可能是偶数,会向两张表中添加数据,把代码执行查看效果。
执行成功后,显示十条 insert 语句输出,根据 cid 值分别向 course_1,course_2中添加数据,以 465114667455348737 为例,值为奇数会操作 course_2;465114668461981696 末位值为 6 值为偶数,操作 course_1,在数据库中查看,首先 course_1 中有 6 条数据,cid均为偶数,末位值为 6 每一个 cid 均为随机唯一值;course_2 中末位为 7 均为奇数,使用雪花算法每次生成随机唯一值;最终把数据添加到 course_1,course_2 中;添加测试完成后,可以再次测试,下面进行查询测试,,编写代码命名为 findCourse,调用 course Mapper 中 selectOne 方法,向其中添加条件,编写条件构造器 QueryWrapper,QueryWrapper<Course> wrapper =new QueryWrapper<>();创建完成后根据 id 做查询,eq 表示等于id 位 cid 值添加 cid值为 465114665106538497 是一个奇数,因为是 Long 类型所以在数字后面添加 L;把wrapper 传入方法 select One 中,会返回对象;把对象 course 进行输出。完成简单 id 查询方法,根据 cid 进行查询。这段代码执行,如果编写正确,在 course_2 表中把数据查询出。
@Test
public void findCourse(){
QueryWrapper<Course> wrapper= new QueryWrapper<>
();
wrapper.eq(column:"cid",val:465114665106538497L);
Course course = courseMapper.selectOne(wrapper);
System.out println(course);
}
执行代码,最终执行成功,数据能够查询并且没有问题,因为 id 值是奇数所以会查询 course_2 表;在配置文件中配置分片策略,如果 cid 值是偶数查询 course_1 如果是奇数查询 course_2。使用 Shard ing-jdbc 实现对分库分表后数据的操作。
强调细节,使用 Shard ing-jdbc 做水平分表,首先搭建环境,在项目中引入相关依赖,然后创建实体类 mapper,mapper 中使用Base Mapper ,建启用类 Mapper Scan,在测试文件中进行最终测试。第二步,创建数据库做水平分表包括其中的两个表 course_1 和 course_2。下一步在配置文件中配置分片策略,主要数据结构,可以通过官网修改为理想的效果,主要配置数据源地址时应适用 MySQL 8;最后进行测试,测试时出现问题,可以同给添加 etting spring.main.allow-bean-deinition-overriding = true 语句解决,出现的问题为一个实体类无法对应两张表,一个实体类需要对应两张表把两张表覆盖,因为两张表结构相同,目前在水平分表时需要这个配置。在测试中进行添加,查询;添加时根据规则 id 是奇数添加到 course_2 中,是偶数添加到 course_1 中;查询的 cid 值是奇数,所以查询 course_2 表中数据,如果查询的值是偶数,肯定查询 course_1 中的数据。例如把测试代码中查询的值替换为偶数,执行代码做测试,执行成功查看语句查询那张表,因为值是偶数所以查询 course_1。目前就完成使用 Shard ing-jdb 实现水平分表完整的代码过程。