要须心地收汗马,孔孟行世目杲杲。这篇文章主要讲述SpringBoot+Mybatis-Plus整合Sharding-JDBC5.1.1实现单库分表全网最新相关的知识,希望能为你提供帮助。
一、前言小编最近一直在研究关于分库分表的东西,前几天docker安装了mycat实现了分库分表,但是都在说mycat的bug很多。很多人还是倾向于shardingsphere
,其实他是一个全家桶,有JDBC、Proxy 和 Sidecar
组成,小编今天以最简单的JDBC
来简单整合一下!
现在最新版已经是5.1.1
,经过一天的研究用于解决了所有问题,完成了单库分表!!
想了解4.0.0版本的可以看一下小编刚刚写的:SpringBoot+Mybatis-Plus整合Sharding-JDBC4.0.0实现单库分表
如果想看mycat的可以看一下小编之前写的文章哈:Docker安装Mycat和Mysql进行水平分库分表实战
二、踩过的坑
1. 数据源问题
不要使用druid-spring-boot-starter
这个依赖,启动会有问题
<
dependency>
-->
<
groupId>
com.alibaba<
/groupId>
<
artifactId>
druid-spring-boot-starter<
/artifactId>
<
version>
1.1.21<
/version>
/dependency>
报错信息:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name userMapper defined in file
[D:\\jiawayun\\demo\\target\\classes\\com\\example\\demo\\mapper\\UserMapper.class]:
Invocation of init method failed;
nested exception is
java.lang.IllegalArgumentException: Property sqlSessionFactory
or sqlSessionTemplate are required
==解决方案:==
使用单独的
druid
<
dependency>
<
groupId>
com.alibaba<
/groupId>
<
artifactId>
druid<
/artifactId>
<
version>
1.2.8<
/version>
<
/dependency>
建议使用==默认的数据源==,sharding-jdbc也是使用的默认的数据源,小编使用的自带的,忘记
druid
后面会不会有问题了!!type: com.zaxxer.hikari.HikariDataSource
2. Insert 语句不支持分表路由到多个数据节点
报错信息:
Insert statement does not support sharding table routing to multiple data nodes.
解决方案:
看小编文章:解决不支持分表路由问题
三、导入maven依赖
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-web<
/artifactId>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-test<
/artifactId>
<
scope>
test<
/scope>
<
exclusions>
<
exclusion>
<
groupId>
org.junit.vintage<
/groupId>
<
artifactId>
junit-vintage-engine<
/artifactId>
<
/exclusion>
<
/exclusions>
<
/dependency>
<
dependency>
<
groupId>
junit<
/groupId>
<
artifactId>
junit<
/artifactId>
<
scope>
test<
/scope>
<
/dependency>
<
dependency>
<
groupId>
org.apache.shardingsphere<
/groupId>
<
artifactId>
shardingsphere-jdbc-core-spring-boot-starter<
/artifactId>
<
version>
5.1.1<
/version>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-web<
/artifactId>
<
/dependency>
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-test<
/artifactId>
<
scope>
test<
/scope>
<
/dependency>
<
!-- lombok -->
<
dependency>
<
groupId>
org.projectlombok<
/groupId>
<
artifactId>
lombok<
/artifactId>
<
version>
1.18.10<
/version>
<
/dependency>
<
!--jdbc-->
<
dependency>
<
groupId>
org.springframework.boot<
/groupId>
<
artifactId>
spring-boot-starter-jdbc<
/artifactId>
<
/dependency>
<
!-- mysql -->
<
dependency>
<
groupId>
mysql<
/groupId>
<
artifactId>
mysql-connector-java<
/artifactId>
<
/dependency>
<
!-- mybatis-plus -->
<
dependency>
<
groupId>
com.baomidou<
/groupId>
<
artifactId>
mybatis-plus-boot-starter<
/artifactId>
<
version>
3.5.1<
/version>
<
/dependency>
四、新建表 1. 新建二张表
命名为:
user_0
、user_1
CREATE TABLE `user_0`(
`cid` bigint(25) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`gender` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`data` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
2. 数据库结构
文章图片
五、框架全局展示 1. User实体类
@Data
public class User implements Serializable
private static final long serialVersionUID = 337361630075002456L;
private Long cid;
private String name;
private String gender;
private String data;
2. controller
@RestController
@RequestMapping("/test")
public class UserController @Autowired
private UserMapper userMapper;
@GetMapping("/insertTest")
public void insertTest()
for (int i = 1 ;
i <
10;
i++)
User test = new User("王"+i,"男","数据" + i);
userMapper.insert(test);
3. mapper
我们直接省略了service,简单一下哈!!
public interface UserMapper extends BaseMapper<
User>
4. application.yml配置
server:
port: 8089spring:
shardingsphere:
mode:
type: memory
# 是否开启
datasource:
# 数据源(逻辑名字)
names: m1
# 配置数据源
m1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useSSL=false&
autoReconnect=true&
characterEncoding=UTF-8&
serverTimezone=UTC
username: root
password: root
# 分片的配置
rules:
sharding:
# 表的分片策略
tables:
# 逻辑表的名称
user:
# 数据节点配置,采用Groovy表达式
actual-data-nodes: m1.user_$->
0..1
# 配置策略
table-strategy:
# 用于单分片键的标准分片场景
standard:
sharding-column: cid
# 分片算法名字
sharding-algorithm-name: user_inline
key-generate-strategy: # 主键生成策略
column: cid# 主键列
key-generator-name: snowflake# 策略算法名称(推荐使用雪花算法)
key-generators:
snowflake:
type: SNOWFLAKE
sharding-algorithms:
user_inline:
type: inline
props:
algorithm-expression: user_$->
cid % 2
props:
# 日志显示具体的SQL
sql-show: truelogging:
level:
com.wang.test.demo: DEBUGmybatis-plus:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.demo.entity
configuration:
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 address_book --->
addressBook
map-underscore-to-camel-case: true
5. 启动类
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication public static void main(String[] args)
SpringApplication.run(DemoApplication.class, args);
六、测试插入九条数据==本次测试策略是:行表达式分片策略:
inline
==1. 插入数据
输入 :
localhost:8089/test/insertTest
文章图片
==分片成功==
2. 单个查询
@GetMapping("/selectOneTest")
public void selectOneTest()User user = userMapper.selectOne(Wrappers.<
User>
lambdaQuery().eq(User::getCid,736989417020850176L));
System.out.println(user);
这时他会根据cid去自动获取去那个表中获取数据
文章图片
3. 全查询
@GetMapping("/selectListTest")
public void selectListTest()List<
User>
list = userMapper.selectList(null);
System.out.println(list);
由于没有条件,他会去把两个表
UNION ALL
进行汇总文章图片
4. 分页查询
需要先配置mybatis-plus分页配置类:
@Configuration
public class MybatisPlusConfig @Bean
public MybatisPlusInterceptor mybatisPlusInterceptor()
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
@GetMapping("/selectListPage")
public void selectListPage()
IPage<
User>
page = new Page(1,6);
IPage<
User>
userIPage = userMapper.selectPage(page,null);
List<
User>
records = userIPage.getRecords();
System.out.println(records);
我们user_0有5条数据,user_1有4条数据
==我们发现它会向所有的表中去进行一遍分页查询,第一个表数据不够就会加上另一个表分页拿到的值==
文章图片
==分页size为3时,一个user_0就可以满足分页条件,就会忽略user_1的分页数据。==
文章图片
5. 非分片属性查询
我们先把
user_0表
性别修改两个为女,然后进行查询!看看没有分片的字段是否能够只去user_0
去查询@GetMapping("/selectListByGender")
public void selectListByGender()List<
User>
list = userMapper.selectList(Wrappers.<
User>
lambdaQuery().eq(User::getGender, "女"));
System.out.println(list);
有图可见:不是分片的字段查询,回去全连接表去查询一遍,效率和不分表一样了哈!!
文章图片
6. 分片属性来自一个表in查询
@GetMapping("/selectInList")
public void selectList()
List<
User>
users = userMapper.selectList(Wrappers.<
User>
lambdaQuery().in(User::getCid,736989417020850176L,736989418119757824L));
System.out.println(users);
我们可以发现,我们根据分片字段进行in查询,sharding-jdbc会识别出来来自于那个表进而提高效率,不会所有的表进行全连接。
文章图片
七、总结这样就完成了最新版的
sharding-jdbc
的简单测试和一些坑的解决,总的来说配置很费劲,不能有一定的错误!看到这里了,还不给小编一键三连走起来,谢谢大家了!!
有缘人才可以看得到的哦!!!
【SpringBoot+Mybatis-Plus整合Sharding-JDBC5.1.1实现单库分表全网最新】点击访问!小编自己的网站,里面也是有很多好的文章哦!
推荐阅读
- 5.28-6.2博客精彩回顾
- Linux安装文件目录结构
- Windows服务器(web服务:实验案例二:)
- Linux中查看操作操作系统版本的方法
- sqlserver数据库查询数据库连接情况和什么语句造成死锁
- Python 编程学习教程
- Git的纯命令操作,Install,Clone, Commit,Push,Pull,版本回退,撤销更新,分支的创建/切换/更新/提交/合并,代码冲突
- 又一款高效简单的服务器探针——WGCLOUD
- Android源码浅析——SecureCRT远程连接Linux,配置端点和字节码