🚀 ShardingSphere 🚀 |
🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯
🚀 ShardingSphere 🚀 |
🍔 目录
- 🍀 一.Sharding-JDBC强制路由基本概念
- 🍀 二.Sharding-JDBC强制路由案例实战
- 🥦 2.1 数据环境准备
- 🥦 2.2 创建SpringBoot程序 - 导入依赖
- 🥦 2.3 创建SpringBoot程序 - 实体类
- 🥦 2.4 创建SpringBoot程序 - 数据库Mapper接口 & 主启动类
- 🥦 2.5 创建SpringBoot程序 - 自定义强制路由配置类
- 🥦 2.6 创建SpringBoot程序 - 强制路由配置文件
- 🍀 三.Sharding-JDBC强制路由案例测试
- 🥦 3.1 强制路由到库测试
- 🥦 3.2 强制路由到库到表测试
- 🍀 四.总结
- 💬 五.共勉
🍀 一.Sharding-JDBC强制路由基本概念
在一些应用场景中,分片条件依赖于外部业务逻辑。因此需要提供一种通过在外部业务代码中指定路由配置的一种方式,在ShardingSphere中叫做Hint。如果使用Hint指定了强制分片路由,那么SQL将会无视原有的分片逻辑,直接路由至指定的数据节点操作。ShardingSphere使用ThreadLocal管理分片键值进行Hint强制路由。可以通过编程的方式向HintManager中添加分片值,该分片值仅在当前线程内生效。
Hint使用场景:
- 数据分片操作,如果分片键没有在SQL或数据表中,而是在业务逻辑代码中
- 读写分离操作,如果强制在主库进行某些数据操作
Sharding-JDBC强制路由案例实战官方指导手册
🍀 二.Sharding-JDBC强制路由案例实战
🥦 2.1 数据环境准备
没有创建过的同学们需要在 ljw_course_db1
和 ljw_course_db2
中创建 t_course表.
CREATE TABLE `t_course` (`cid` bigint(20) NOT NULL,`user_id` bigint(20) DEFAULT NULL,`corder_no` bigint(20) DEFAULT NULL,`cname` varchar(50) DEFAULT NULL,`brief` varchar(50) DEFAULT NULL,`price` double DEFAULT NULL,`status` int(11) DEFAULT NULL,PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
🥦 2.2 创建SpringBoot程序 - 导入依赖
引入依赖 (注意: 在这里使用ShardingSphere4.1版本为案例
进行强制路由的实战)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>shardingjdbc-hint</artifactId><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.5.RELEASE</version><relativePath/></parent><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-core-common</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.8</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.5</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version><scope>compile</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
🥦 2.3 创建SpringBoot程序 - 实体类
与数据库表中对应的实体类
@TableName("t_course")
@Data
@ToString
public class Course {@TableId(type = IdType.ASSIGN_ID)private Long cid;private Long userId;private Long corderNo;private String cname;private String brief;private double price;private int status;
}
🥦 2.4 创建SpringBoot程序 - 数据库Mapper接口 & 主启动类
编写对应的数据库持久层CourseMapper接口
@Repository
public interface CourseMapper extends BaseMapper<Course> {
}
@Repository注解的类需要交给我们的Spring容器进行管理,因此需要我们在主启动类加上扫描接口的注解。
@SpringBootApplication
@MapperScan("com.ljw.mapper")
public class ShardingSphereApplication {public static void main(String[] args) {SpringApplication.run(ShardingSphereApplication.class,args);}
}
🥦 2.5 创建SpringBoot程序 - 自定义强制路由配置类
在自定义类中编写分库或分表路由策略,实现HintShardingAlgorithm接口,并且重写doSharding方法
public class HintShardingAlgorithmConfig implements HintShardingAlgorithm<Long> {/*** 定义强制路由策略* collection: 代表分片目标: 对哪些数据库 表进行分片,比如做分库路由,集合中就存储着 db1.t_course, db1.t_course* hintShardingValue: 代表分片值, 指的是使用者对分片键赋的值*/@Overridepublic Collection<String> doSharding(Collection<String> collection, HintShardingValue<Long> hintShardingValue) {// 结果收集Collection<String> result = new ArrayList<>();// 遍历数据库// collection: 代表分片目标: 对哪些数据库 表进行分片,比如做分库路由,集合中就存储着 db1.t_course, db1.t_coursefor (String actualDb : collection) {// hintShardingValue: 代表分片值, 指的是使用者对分片键赋的值Collection<Long> values = hintShardingValue.getValues();for (Long value : values) {//分库路由 判断当前节点名称结尾 是否与取模结果一致if(actualDb.endsWith(String.valueOf(value % 2 + 1))){result.add(actualDb);}}}return result;}}
🥦 2.6 创建SpringBoot程序 - 强制路由配置文件
配置读写分离相关配置的信息
# 应用名称
spring.application.name=sharding-jdbc-hint# 打印SQl
spring.shardingsphere.props.sql-show=true# 定义多个数据源
spring.shardingsphere.datasource.names = db1,db2# 数据源1
spring.shardingsphere.datasource.db1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db1.jdbc-url=jdbc:mysql://192.168.10.132:3306/ljw_course_db1?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.db1.username=root
spring.shardingsphere.datasource.db1.password=root# 数据源2
spring.shardingsphere.datasource.db2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db2.jdbc-url=jdbc:mysql://192.168.10.133:3306/ljw_course_db2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.db2.username=root
spring.shardingsphere.datasource.db2.password=root# 配置默认数据源db1
spring.shardingsphere.sharding.default-data-source-name=db1# Hint强制路由
# 使用t_course表测试强制路由到库
spring.shardingsphere.sharding.tables.t_course.database-strategy.hint.algorithm-class-name=com.ljw.hint.HintShardingAlgorithmConfig
# 强制路由到指定表
spring.shardingsphere.sharding.tables.t_course.table-strategy.hint.algorithm-class-name=com.ljw.hint.HintShardingAlgorithmConfig#配置数据节点 指定t_course逻辑表表的真实分布情况
spring.shardingsphere.sharding.tables.t_course.actual-data-nodes=db$->{1..2}.t_course_$->{1..2}
🍀 三.Sharding-JDBC强制路由案例测试
先将我们数据库中表中原来的数据都删除掉,如果是新建的同学就不用了!
🥦 3.1 强制路由到库测试
@Autowiredprivate CourseMapper courseMapper;//测试强制路由 到指定库的插入操作@Testpublic void testInsertCourse(){//通过hintManager指定执行策略的分片键的值HintManager hintManager = HintManager.getInstance();//强制路由到db2,此时我们需要传入1,因为我们配置类的逻辑是vlaue%2+1->1%2+1hintManager.setDatabaseShardingValue(1L);for (int i = 0; i < 6; i++) {Course course = new Course();course.setUserId(1000L+i);course.setCname("Sharding-JDBC强制路由案例实战");course.setBrief("全网Sharding-JDBC强制路由案例实战最详细讲解!!!");course.setPrice(8939.00);course.setStatus(0);courseMapper.insert(course);}}
运行结果:
🥦 3.2 强制路由到库到表测试
@Autowiredprivate CourseMapper courseMapper;@Testpublic void testHintDbToTable(){HintManager hintManager = HintManager.getInstance();//强制路由到指定库 -> db2hintManager.addDatabaseShardingValue("t_course",1L);//强制路由到指定表 ->course1hintManager.addTableShardingValue("t_course",0L);List<Course> courses = courseMapper.selectList(null);courses.forEach(System.out::println);}
运行结果:
🍀 四.总结
本篇文章主要讲解了Sharding-JDBC强制路由案例实战,实操过程非常重要,大家一定要动手亲自实践一下,必须掌握。下节预告,数据加密详解与实战,大家敬请期待呦!!!。
💬 五.共勉
最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |