背景介绍
如果你的系统需要提高并发,那么你需要进行分库,如果你的系统需要支持海量数据,那么你需要进行分表。分库分表之后,应用这边如何才能做到跟单库单表一样简单。有很多开源软件来支持分库分表,现在比较常用的是 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='用户表';
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于