Sharding-JDBC implements sub-table
Perform operations such as sharding the database in accordance with the rules in the form of configuration
Hello World
Implement horizontal table splitting through Sharding-JDBC: use user_1 and user_2 in the database to split horizontally through the primary key, the id is an odd number into the user_1 table, and the id is an even number into the user_2 table
1 Create a database and table
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 Create a SpringBoot project
Sharding-jdbc provides us with a starter that integrates springBoot, which is very simple to configure
<!-- 数据库连接驱动 -->
<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 configure the application.properties file
##基本配置(正常操作)
server.port=8998
# mybatis-plus 配置
mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
mybatis-plus.type-aliases-package=com.mt.bean
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
spring.redis.host=120.25.227.88
spring.redis.password=123456
#sharding-jdbc的配置 ps:官网有详细的配置文件介绍:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/configuration/config-spring-boot/
#声明一个数据库(虚拟的)
spring.shardingsphere.datasource.names=db1
#声明虚拟数据库对应的连接,驱动,用户名,密码,连接池等信息
spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.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.datasource.db1.type=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}
#设置主键字段
spring.shardingsphere.sharding.tables.user.key-generator.column=id
# 设置主键生成策略 可选内置的 SNOWFLAKE(雪花算法)/UUID
#也可以自定义(实现ShardingKeyGenerator,并配置META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator)
spring.shardingsphere.sharding.tables.user.key-generator.type=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 write the corresponding object
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> {
}
Test class:
@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 );
}
}
After testing, user Zhang San was added to user_1, and Li Si was added to user_2
Custom primary key generation strategy
Sharding-jdbc provides us with 2 default generation strategies:
- SNOWFLAKE: Snowflake algorithm (corresponding to the database bigint type and java Long type)
- UUID: uuid generation strategy (varchar and String types)
These two types alone cannot meet our needs, so sharding-jdbc provides us with an ShardingKeyGenerator
interface to allow us to customize the primary key generation strategy.
Implementation: Here is an auto-incremented primary key generated by redis
1 Implement the ShardingKeyGenerator interface
@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 = applicationContext.getBean(StringRedisTemplate.class);
}
}
2 Configure the class just created
We need to create files under resource
META-INF\services\org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator
And configure the host generator we just wrote
com.mt.config.Sharding.KeyGenerator
3 use
Just specify the name of the generator just in the configuration file
spring.shardingsphere.sharding.tables.user.key-generator.type=auto_increment
Custom table fragmentation strategy
Demonstrated above sub-table strategy is sharding-jdbc provides us with the inline
fragmentation of the rules, you can write 行表达式
simple table partitioning strategy, for example, according to the modulo id, according to gender classification. But for some more complex partitioning strategies, row expressions may not meet our requirements, so we need to customize the table fragmentation strategy
Case: According to the current year, month and minute, insert data into different tables. For example, there are order_202001, order_202002, etc. in the database. We need to dynamically store the date generated by the order into different tables:
1 Create a database table
create table `order_202001`(
id int primary key auto_increment,
date datetime,
price decimal(10,2),
cmd varchar(200)
);
create table `order_202002`(
id int primary key auto_increment,
date datetime,
price decimal(10,2),
cmd varchar(200)
);
create table `order_202003`(
id int primary key auto_increment,
date datetime,
price decimal(10,2),
cmd varchar(200)
);
2 Create an entity object
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("`order`")
public class Order {
@TableId(type = IdType.AUTO)
private Integer id;
private Date date;
private BigDecimal price;
private String cmd;
}
3 Create a sharding logic class
@Component
public class OrderTableShardingAlgorithm implements PreciseShardingAlgorithm<Date> {
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Date> preciseShardingValue) {
//preciseShardingValue就是当前插入的字段值
//collection 内就是所有的逻辑表
//获取字段值
Date time = preciseShardingValue.getValue();
if(time == null){
throw new UnsupportedOperationException("prec is null");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
String year =sdf.format(time);
for (String tableName : collection) {
//循环表名已确定使用哪张表
String name = tableName.substring(tableName.length() - 6);
if(year.equals(name)){
return tableName;//返回要插入的逻辑表
}
}
return null;
}
}
#声明虚拟表
spring.shardingsphere.sharding.tables.order.actual-data-nodes=db1.order_$->{2000..2099}0$->{1..9},db1.order_$->{2000..2099}1$->{0..2}
#声明表内的主键
spring.shardingsphere.sharding.tables.order.key-generator.column=id
#声明主键生成策略
spring.shardingsphere.sharding.tables.order.key-generator.type=order_auto_increment
#声明根据哪个字段进行分片
spring.shardingsphere.sharding.tables.order.table-strategy.standard.sharding-column=date
#自定义分片规则类
spring.shardingsphere.sharding.tables.order.table-strategy.standard.precise-algorithm-class-name=com.mt.config.Sharding.OrderTableShardingAlgorithm
4 Add operation through mybatis-plus
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderMapper orderMapper;
@GetMapping("add")
public String add(Order order){
orderMapper.insert(order);
return "success";
}
}