Sharding-JDBC:一种分库分表的解决方案,定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。
4.0.0
demo
com.alex
0.0.1-SNAPSHOT
com.alex
sharding-jdbc
0.0.1-SNAPSHOT
sharding-jdbc
Demo project for Spring Boot
jar
1.8
UTF-8
UTF-8
2.3.7.RELEASE
1.18.4
4.1.1
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-starter-web
junit
junit
test
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
4.0.0-RC1
com.alibaba
druid-spring-boot-starter
1.1.21
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
com.baomidou
mybatis-plus-boot-starter
3.5.1
org.projectlombok
lombok
${lombok.version}
cn.hutool
hutool-all
${hutool.version}
com.baomidou
mybatis-plus-core
3.5.1
compile
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
UTF-8
org.springframework.boot
spring-boot-maven-plugin
2.3.7.RELEASE
com.alex.shardingjdbc.ShardingJdbcApplication
repackage
repackage
单库分表的写法:
server:
port: 8089
servlet:
context-path: /sharding-jdbc
spring:
application:
name: sharding-jdbc
main:
# 一个实体类对应三张表,覆盖,不然启动报错
allow-bean-definition-overriding: true
# Sharding-JDBC的配置
shardingsphere:
datasource:
# 数据源(逻辑名字)
names: m1
# 配置数据源
m1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/alex_demo?characterEncoding=utf8&useSSL=true&createDatabaseIfNotExist=true&serverTimezone=GMT&nullNamePatternMatchesAll=true
username: root
password: yimaisc@2019
# 分片的配置
sharding:
# 表的分片策略
tables:
# 逻辑表的名称
user:
# 数据节点配置,采用Groovy表达式
actual-data-nodes: m1.user_$->{0..1}
# 配置策略
table-strategy:
# 精确匹配
inline:
sharding-column: cid
algorithm-expression: user_$->{cid % 2}
# 主键生成策略
key-generator:
# 主键
column: cid
# 雪花算法
type: SNOWFLAKE
props:
sql:
# 日志显示具体的SQL
show: true
logging:
level:
com.wang.test.demo: DEBUG
mybatis-plus:
mapper-locations: classpath*:/mapper/*.xml
type-aliases-package: com.alex.shardingjdbc.entity
configuration:
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 address_book ---> addressBook
map-underscore-to-camel-case: true
分库分表的写法:
server:
port: 8089
servlet:
context-path: /sharding-jdbc
spring:
application:
name: sharding-jdbc
main:
# 一个实体类对应三张表,覆盖,不然启动报错
allow-bean-definition-overriding: true
# Sharding-JDBC的配置
shardingsphere:
datasource:
# 数据源(逻辑名字)
names: m0,m1
# 配置数据源
m0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/alex_demo?characterEncoding=utf8&useSSL=true&createDatabaseIfNotExist=true&serverTimezone=GMT&nullNamePatternMatchesAll=true
username: root
password: yimaisc@2019
m1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/activiti?characterEncoding=utf8&useSSL=true&createDatabaseIfNotExist=true&serverTimezone=GMT&nullNamePatternMatchesAll=true
username: root
password: yimaisc@2019
# 分片的配置
sharding:
# 表的分片策略
tables:
# 逻辑表的名称
user:
# 数据节点配置,采用Groovy表达式
actual-data-nodes: m$->{0..1}.user_$->{0..1} #根据表名定义,超了就要创建对应的表,不然则会报错
# 配置策略
table-strategy:
# 精确匹配
inline:
sharding-column: cid
algorithm-expression: user_$->{cid % 2}
# 主键生成策略
key-generator:
# 主键
column: cid
# 雪花算法
type: SNOWFLAKE
props:
sql:
# 日志显示具体的SQL
show: true
logging:
level:
com.wang.test.demo: DEBUG
mybatis-plus:
mapper-locations: classpath*:/mapper/*.xml
type-aliases-package: com.alex.shardingjdbc.entity
configuration:
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 address_book ---> addressBook
map-underscore-to-camel-case: true
package com.alex.shardingjdbc.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 分页配置类
*/
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
package com.alex.shardingjdbc.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private static final long serialVersionUID = 337361630075002456L;
@TableId
private Long cid;
private String name;
private String gender;
private String data;
public User(String name, String gender, String data) {
this.name = name;
this.gender = gender;
this.data = data;
}
}
package com.alex.shardingjdbc.mapper;
import com.alex.shardingjdbc.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper extends BaseMapper {
List getList();
}
package com.alex.shardingjdbc.service;
import com.alex.shardingjdbc.entity.User;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface UserService extends IService {
void add();
IPage selectListPage();
List getList();
}
package com.alex.shardingjdbc.service.impl;
import com.alex.shardingjdbc.entity.User;
import com.alex.shardingjdbc.mapper.UserMapper;
import com.alex.shardingjdbc.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void add() {
for (int i = 1; i < 10; i++) {
User test = new User("王" + i, "男", "数据" + i);
userMapper.insert(test);
}
}
@Override
public IPage selectListPage() {
IPage page = new Page(1, 5);
IPage userIPage = userMapper.selectPage(page, new QueryWrapper().orderByAsc("name"));
return userIPage;
}
@Override
public List getList() {
return this.baseMapper.getList();
}
}
package com.alex.shardingjdbc.controller;
import com.alex.shardingjdbc.entity.User;
import com.alex.shardingjdbc.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/test")
public class UserController {
@Autowired
private UserService userService;
/**
* 插入
*
* @return
*/
@GetMapping("/insertTest")
public String insertTest() {
userService.add();
return "插入完成";
}
/**
* 查询单个
*
* @return
*/
@GetMapping("/selectTest")
public User selectTest() {
User user = this.userService.getById(798130859839324160L);
return user;
}
/**
* 查询所有
*
* @return
*/
@GetMapping("/selectListTest")
public List selectListTest() {
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.orderByAsc("name");
List list = this.userService.list(wrapper);
return list;
}
/**
* 分页查询
* 逻辑:会向所有的表中去进行一遍分页查询,第一个表数据不够就会加上另一个表分页拿到的值,但是如果加了排序的话,则会混合取值
*
* @return
*/
@GetMapping("/selectListPage")
public IPage selectListPage() {
return this.userService.selectListPage();
}
/**
* 非分片属性查询:同时查询两张表的数据
*
* @return
*/
@GetMapping("/selectListByGender")
public List selectListByGender() {
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("gender", "女");
List list = this.userService.list(wrapper);
return list;
}
/**
* 自定义sql查询
* 备注:不需要指定具体表,只需要按照定义的规则指定表的前缀即可,如select * from user则会去查询user_1和user_2的数据
*
* @return
*/
@GetMapping("/getList")
public List getList() {
List list = this.userService.getList();
return list;
}
}