背景介绍
如果你的系统需要提高并发,那么你需要进行分库,如果你的系统需要支持海量数据,那么你需要进行分表。分库分表之后,应用这边如何才能做到跟单库单表一样简单。有很多开源软件来支持分库分表,现在比较常用的是 sharding-jdbc,mycat 框架。今天来讲讲 sharding-jdbc,示例实现了:数据分片、读写分离、数据分片 + 读写分离、数据治理的功能。
整体项目
说明:
数据分片:两个数据库 uc0、uc1 每个数据库两种表 user0、user1
读写分离:一个主库,一个从库
数据分片 + 读写分离:两个主库、两个从库、每个库里存在两种表
pom 配置
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 使用数据治理需要加入 -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-orchestration-reg-zookeeper-curator</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
核心代码
UserService:为 service 接口。
UserServiceImpl:为 service 实现类。
UserDao:
@Mapper
public interface UserDao {
User getById(Long id);
void insert(User user);
void update(User user);
}
ShardingJdbcApplicationTests:为测试类。
配置
UserDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cimu.shardingjdbc.mapper.UserDao">
<resultMap id="BaseResultMap" type="com.cimu.shardingjdbc.entity.User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="real_name" property="realName" jdbcType="VARCHAR" />
<result column="mobile" property="mobile" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List">
id, real_name, mobile, password
</sql>
<select id="getById" resultMap="BaseResultMap" parameterType="java.lang.Long">
select
<include refid="Base_Column_List" />
from user
where id=#{id}
</select>
<insert id="insert" parameterType="com.cimu.shardingjdbc.entity.User" useGeneratedKeys="true" keyProperty="id">
insert into user
(
`id`,
`real_name`,
`mobile`,
`create_time`,
`update_time`,
`del_flag`
)
values
(
#{id},
#{realName},
#{mobile},
#{createTime},
#{updateTime},
#{delFlag}
)
</insert>
<update id="update" parameterType="com.cimu.shardingjdbc.entity.User">
update user
<set>
<if test="realName != null ">`real_name` = #{realName},</if>
<if test="mobile != null ">`mobile` = #{mobile},</if>
<if test="createTime != null ">`create_time` = #{createTime},</if>
<if test="updateTime != null ">`update_time` = #{updateTime},</if>
<if test="delFlag != null ">`del_flag` = #{delFlag},</if>
</set>
where id = #{id}
</update>
</mapper>
application.properties
##==========================只支持分片配置=====start======================================
##数据源的名称,多个以短号隔开
#sharding.jdbc.datasource.names=uc0,uc1
##数据源的配置
#sharding.jdbc.datasource.uc0.type=com.zaxxer.hikari.HikariDataSource
#sharding.jdbc.datasource.uc0.driver-class-name=com.mysql.jdbc.Driver
#sharding.jdbc.datasource.uc0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
#sharding.jdbc.datasource.uc0.username=root
#sharding.jdbc.datasource.uc0.password=
##数据源的配置
#sharding.jdbc.datasource.uc1.type=com.zaxxer.hikari.HikariDataSource
#sharding.jdbc.datasource.uc1.driver-class-name=com.mysql.jdbc.Driver
#sharding.jdbc.datasource.uc1.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
#sharding.jdbc.datasource.uc1.username=root
#sharding.jdbc.datasource.uc1.password=
##默认的数据库分片策略,如果没有指定具体某个数据库的分片策略,那么使用默认分片策略
#sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
#sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=uc$->{id % 2}
##id.intdiv(2) % 2 : 根据id进行分片,先对数据库数量进行取余,在对表数量进行取模。这个作用是让数据可以更加均匀的分布在不同表中。
##$->{0..1} 是行表达式标识符,uc$->{0..1}表示uc0,uc1
#sharding.jdbc.config.sharding.tables.user.actual-data-nodes=uc$->{0..1}.user$->{0..1}
#sharding.jdbc.config.sharding.tables.user.table-strategy.inline.sharding-column=id
#sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithm-expression=user$->{id.intdiv(2) % 2}
##是否开启SQL显示,默认值: false
#sharding.jdbc.config.sharding.props.sql.show=true
##==========================只支持分片配置======end=====================================
##==========================只支持读写分离配置=====start======================================
##数据源的名称,多个以短号隔开
#sharding.jdbc.datasource.names=ucmaster,ucslave0
##数据源的配置
#sharding.jdbc.datasource.ucmaster.type=com.zaxxer.hikari.HikariDataSource
#sharding.jdbc.datasource.ucmaster.driver-class-name=com.mysql.jdbc.Driver
#sharding.jdbc.datasource.ucmaster.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
#sharding.jdbc.datasource.ucmaster.username=root
#sharding.jdbc.datasource.ucmaster.password=
##数据源的配置
#sharding.jdbc.datasource.ucslave0.type=com.zaxxer.hikari.HikariDataSource
#sharding.jdbc.datasource.ucslave0.driver-class-name=com.mysql.jdbc.Driver
#sharding.jdbc.datasource.ucslave0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
#sharding.jdbc.datasource.ucslave0.username=root
#sharding.jdbc.datasource.ucslave0.password=
##从库负载均衡算法类型,可选值:ROUND_ROBIN,RANDOM。若`load-balance-algorithm-class-name`存在则忽略该配置
#sharding.jdbc.config.masterslave.load-balance-algorithm-type=round_robin
#sharding.jdbc.config.masterslave.name=ms
##主库数据源名称
#sharding.jdbc.config.masterslave.master-data-source-name=ucmaster
##从库数据源名称列表,多个以逗号隔开
#sharding.jdbc.config.masterslave.slave-data-source-names=ucslave0
##是否开启SQL显示,默认值: false
#sharding.jdbc.config.masterslave.props.sql.show=true
##==========================只支持读写分离配置======end=====================================
##==========================数据分片+读写分离配置=====start======================================
#数据源的名称,多个以短号隔开
sharding.jdbc.datasource.names=master0,master1,uc0slave0,uc1slave0
#master数据源的配置
sharding.jdbc.datasource.master0.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.master0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.master0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
sharding.jdbc.datasource.master0.username=root
sharding.jdbc.datasource.master0.password=
#slave数据源的配置
sharding.jdbc.datasource.uc0slave0.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.uc0slave0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.uc0slave0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc0slave0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
sharding.jdbc.datasource.uc0slave0.username=root
sharding.jdbc.datasource.uc0slave0.password=
#master数据源的配置
sharding.jdbc.datasource.master1.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.master1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.master1.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
sharding.jdbc.datasource.master1.username=root
sharding.jdbc.datasource.master1.password=
#slave数据源的配置
sharding.jdbc.datasource.uc1slave0.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.uc1slave0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.uc1slave0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/uc1slave0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
sharding.jdbc.datasource.uc1slave0.username=root
sharding.jdbc.datasource.uc1slave0.password=
##默认的数据库分片策略,如果没有指定具体某个数据库的分片策略,那么使用默认分片策略
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=aa$->{id % 2}
#id.intdiv(2) % 2 : 根据id进行分片,先对数据库数量进行取余,在对表数量进行取模。这个作用是让数据可以更加均匀的分布在不同表中。
#$->{0..1} 是行表达式标识符,aa$->{0..1}表示aa0,aa1
sharding.jdbc.config.sharding.tables.user.actual-data-nodes=aa$->{0..1}.user$->{0..1}
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithm-expression=user$->{id.intdiv(2) % 2}
sharding.jdbc.config.sharding.tables.user.key-generator-column-name=id
#这里的aa0需要和上面的default-database-strategy.inline.algorithm-expression,sharding.tables.user.actual-data-nodes的对应
sharding.jdbc.config.sharding.master-slave-rules.aa0.master-data-source-name=master0
sharding.jdbc.config.sharding.master-slave-rules.aa0.slave-data-source-names=uc0slave0
sharding.jdbc.config.sharding.master-slave-rules.aa1.master-data-source-name=master1
sharding.jdbc.config.sharding.master-slave-rules.aa1.slave-data-source-names=uc1slave0
##==========================数据分片+读写分离配置======end=====================================
##==========================数据治理配置======start===================================
sharding.jdbc.config.sharding.orchestration.name=demo-orchestration
#本地配置是否覆盖注册中心配置。如果可覆盖,每次启动都以本地配置为准
sharding.jdbc.config.sharding.orchestration.overwrite=true
sharding.jdbc.config.sharding.orchestration.registry.server-lists=xxxx:2181
sharding.jdbc.config.sharding.orchestration.registry.namespace=demo-orchestration
##==========================数据治理配置======end=====================================
mybatis.typeAliasesPackage=com.cimu.shardingjdbc.entity
mybatis.mapperLocations=classpath:mapper/*.xml
user.sql
CREATE TABLE `user0` (
`id` BIGINT(64) NOT NULL PRIMARY KEY COMMENT '主键ID',
`real_name` VARCHAR(100) DEFAULT NULL COMMENT '真实名称',
`mobile` VARCHAR(11) DEFAULT NULL COMMENT '手机号码',
`password` VARCHAR(20) DEFAULT NULL COMMENT '密码',
`create_time` DATETIME DEFAULT NULL COMMENT '创建日期',
`update_time` DATETIME DEFAULT NULL COMMENT '修改日期',
`del_flag` CHAR(1) NOT NULL DEFAULT '0' COMMENT '删除标记 1:删除;0:未删除'
)COMMENT='用户表';
CREATE TABLE `user1` (
`id` BIGINT(64) NOT NULL PRIMARY KEY COMMENT '主键ID',
`real_name` VARCHAR(100) DEFAULT NULL COMMENT '真实名称',
`mobile` VARCHAR(11) DEFAULT NULL COMMENT '手机号码',
`password` VARCHAR(20) DEFAULT NULL COMMENT '密码',
`create_time` DATETIME DEFAULT NULL COMMENT '创建日期',
`update_time` DATETIME DEFAULT NULL COMMENT '修改日期',
`del_flag` CHAR(1) NOT NULL DEFAULT '0' COMMENT '删除标记 1:删除;0:未删除'
)COMMENT='用户表';
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于