使用sharding-jdbc实现水平分表的示例代码
目录
- 在mysql中新建数据库sharding_db,新增两张结构一样的表student_1和student_2。
- 添加依赖
- 编写配置文件
- 编写实体类
- 编写mapper接口
- 编写测试类
- 执行测试
在mysql中新建数据库sharding_db,新增两张结构一样的表student_1和student_2。
CREATE TABLE `student_1` (`ID`bigint(20) NOT NULL ,`NAME`varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL ,`AGE`int(11) NOT NULL ,`GENDER`varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL ,PRIMARY KEY (`ID`));
此处未指定主键自增,因为两张表的id不能重复,所以只能从后端传入id。
添加依赖
org.springframework.boot spring-boot-starter-jdbcorg.springframework.boot spring-boot-starter-webcom.alibaba druid1.1.20 mysql mysql-connector-javacom.baomidou mybatis-plus-boot-starter3.0.5 org.apache.shardingsphere sharding-jdbc-spring-boot-starter4.0.0-RC1 org.projectlombok lombokorg.springframework.boot spring-boot-testtestjunit junittestorg.springframework.boot spring-boot-starter-testtestorg.junit.vintage junit-vintage-engine
编写配置文件
spring.main.allow-bean-definition-overriding=true# 配置Sharding-JDBC的分片策略# 配置数据源,给数据源起名g1,g2...此处可配置多数据源spring.shardingsphere.datasource.names=g1# 配置数据源具体内容:连接池,驱动,地址,用户名,密码# 由于上面配置数据源只有g1因此下面只配置g1.type,g1.driver-class-name,g1.url,g1.username,g1.passwordspring.shardingsphere.datasource.g1.type=com.alibaba.druid.pool.DruidDataSourcespring.shardingsphere.datasource.g1.driver-class-name=com.mysql.cj.jdbc.Driverspring.shardingsphere.datasource.g1.url=jdbc:mysql://localhost:3306/sharding_db?characterEncoding=utf-8&useUnicode=true&useSSL=false&serverTimezone=UTCspring.shardingsphere.datasource.g1.username=rootspring.shardingsphere.datasource.g1.password=123456# 配置表的分布,表的策略spring.shardingsphere.sharding.tables.student.actual-data-nodes=g1.student_$->{1..2}# 指定student表 主键gid 生成策略为 SNOWFLAKEspring.shardingsphere.sharding.tables.student.key-generator.column=idspring.shardingsphere.sharding.tables.student.key-generator.type=SNOWFLAKE# 指定分片策略 约定id值是偶数添加到student_1表,如果id是奇数添加到student_2表spring.shardingsphere.sharding.tables.student.table-strategy.inline.sharding-column=idspring.shardingsphere.sharding.tables.student.table-strategy.inline.algorithm-expression=student_$->{id % 2 + 1}# 打开sql输出日志spring.shardingsphere.props.sql.show=true
或者是yml格式
spring:main:allow-bean-definition-overriding: trueshardingsphere:datasource:g1:driver-class-name: com.mysql.cj.jdbc.Driverpassword: 123456type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://localhost:3306/sharding_db?characterEncoding=utf-8&useUnicode=true&useSSL=false&serverTimezone=UTCusername: rootnames: g1props:sql:show: truesharding:tables:student:actual-data-nodes: g1.student_$->{1..2}key-generator:column: idtype: SNOWFLAKEtable-strategy:inline:algorithm-expression: student_$->{id % 2 + 1}sharding-column: id
编写实体类
@Datapublic class Student {private Long id; private String name; private int age; private String gender; }
编写mapper接口
@Repositorypublic interface StudentMapper extends BaseMapper {}
编写测试类
@SpringBootTestclass ShardingJdbcDemoApplicationTests {@Autowiredprivate StudentMapper studentMapper; @Testpublic void test01() {for (int i = 0; i < 10; i++) {Student student = new Student(); student.setName("wuwl"); student.setAge(27); student.setGender("男"); studentMapper.insert(student); }}}
执行测试
文章图片
执行成功,主键通过雪花算法在后端生成,传入到数据库中,根据奇偶性进行分表。
student_1表数据:
文章图片
student_2表数据:
文章图片
两张表的数据分别有5条,但这只是因为雪花算法生成的id奇数偶数各5个,不是1:1的关系,需要注意。
主键生成后,根据策略插入到对应的表中,从打印出来的sql可以证明这一点。
通过mapper接口的selectById方法进行查询时,会先根据主键策略判断在哪个库,再直接去那个库根据主键查询。而如果是通过其它条件查询,或者是多个id的selectById方法查询,又是如何的呢?
@Testpublic void test03() {Listlist = new ArrayList<>(); list.add(1362282042768609282l); list.add(1362282040277192705l); List studentList = studentMapper.selectBatchIds(list); System.out.println(studentList); }
取了两张表的id进行查询。
文章图片
执行同样的sql,在两张表中都查询一遍,再组合结果。
如果所有的id,都来自同一张表,那是否会去多个表中重复查询呢?
文章图片
只执行了一遍。所以,在执行查询时,sharding会先判断是否可以确定需要的数据来自那张表,如果能,则直接去那一张表中查询数据即可,而如果不能确定,则会多个表重复查询,以确定查询结果的完整性。
【使用sharding-jdbc实现水平分表的示例代码】到此这篇关于使用sharding-jdbc实现水平分表的示例代码的文章就介绍到这了,更多相关sharding-jdbc 水平分表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入