博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot+mybatis+sharding-jdbc整合分库分表实战
阅读量:2065 次
发布时间:2019-04-29

本文共 9728 字,大约阅读时间需要 32 分钟。

接上一张分库分表分析。项目代码地址:

1.引入jar包

org.springframework.boot
spring-boot-starter-parent
2.1.5.RELEASE
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.2.0
com.alibaba
druid
1.1.9
io.shardingsphere
sharding-jdbc-spring-boot-starter
3.1.0

2.新建表t_user_1和t_user_2,表结构完全一样

3.新建工程sharding-jdbc,结构
mapper接口

public interface TUserMapper {	int insert(TUser user);}

mapper接口对应的xml

INSERT INTO t_user (user_name,age,remark) VALUES (#{userName}, #{age}, #{remark})

service接口

public interface TUserService {	boolean  insert(TUser user);}

service接口实现类

@Servicepublic class TUserServiceImpl implements TUserService{	@Autowired	private TUserMapper tUserMapper;		@Override	public boolean insert(TUser user) {		return this.tUserMapper.insert(user) == 1;	}}

TUser实体类

public class TUser implements Serializable {	private static final long serialVersionUID = 1L;	private Integer id;	private String userName;	private Integer age;	private String remark;	public Integer getId() {		return id;	}	public void setId(Integer id) {		this.id = id;	}	public String getUserName() {		return userName;	}	public void setUserName(String userName) {		this.userName = userName;	}	public Integer getAge() {		return age;	}	public void setAge(Integer age) {		this.age = age;	}	public String getRemark() {		return remark;	}	public void setRemark(String remark) {		this.remark = remark;	}}

Controller类

@RestControllerpublic class TUserController {	@Autowired	private TUserService tUserService;		@GetMapping("/add")	public String add(){		TUser user = new TUser();		user.setUserName("张三");		user.setAge(20);		user.setRemark("...");		boolean result = this.tUserService.insert(user);		if(result){			return "success";		}		return "fail";	}}

application.properties配置,本文采用的是sharding-jdbc-spring-boot-starter的3.1.0版本的,所以配置文件需以sharding.jdbc.开头

水平分表不分库配置

#spring.main.allow-bean-definition-overriding=true#配置数据源的详细信息,多个逗号分开sharding.jdbc.datasource.names=m1# 数据库连接池sharding.jdbc.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource#数据库驱动类名sharding.jdbc.datasource.m1.driver-class-name=com.mysql.jdbc.Driver# 数据库 URL 连接sharding.jdbc.datasource.m1.url=jdbc:mysql://localhost:3306/sharding-jdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC# 数据库用户名sharding.jdbc.datasource.m1.username=root# 数据库密码sharding.jdbc.datasource.m1.password=123456# 指定t_user表的分布情况,配置在哪个数据库,表名称是什么  m1.t_user_1  m1.t_user_2sharding.jdbc.config.sharding.tables.t_user.actual-data-nodes=m1.t_user_$->{1..2}#指定t_user表中主键的生成策略  SNOWFLAKE:雪花算法,随机生成主键Idsharding.jdbc.config.sharding.tables.t_user.key-generator-column-name=idsharding.jdbc.config.sharding.tables.t_user.key-generator-type=SNOWFLAKE# 指定分片的策略 约定id值 : 偶数--》t_user_1  奇数-->t_user_2sharding.jdbc.config.sharding.tables.t_user.table-strategy.inline.sharding-column=idsharding.jdbc.config.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user_$->{id%2 +1}#打开sql的输出日志sharding.jdbc.config.sharding.props.sql.show=true#实体类扫描配置,这样在mapper的xml中可以直接使用实体类名,不用写包路径mybatis.type-aliases-package=com.xqc.mode#驼峰转换mybatis.configuration.mapUnderscoreToCamelCase=true#处理日期spring.jackson.date-format=yyyy-MM-dd HH:mmspring.jackson.time-zone=GMT+8#xml文件扫描mybatis.mapperLocations=classpath:mapper/*.xml

启动类配置

@SpringBootApplication@MapperScan("com.xqc.dao")//mapper接口扫描public class App {	    public static void main( String[] args ){      	SpringApplication.run(App.class, args);    }    }

4.浏览器多次访问查看数据库数据

主键ID尾数奇数的存在t_user_2表中
主键ID尾数偶数的存在t_user_1表中
上面数据存储采用的是自带的inline算法,我们也可以根据自己的需求,自定义分片算法

# 自定义分表算法sharding.jdbc.config.sharding.tables.t_user.table-strategy.standard.sharding-column=idsharding.jdbc.config.sharding.tables.t_user.table-strategy.standard.precise-algorithm-class-name=com.xqc.algorithm.MyPreciseShardingAlgorithm

实现接口PreciseShardingAlgorithm

/*** @dateTime 创建时间:2020年8月19日 上午10:19:06* @version V1.0.0* 类说明 自定义分表算法,尾数0-5存表t_user_1,6-9存表t_user_2*/public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm
{ private static final List
PARAM_LIST = Arrays.asList("0","1","2","3","4","5"); @Override public String doSharding(Collection
availableTargetNames, PreciseShardingValue
shardingValue) { //availableTargetNames拆分出来的物理表【t_user_1,t_user_2】,shardingValue分片字段的值 for (String availableTargetName : availableTargetNames) { String value = "2" ; //尾数0-5存表t_user_1,6-9存表t_user_2 String colValue = shardingValue.getValue().toString(); String subLast = shardingValue.getValue().toString().substring(colValue.length()-1, colValue.length()); if(PARAM_LIST.contains(subLast)){ value = "1"; } if(availableTargetName.endsWith(value)){ return availableTargetName; } } throw new IllegalArgumentException(); }}

再看数据库数据

分片算法介绍

通过分片算法将数据分片,支持通过=、BETWEEN和IN分片。分片算法需要应用方开发者自行实现,可实现的灵活度非常高。
精确分片算法
对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。
范围分片算法
对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND进行分片的场景。需要配合StandardShardingStrategy使用。
复合分片算法
对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。
Hint分片算法
对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。

水平分库分表配置:不同的数据库,相同的表结构,每个库都有多份

#分库不分表的情况#spring.main.allow-bean-definition-overriding=true#配置数据源的详细信息,多个逗号分开sharding.jdbc.datasource.names=m1,m2#数据库1# 数据库连接池sharding.jdbc.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource#数据库驱动类名sharding.jdbc.datasource.m1.driver-class-name=com.mysql.jdbc.Driver# 数据库 URL 连接sharding.jdbc.datasource.m1.url=jdbc:mysql://localhost:3306/sharding-jdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC# 数据库用户名sharding.jdbc.datasource.m1.username=root# 数据库密码sharding.jdbc.datasource.m1.password=123456#数据库2# 数据库连接池sharding.jdbc.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource#数据库驱动类名sharding.jdbc.datasource.m2.driver-class-name=com.mysql.jdbc.Driver# 数据库 URL 连接sharding.jdbc.datasource.m2.url=jdbc:mysql://localhost:3306/sharding-jdbc_02?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC# 数据库用户名sharding.jdbc.datasource.m2.username=root# 数据库密码sharding.jdbc.datasource.m2.password=123456# 指定分库的策略 约定id值 : 偶数--》m1  奇数-->m2sharding.jdbc.config.sharding.tables.t_user.database-strategy.inline.sharding-column=idsharding.jdbc.config.sharding.tables.t_user.database-strategy.inline.algorithm-expression=m$->{id%2 +1}# 指定t_user表的分布情况,配置在哪个数据库,表名称是什么  m1.t_user_1  m1.t_user_2sharding.jdbc.config.sharding.tables.t_user.actual-data-nodes=m$->{1..2}.t_user_$->{1..2}#指定t_user表中主键的生成策略  SNOWFLAKE:雪花算法,随机生成主键Idsharding.jdbc.config.sharding.tables.t_user.key-generator-column-name=idsharding.jdbc.config.sharding.tables.t_user.key-generator-type=SNOWFLAKE#指定表的分表算法sharding.jdbc.config.sharding.tables.t_user.table-strategy.inline.sharding-column=pidsharding.jdbc.config.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user_$->{pid%2 +1}#打开sql的输出日志sharding.jdbc.config.sharding.props.sql.show=true#实体类扫描配置,这样在mapper的xml中可以直接使用实体类名,不用写包路径mybatis.type-aliases-package=com.xqc.mode#驼峰转换mybatis.configuration.mapUnderscoreToCamelCase=true#处理日期spring.jackson.date-format=yyyy-MM-dd HH:mmspring.jackson.time-zone=GMT+8#xml文件扫描mybatis.mapperLocations=classpath:mapper/*.xml

水平分库不分表配置:相同的表结构,放在多个数据库中,根据分库算法存放数据,访问地址

#分库不分表的情况#spring.main.allow-bean-definition-overriding=true#配置数据源的详细信息,多个逗号分开sharding.jdbc.datasource.names=m1,m2#数据库1# 数据库连接池sharding.jdbc.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource#数据库驱动类名sharding.jdbc.datasource.m1.driver-class-name=com.mysql.jdbc.Driver# 数据库 URL 连接sharding.jdbc.datasource.m1.url=jdbc:mysql://localhost:3306/sharding-jdbc?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC# 数据库用户名sharding.jdbc.datasource.m1.username=root# 数据库密码sharding.jdbc.datasource.m1.password=123456#数据库2# 数据库连接池sharding.jdbc.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource#数据库驱动类名sharding.jdbc.datasource.m2.driver-class-name=com.mysql.jdbc.Driver# 数据库 URL 连接sharding.jdbc.datasource.m2.url=jdbc:mysql://localhost:3306/sharding-jdbc_02?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC# 数据库用户名sharding.jdbc.datasource.m2.username=root# 数据库密码sharding.jdbc.datasource.m2.password=123456# 指定t_user表的分布情况,配置在哪个数据库,表名称是什么  m1.t_user_1  m1.t_user_2#sharding.jdbc.config.sharding.tables.t_role.actual-data-nodes=m1.t_user_$->{1..2}#指定t_user表中主键的生成策略  SNOWFLAKE:雪花算法,随机生成主键Idsharding.jdbc.config.sharding.tables.t_role.key-generator-column-name=idsharding.jdbc.config.sharding.tables.t_role.key-generator-type=SNOWFLAKE# 指定分片的策略 约定id值 : 偶数--》m1  奇数-->m2# 自定义分库算法sharding.jdbc.config.sharding.tables.t_role.database-strategy.inline.sharding-column=idsharding.jdbc.config.sharding.tables.t_role.database-strategy.inline.algorithm-expression=m$->{id%2 +1}#打开sql的输出日志sharding.jdbc.config.sharding.props.sql.show=true#实体类扫描配置,这样在mapper的xml中可以直接使用实体类名,不用写包路径mybatis.type-aliases-package=com.xqc.mode#驼峰转换mybatis.configuration.mapUnderscoreToCamelCase=true#处理日期spring.jackson.date-format=yyyy-MM-dd HH:mmspring.jackson.time-zone=GMT+8#xml文件扫描mybatis.mapperLocations=classpath:mapper/*.xml

sharding-jdbc执行流程
SQL路由:根据解析上下文匹配用户配置的分片策略,并生成最终的路由路径
SQL改写:将SQL改写为在真实数据库中可以正确执行的语句。

转载地址:http://jiwmf.baihongyu.com/

你可能感兴趣的文章
AWS 容器三大新品:K8s 发行版,免费镜像库和 “Game Changer”AWS Proton
查看>>
多平台容器镜像构建就看这一篇
查看>>
macOS Big Sur 使用全新虚拟化框架创建超轻量虚拟机!
查看>>
16 岁高中生成功在 iPhone 7 上安装 Ubuntu 20.04 桌面!
查看>>
两个程序都要用同一个端口,怎么解?
查看>>
有了这款图形管理界面,一分钟内配置 10 个 WireGuard 客户端不是梦
查看>>
Containerd镜像lazy-pulling解读
查看>>
Grafana 教程 - 构建你的第一个仪表盘
查看>>
由 OOM 引发的 ext4 文件系统卡死
查看>>
什么?WireGuard 可以让躲在 NAT 后面的客户端之间直连了??
查看>>
k8s集群内的节点,可能没你想象的那么健壮!(磁盘管理篇)
查看>>
利用 ebpf sockmap/redirection 提升 socket 性能(2020)
查看>>
春节前最后一波福利,Alibaba Java 训练营]5天突破面向对象编程限时免费报名!...
查看>>
我就要在容器里写文件!?
查看>>
支付宝集五福最全攻略,五分钟集齐五福!
查看>>
Runc 容器初始化和容器逃逸
查看>>
使用 GDB + Qemu 调试 Linux 内核
查看>>
介绍一个小工具:SSL-exporter
查看>>
深入理解 tc ebpf 的 direct-action (da) 模式(2020)
查看>>
为容器时代设计的高级 eBPF 内核特性(FOSDEM, 2021)
查看>>