SpringBoot+Sharding-JDBC⾃定义分⽚规则+⾃定义主键⽣成策略实现⽔平分
Sharding-JDBC 实现分表
通过配置的形式将数据库按照规则进⾏分⽚等操作
Hello World
通过 Sharding-JDBC 实现⽔平分表: 数据库内⽤user_1 和 user_2 通过主键进⾏⽔平拆分,id为奇数放⼊user_1表,id为偶数放⼊user_2表
1 创建数据库和表
create database sharding character set= utf8;
use sharding;
create table user_1(
id int primary key auto_increment,
name varchar(20),
age int,
birthday datetime,
cmd varchar(200)
);
create table user_2(
id int primary key auto_increment,
name varchar(20),
age int,
birthday datetime,
cmd varchar(200)
)
;
2 创建SpringBoot⼯程
Sharding-jdbc 为我们提供了整合springBoot的启动器,配置起来⾮常简单
<!-- 数据库连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- sharding-jdbc 数据库分库分表 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.1</version>
</dependency>
<!-- 数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
<!-- reids 依赖(这⾥主要⽤于⽣成主键) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3配置application.properties⽂件
##基本配置(正常操作)
server.port=8998
# mybatis-plus 配置
mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
#sharding-jdbc的配置 ps:官⽹有详细的配置⽂件介绍:/document/legacy/4.x/document/cn/manual/sharding-jdbc/configurat ion/config-spring-boot/
#声明⼀个数据库(虚拟的)
spring.shardingsphere.datasource.names=db1
#声明虚拟数据库对应的连接,驱动,⽤户名,密码,连接池等信息
spring.shardingsphere.datasource.db1.sql.cj.jdbc.Driver
spring.shardingsphere.datasource.db1.url=jdbc:mysql://localhost:3306/sharding?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai& rewriteBatchedStatements=true
spring.shardingsphere.datasource.db1.username=root
spring.shardingsphere.datasource.db1.password=root
spring.shardingsphere.pe=com.alibaba.druid.pool.DruidDataSource
#声明表存放在对应的数据库 $->{0..1} 就是⾏内表达式
#这⾥的意思是db1库内有user虚拟表指向 user_1和user_2
spring.shardingsphere.sharding.tables.user.actual-data-nodes=db1.user_$->{1..2}
#设置主键字段
springboot推荐算法spring.shardingsphere.sharding.tables.lumn=id
# 设置主键⽣成策略可选内置的 SNOWFLAKE(雪花算法)/UUID
#也可以⾃定义(实现ShardingKeyGenerator,并配置META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator)
spring.shardingsphere.sharding.tables.pe=SNOWFLAKE
#设置根据哪个字段进⾏分⽚
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
#分⽚规则奇数存⼊user_1  偶数存⼊user_2
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{id % 2 != 0 ? 1:2}
spring.shardingsphere.props.sql.show=true
4编写对应的对象
bean:
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private Date birthday;
private String cmd;
}
mapper:
public interface UserMapper extends BaseMapper<User>{}
测试类:
@SpringBootTest
class ShardingSphereApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads(){
User user1 =new User();
user1.setAge(10);
user1.setName("张三");
user1.setBirthday(new Date());
user1.setCmd("张三今年10岁");
User user2 =new User();
user2.setAge(20);
user2.setName("李四");
user2.setBirthday(new Date());
user2.setCmd("李四今年20岁");
userMapper.insert( user2 );
}
}
经过测试⽤户张三被添加到 user_1,李四则被添加到 user_2
⾃定义主键⽣成策略
Sharding-jdbc为我们提供了2个默认的⽣成策略:
SNOWFLAKE: 雪花算法(对应数据库 bigint类型 和java的Long类型)
UUID: uuid⽣成策略(varchar和String类型)
仅仅这2种并不能满⾜我们的需求,因此sharding-jdbc为我们提供了ShardingKeyGenerator 接⼝来允许我们⾃定义主键⽣成策略实现: 这⾥通过redis⽣成⾃增的主键
1 实现 ShardingKeyGenerator 接⼝
@Component
@Slf4j
public class KeyGenerator implements ShardingKeyGenerator, ApplicationContextAware {
@Getter
@Setter
private Properties properties;
//必须设置为静态,否则为null
public static RedisTemplate redisTemplate;
@Override
public Comparable<?>generateKey(){
ValueOperations valueOp = redisTemplate.opsForValue();
return  valueOp.increment("id");
}
//设置在yaml内的名字
@Override
public String getType(){
return"auto_increment";
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
redisTemplate = Bean(StringRedisTemplate.class);
}
}
2 配置刚刚创建的类
我们需要在resource下创建⽂件
META-INF\services\org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator
并配置我们刚刚编写的主机⽣成器
3 使⽤
只需要在配置⽂件内指定刚刚的⽣成器名即可
spring.shardingsphere.sharding.tables.pe=auto_increment
⾃定义表分⽚策略
上⾯演⽰的分表策略是sharding-jdbc为我们提供的 inline 的分⽚规则,可以通过编写⾏表达式实现简单的表分⽚策略,例如根据id取模,根据性别去分类。但是对于⼀些较为复杂的分区策略,⾏表达式可能⽆法满⾜我们的要求,因此我们需要⾃定义表分⽚策略
案例: 根据当前的年⽉分,将数据插⼊不同的表中,⽐如数据库内有order_202001,order_202002等我们需要通过订单⽣成的⽇期动态的存⼊不同的表中:
1 创建数据库表