赞
踩
CREATE TABLE `order_info` (
`id` bigint NOT NULL COMMENT 'id',
`name` varchar(32) DEFAULT NULL COMMENT '名称',
`num` int DEFAULT NULL COMMENT '数量',
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
这里的分表逻辑是根据id取余,分成4个表。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--导入mybatisplus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- shardingjdbc-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.2</version>
</dependency>
<!-- druid数据源,需要导入,否则shardingjdbc无法找到druid数据源会报错-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
<!-- mybatisplus 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
package com.walker.mbpsharding.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* @Author: WalkerShen
* @DATE: 2022/3/29
* @Description:
**/
@Data
//使用tableName代表映射的mysql的表
@TableName("order_info")
public class OrderInfo {
private Long id;
private String name;
private Integer num;
private Date createTime;
}
package com.walker.mbpsharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.walker.mbpsharding.entity.OrderInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @Author: WalkerShen
* @DATE: 2022/3/29
* @Description: 创建mapper接口,
**/
//使用@Mapper,注入容器
@Mapper
//继承BaseMapper类,可以获取BaseMapper中的方法
public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
}
package com.walker.mbpsharding.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.walker.mbpsharding.entity.OrderInfo;
import java.util.List;
public interface OrderInfoService extends IService<OrderInfo> {
List<OrderInfo> listSharding();
}
package com.walker.mbpsharding.service;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.walker.mbpsharding.entity.OrderInfo;
import com.walker.mbpsharding.mapper.OrderInfoMapper;
import org.springframework.stereotype.Service;
import java.util.List;
//1、使用@Service注入容器
@Service
//2、继承serviceImpl
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService{
// 使用@DS指定需要执行的数据源
@DS(value="sharding")
@Override
public List<OrderInfo> listSharding() {
return list();
}
}
OrderInfoMapper.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">
<!--namespace:命名空间,用来映射对应的mapper
相当于将mapper和mapper.xml连接起来,这一步很重要-->
<mapper namespace="com.walker.mbpsharding.mapper.OrderInfoMapper">
</mapper>
注意:xml文件的位置需要和配置文件配置的一样,否则找不到就会报Mapper的Bean找不到的错误
package com.walker.mbpsharding.config;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.apache.shardingsphere.driver.jdbc.adapter.AbstractDataSourceAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;
/**
* 动态数据源配置:
*
* 使用{@link com.baomidou.dynamic.datasource.annotation.DS}注解,切换数据源
*
*/
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class,
SpringBootConfiguration.class})
public class DataSourceConfiguration {
// 分表数据源名称
private static final String SHARDING_DATA_SOURCE_NAME = "sharding";
//mybatisplus 动态数据源配置项
@Autowired
private DynamicDataSourceProperties properties;
// shardingjdbc的数据源
@Lazy
@Resource(name = "shardingSphereDataSource")
AbstractDataSourceAdapter shardingSphereDataSource;
// 动态数据源提供者bean注册
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
// 首先从mybatisplus的动态数据源先获取
Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
return new AbstractDataSourceProvider() {
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
// 然后将 shardingjdbc 管理的数据源也交给动态数据源管理
dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingSphereDataSource);
return dataSourceMap;
}
};
}
// 数据源配置 @Primary 代表优先使用该bean
@Primary
@Bean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
// 首选数据源
dataSource.setPrimary(properties.getPrimary());
dataSource.setStrict(properties.getStrict());
dataSource.setStrategy(properties.getStrategy());
// 配置数据源提供者
dataSource.setProvider(dynamicDataSourceProvider);
dataSource.setP6spy(properties.getP6spy());
dataSource.setSeata(properties.getSeata());
return dataSource;
}
}
其实就是分别获取mybatisplus的数据源和sharding的数据源,然后将sharding的数据源加入到mybatisplus的动态数据源Map中,然后就可以使用@DS注解去指定数据源了
spring:
autoconfigure: # 排除druid 否则报错
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
# 注意格式一定要配好,这里有一个datasource 然后再dynamic,后面再来了一个datasource 才到了配置数据源
datasource:
# 1、mybatisplus动态数据源的配置
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://localhost:3306/table_sharding?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimeZone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
shardingsphere:
# 开启sql打印
enabled: true
props:
# 是否显示sql
sql-show: true
# 2、shardingjdbc的数据源的配置
datasource:
# 数据源名称
names: sharding
# 数据源实例: 如果这里还有master
sharding:
type: com.alibaba.druid.pool.DruidDataSource
driver-class: com.mysql.cj.jdbc.Driver
# 使用Druid,不能使用jdbc-url 得使用url
url: jdbc:mysql://localhost:3306/table_sharding?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
# 分片规则
rules:
sharding:
# 对表进行分片
tables:
# 逻辑表名,代表的是需要分表的名称
order_info:
# 实际节点:这里代表的是 会使用sharding数据源中 order_info表 细分为0~3 4个表
actual-data-nodes: sharding.order_info_$->{0..3}
# 表策略
table-strategy:
# 标准表策略
standard:
# 分表的列
sharding-column: id
# 分片算法名称: 来源于下面的sharding-algorithms
sharding-algorithm-name: alg_hash_mod
key-generate-strategy: # 主键生成策略
column: id # 主键列
key-generator-name: snowflake # 策略算法名称(推荐使用雪花算法)
# 主键生成规则,SNOWFLAKE 雪花算法
key-generators:
snowflake:
type: SNOWFLAKE
# 分片算法
sharding-algorithms:
alg_hash_mod:
# 类型:hash取余 类似于获取一个列的数,假如是3 3%4=0 数据就会进入第0个表
type: HASH_MOD
# 分片的数量,因为是4个表,所以是4
props:
sharding-count: 4
# mybatisplus配置
mybatis-plus:
# 配置xml路径
mapper-locations: classpath*:/mapper/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
package com.walker.mbpsharding;
import com.walker.mbpsharding.entity.OrderInfo;
import com.walker.mbpsharding.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@Slf4j
@SpringBootTest
class MybatisplusShardingApplicationTests {
@Autowired
private OrderInfoService orderInfoService;
@Test
public void list(){
List<OrderInfo> list = orderInfoService.list();
log.info("返回结果:{}",list);
}
@Test
public void sharding(){
List<OrderInfo> list = orderInfoService.listSharding();
log.info("返回结果:{}",list);
}
}
执行list方法:
执行sharding方法
可以看到,使用分表的原则去查询数据
SELECT id,name,num,create_time FROM order_info_0 UNION ALL SELECT id,name,num,create_time FROM order_info_1 UNION ALL SELECT id,name,num,create_time FROM order_info_2 UNION ALL SELECT id,name,num,create_time FROM order_info_3
我们可以查看DynamicDataSourceProperties类,可以看到关于Druid的配置
所以我们要如此配置:
放在指定的数据源下面: druid.xxx
spring:
# 注意格式一定要配好,这里有一个datasource 然后再dynamic,后面再来了一个datasource 才到了配置数据源
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://localhost:3306/table_sharding?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimeZone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
wall:
multi-statement-allow: true
condition-and-alway-true-allow: true
stat:
# 慢SQL记录
logSlowSql: true
slowSqlMillis: 1000
mergeSql: true
mybatisplus多数据源配置参考:
https://baomidou.com/pages/a61e1b/
整合Mybatisplus应该是比较常见的场景了,现在大部分企业都有使用mp。
也可以看看历史文章学习一下哦~
ShardingSphere系列01:Shardingjdbc实现分表(含项目实践)
ShardingSphere系列02:ShardingJdbc+Mybatis实现多数据源
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。