- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
垂直分库和垂直分表是一种思想,其实质和单库单表一样,并不是由Sharding-jdbc进行维护
在进行SQL操作时,如果SQL中的字段不是分片(分库分表)策略的分片键,则会对所有分库(表)进行广播路由操作,如果条件中存在多个分片策略键,则会按照每个字段的分片策略进行不同的路由查询,在SQL中操作的表的字段必须进行了分片策略配置才会按照分片策略进行匹配操作
框架搭建:SpringBoot + HikariCP/Druid + Mybatis + Mysql+sharding-jdbc
1、POM依赖:
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
2、配置允许数据源覆盖
properties
文件加入以下配置
# 允许数据源覆盖
spring.main.allow-bean-definition-overriding=true
3、数据源配置
数据源类型通常选择DruidDataSource
或者HikariDataSource
两者在配置上有所不同。
<!-- 不能使用druid-spring-boot-starter,会导致:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>version</version>
</dependency>
com.alibaba.druid.pool.DruidDataSource
DruidDataSource需要引入druid的Jar包,使用:url
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.url=
com.zaxxer.hikari.HikariDataSource
HikariDataSource要使用:jdbc-url
spring.shardingsphere.datasource.m1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.m1.jdbc-url=
将用户(user)表,进行水平分表,分为:user_0,user_1,user_2,并且对表进行CRUD操作;id为1的数据进入user_1,id为3的数据进入user_0,依次类推;
1、SQL:
//创建数据表
CREATE TABLE user_0/1/2 (
id BIGINT(20) NOT NULL COMMENT 'Id',
name VARCHAR(20) NOT NULL COMMENT '名称',
phone VARCHAR(20) NOT NULL COMMENT '电话',
email VARCHAR(20) NOT NULL COMMENT '邮箱',
PRIMARY KEY (id)
)
2、properties配置:
#sharding-jdbc 水平分表规则配置
# 数据源名称,多数据源逗号隔开
spring.shardingsphere.datasource.names=m1
spring.shardingsphere.datasource.m1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.jdbc-url=jdbc:mysql://127.0.0.1:3307/shardingjdbc?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456
# 水平分表:user_0/1/2,多个表进行分表时,依次在tables标签后写逻辑
# user_0/1/2 为数据库中的事实表
# user为xml编码中操作的逻辑表,sharding-jdbc会自动根据策略操作事实表
# 配置节点分布情况
spring.shardingsphere.sharding.tables.user.actual-data-nodes=m1.user_$->{
0..2}
# 指定user表的主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.user.key-generator.column=id
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE
# 指定user表的分片策略,分片策略包括分片键和分片算法, user_0/1/2 所有对3取余
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{
id % 3}
# 打开sql输出日志
spring.shardingsphere.props.sql.show=true
3、代码实现
Controller:
@RestController
@RequestMapping("test")
public class TestController {
// TODO DEMO配置文件中,存在多种配置策略,如何只需要对某一种类型进行测试,则需要修改配置文件配置
@Resource
private TestService testService;
@GetMapping("/table")
public Object table() {
return testService.table();
}
Service:
@Service
public class TestService {
@Resource
private TableMapper tableMapper;
public Object table() {
// 插入测试
for (long i = 1; i <= 10; i++) {
User user = new User();
user.setId(i);
user.setName("Name_" + i);
user.setPhone("phone");
user.setEmail("email");
tableMapper.insertTable(user);
}
// 修改测试(模拟修改Id为1的数据)
tableMapper.updateTableById(1L, "修改名称");
// 删除测试(模拟修改Id为2的数据)
tableMapper.deleteTableById(2L);
// 查询测试
List<User> list = tableMapper.listAllTable();
return list;
}
}
Mapper
@Mapper
public interface TableMapper {
int insertTable(User user);
int deleteTableById(Long id);
int updateTableById(@Param("id") Long id, @Param("name") String name);
List<User> listAllTable();
}
Mapping
<!--SQL写法 CRUD -->
<insert id="insertTable" parameterType="com.sharding.model.entity.User">
insert into user(id, name, phone, email)
values (#{id},{name},{phone},{email})
</insert>
<delete id="deleteTableById">
delete
from user
where id ={id}
</delete>
<update id="updateTableById">
update
user
set name ={name}
where id ={id}
</update>
<select id="listAllTable"
resultType="com.sharding.model.entity.User">
select *
from user
order by id desc
</select>
在执行SQL时,会根据SQL语句的逻辑表查询,然后Sharding-JDBC
会根据分片策略操作事实表,如果操作的表没有进行配置任何的分片策略,则和正常操作方式一样不受任何影响,如 果对事实表的分片字段进行操作时,数据会随机被写入到不同的数据表中,并且修改/删除/查询时会对所有的分库进行查询操作。
在设计分片字段时,一定要想清楚,CURD需要使用到相同的分片建,否则会操作全表操作,导致性能下降。
4、效果:
模拟系统使用,存在水平分库
将数据库分为:sharding_0、sharding_1,需要手动创建
事实表:user
1、SQL:
//创建数据表
CREATE TABLE user (
id BIGINT(20) NOT NULL COMMENT 'Id',
name VARCHAR(20) NOT NULL COMMENT '名称',
phone VARCHAR(20) NOT NULL COMMENT '电话',
email VARCHAR(20) NOT NULL COMMENT '邮箱',
PRIMARY KEY (id)
)
2、properties配置:
#sharding-jdbc 水平分库规则配置
# 数据源名称,多数据源逗号隔开
spring.shardingsphere.datasource.names=ds0,ds1
# 配置第一个库-ds0
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3307/sharding_0?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# 配置第二个库-ds1
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3307/sharding_1?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# 分库策略,以事实表user表的id为分片键,分片策略为id % 2
spring.shardingsphere.sharding.tables.user.database-strategy.inline.sharding-column = id
spring.shardingsphere.sharding.tables.user.database-strategy.inline.algorithm-expression =ds$->{
id % 2}
## 打开sql输出日志
spring.shardingsphere.props.sql.show=true
3、代码实现
Controller:
@RestController
@RequestMapping("test")
public class TestController {
// TODO DEMO配置文件中,存在多种配置策略,如何只需要对某一种类型进行测试,则需要修改配置文件配置
@Resource
private TestService testService;
@GetMapping("/database")
public Object database() {
return testService.database();
}
}
Service:
@Service
public class TestService {
@Resource
private DatabaseMapper databaseMapper;
public Object database() {
// 插入测试
for (long i = 1; i <= 10; i++) {
User user = new User();
user.setId(i);
user.setName("Name_" + i);
user.setPhone("phone");
user.setEmail("email");
databaseMapper.insertDatabase(user);
}
// 修改测试(模拟修改Id为1的数据)
databaseMapper.updateDatabaseById(1L, "修改名称");
// 删除测试(模拟修改Id为2的数据)
databaseMapper.deleteDatabaseById(2L);
// 查询测试
List<User> list = databaseMapper.listAllDatabase();
return list;
}
}
Mapper
@Mapper
public interface DatabaseMapper {
int insertDatabase(User user);
int deleteDatabaseById(Long id);
int updateDatabaseById(@Param("id") Long id, @Param("name") String name);
List<User> listAllDatabase();
}
Mapping
<?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">
<mapper namespace="com.sharding.mapper.DatabaseMapper">
<insert id="insertDatabase" parameterType="com.sharding.model.entity.User">
insert into user(id, name, phone, email)
values (#{id},{name},{phone},{email})
</insert>
<delete id="deleteDatabaseById">
delete
from user
where id ={id}
</delete>
<update id="updateDatabaseById">
update
user
set name ={name}
where id ={id}
</update>
<select id="listAllDatabase"
resultType="com.sharding.model.entity.User">
select *
from user
order by id desc
</select>
</mapper>
4、效果:
模拟系统使用,存在水平分片(分库和分表)
将数据库分为:sharding_0、sharding_1
将用户(user)表,进行水平分表,分为:user_0,user_1,user_2,并且对表进行CRUD操作,按id分片
将用户(account)表,进行水平分表,分为:account_0,account_1,account_2,并且对表进行CRUD操作,按user_id分片
1、SQL:
//创建数据表
CREATE TABLE user_0/1/2 (
id BIGINT(20) NOT NULL COMMENT 'Id',
name VARCHAR(20) NOT NULL COMMENT '名称',
phone VARCHAR(20) NOT NULL COMMENT '电话',
email VARCHAR(20) NOT NULL COMMENT '邮箱',
PRIMARY KEY (id)
)
CREATE TABLE account_0/1/2 (
id BIGINT(20) NOT NULL COMMENT 'Id',
user_id BIGINT(20) NOT NULL COMMENT 'user_id',
user_name VARCHAR(20) NOT NULL COMMENT '用户名',
PRIMARY KEY (id)
)
2、properties配置:
#sharding-jdbc 水平分库及分表规则配置
# 数据源名称,多数据源逗号隔开
spring.shardingsphere.datasource.names=ds0,ds1
# 配置第一个库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3307/sharding_0?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# 配置第二个库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3307/sharding_1?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# 对数据同时进行分库和分表(ds0/ds1及user_0/1/2,account_0/1/2)
# 如果大多数数据库都是以id为分片键,则写入通过default-database-strategy使用,其余以其他分键的表则使用tables.xxx.database-strategy
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column = id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression =ds$->{
id % 2}
# 单独分库策略,以user表的id为分片键,分库策略为id % 2
#spring.shardingsphere.sharding.tables.user.database-strategy.inline.sharding-column = id
#spring.shardingsphere.sharding.tables.user.database-strategy.inline.algorithm-expression =ds$->{id % 2}
# 单独分库策略,以account表的id为分片键,分库策略为id % 2
#spring.shardingsphere.sharding.tables.account.database-strategy.inline.sharding-column = id
#spring.shardingsphere.sharding.tables.account.database-strategy.inline.algorithm-expression =ds$->{id % 2}
# user表分片策略
# 分片节点分布
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds$->{
0..1}.user_$->{
0..2}
# 指定user表的主键生成策略为SNOWFLAKE
#spring.shardingsphere.sharding.tables.user.key-generator.column=id
#spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE
# 指定user表的分片策略,分片策略包括分片键和分片算法, 分片键为id ,算法为对3取余
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{
id % 3}
# account表分片策略
# 分片节点分布
spring.shardingsphere.sharding.tables.account.actual-data-nodes=ds$->{
0..1}.account_$->{
0..2}
# 指定account表的分片策略,分片策略包括分片键和分片算法, 分片键为user_id ,算法为对3取余
spring.shardingsphere.sharding.tables.account.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.account.table-strategy.inline.algorithm-expression=account_$->{
user_id % 3}
# 打开sql输出日志
spring.shardingsphere.props.sql.show=true
3、代码实现
Controller:
@RestController
@RequestMapping("test")
public class TestController {
// TODO DEMO配置文件中,存在多种配置策略,如何只需要对某一种类型进行测试,则需要修改配置文件配置
@Resource
private TestService testService;
@GetMapping("/database/table")
public Object databaseTable() {
return testService.databaseTable();
}
}
Service:
@Service
public class TestService {
@Resource
private DatabaseTableMapper databaseTableMapper;
public Object databaseTable() {
// 插入测试
for (long i = 1; i <= 10; i++) {
//模拟ID
long id = (long) (Math.random() * 100000);
User user = new User();
user.setId(id);
user.setName("Name_" + i);
user.setPhone("phone");
user.setEmail("email");
databaseTableMapper.insertDatabaseUser(user);
Account account = new Account();
account.setId(id);
account.setUserId(user.getId());
account.setUserName("UserName_" + i);
databaseTableMapper.insertDatabaseAccount(account);
}
// 修改测试(模拟修改Id为1的数据)
databaseTableMapper.updateDatabaseUserById(100L, "修改名称");
// 删除测试(模拟修改Id为2的数据)
databaseTableMapper.deleteDatabaseUserById(200L);
// 修改测试(模拟修改Id为1的数据)
databaseTableMapper.updateDatabaseAccountById(100L, "修改名称");
// 删除测试(模拟修改Id为2的数据)
databaseTableMapper.deleteDatabaseAccountById(200L);
// 查询测试
List<User> userLIst = databaseTableMapper.listAllDatabaseUser();
List<Account> accountList = databaseTableMapper.listAllDatabaseAccount();
Map<String, Object> map = new HashMap<>();
map.put("user", userLIst);
map.put("account", accountList);
return map;
}
}
Mapper
@Mapper
public interface DatabaseTableMapper {
int insertDatabaseUser(User user);
int deleteDatabaseUserById(Long id);
int updateDatabaseUserById(@Param("id") Long id, @Param("name") String name);
List<User> listAllDatabaseUser();
int insertDatabaseAccount(Account account);
int deleteDatabaseAccountById(Long id);
int updateDatabaseAccountById(@Param("id") Long id, @Param("userName") String userName);
List<Account> listAllDatabaseAccount();
}
Mapping
<?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">
<mapper namespace="com.sharding.mapper.DatabaseTableMapper">
<insert id="insertDatabaseUser" parameterType="com.sharding.model.entity.User">
insert into user(id, name, phone, email)
values (#{id},{name},{phone},{email})
</insert>
<delete id="deleteDatabaseUserById">
delete
from user
where id ={id}
</delete>
<update id="updateDatabaseUserById">
update
user
set name ={name}
where id ={id}
</update>
<select id="listAllDatabaseUser"
resultType="com.sharding.model.entity.User">
select *
from user
order by id desc
</select>
<insert id="insertDatabaseAccount" parameterType="com.sharding.model.entity.User">
insert into account(id, user_id, user_name)
values (#{id},{userId},{userName})
</insert>
<delete id="deleteDatabaseAccountById">
delete
from account
where id ={id}
</delete>
<update id="updateDatabaseAccountById">
update
account
set user_name ={userName}
where id ={id}
</update>
<select id="listAllDatabaseAccount"
resultType="com.sharding.model.entity.Account">
select *
from account
order by id desc
</select>
</mapper>
4、效果:
公共表属于系统中数据量较小,变动少,而且属于高频联合查询的依赖表。比如:参数表、数据字典表等属于此类型。可以在分库时将这类表在每个数据库都保存一份,当更新操作时SQL同时发送到所有分库进行执行,保证所有库中的公共表的数据一致。
如果不进行公共表配置,会导致数据被随机写入到不同库中。
操作数据库:sharding_0、sharding_1
公共表:tb_dict
1、SQL:
//创建数据表
CREATE TABLE tb_dict (
id BIGINT(20) NOT NULL COMMENT 'Id',
name VARCHAR(20) NOT NULL COMMENT '名称',
value VARCHAR(20) NOT NULL COMMENT '名称'
PRIMARY KEY (id)
)
2、properties配置:
# 指定为公共表,多个逗号隔开
spring.shardingsphere.sharding.broadcast-tables=tb_dict
比如:
#sharding-jdbc 水平分库 操作公共表
# 数据源名称,多数据源逗号隔开
spring.shardingsphere.datasource.names=ds0,ds1
# 配置第一个库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3307/sharding_0?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# 配置第二个库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3307/sharding_1?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# 对数据同时进行分库和分表(ds0/ds1)
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column = id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression =ds$->{
id % 2}
# 指定为公共表
spring.shardingsphere.sharding.broadcast-tables=tb_dict
# 打开sql输出日志
spring.shardingsphere.props.sql.show=true
3、代码实现
Controller:
@RestController
@RequestMapping("test")
public class TestController {
// TODO DEMO配置文件中,存在多种配置策略,如何只需要对某一种类型进行测试,则需要修改配置文件配置
@Resource
private TestService testService;
@GetMapping("/database/common")
public Object databaseCommon() {
return testService.databaseCommon();
}
}
Service:
@Service
public class TestService {
@Resource
private DatabaseCommonMapper databaseCommonMapper;
public Object databaseCommon() {
for (long i = 1; i <= 10; i++) {
Dict dict = new Dict();
dict.setId(i);
dict.setName("测试名称_" + 1);
dict.setValue(i + "");
databaseCommonMapper.insertDatabaseCommon(dict);
}
// 修改测试(模拟修改Id为1的数据)
databaseCommonMapper.updateDatabaseCommonById(1L, "修改名称");
// 删除测试(模拟修改Id为2的数据)
databaseCommonMapper.deleteDatabaseCommonById(2L);
return "操作公共表";
}
}
Mapper
@Mapper
public interface DatabaseCommonMapper {
int insertDatabaseCommon(Dict dict);
int deleteDatabaseCommonById(Long id);
int updateDatabaseCommonById(@Param("id") Long id, @Param("name") String name);
}
Mapping
<?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">
<mapper namespace="com.sharding.mapper.DatabaseCommonMapper">
<insert id="insertDatabaseCommon" parameterType="com.sharding.model.entity.User">
insert into tb_dict(id, name, value)
values (#{id},{name},{value})
</insert>
<delete id="deleteDatabaseCommonById">
delete
from tb_dict
where id ={id}
</delete>
<update id="updateDatabaseCommonById">
update
tb_dict
set name ={name}
where id ={id}
</update>
</mapper>
4、效果:
指分片规则一致的主表和子表(join表)。例如: t_order 表和 t_order_item 表,均按照 order_id 分片,绑定表之间的分区键完全相同,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。
// 在原有的分片策略基础上,加上以下配置:
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
比如:t_order 分片为t_order_0/1,t_order_item分片为t_order_item0/1
<!--执行SQL-->
SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10,11);
在不配置绑定表关系时,假设分片键 order_id 将数值10路由至第0片,将数值11路由至第1片,那么路由后的SQL应该为4条,它们呈现为笛卡尔积:
SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in(10, 11);
SELECT i.* FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in(10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in(10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in(10, 11);
在配置绑定表关系后,路由的SQL应该为2条:
SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in(10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in(10, 11);
在需要使用到事务的service使用以下注解即可:
@ShardingTransactionType(TransactionType.LOCAL)
@Transactional
注意:@ShardingTransactionType
需要同Spring的@Transactional
配套使用,事务才会生效。
SpringBoot-Admin 服务监控 简单介绍 Spring Boot Actuator 是 Spring Boot 自带的一个功能模块, 提供了一组已经开箱即用的生产环境下常用
我想查找通过关键字匹配字段 nameEnglish 或 nameChinese 的模型列表。我花了一个多小时谷歌搜索但我做不到。请帮忙。 Springboot Mongo 入门示例 https://s
(请注意:在调查 this issue 时,我更好地发现了我在此处介绍的问题根源) 我对 Hibernate 和 SpringBoot 非常陌生。我的项目涉及一个搜索引擎,其中索引(javafx 客户
我最近有一个 Web 应用程序从 springboot 升级到 springboot 2。当我将其部署到 Tomcat 8 时,它似乎启动了,但没有完全启动。 在 localhost.2019-09-
我是 Spring boot 的新手...我在运行 Controller 时遇到问题, Description: Field todoService in com.springboot.todoCon
我有一个SpringBoot应用程序,它使用以下配置与PostgreSQL通信,通过AWS Beanstrik部署:。在我将AWS Aurora证书更新为rds-ca-ecc384-g1之前,一切都很
实在是不知道标题写什么了 可以在评论区给个建议哈哈哈哈 先用这个作为标题吧 尝试使用 国内给出的 AI 大模型做出一个 可以和 AI 对话的 网站出来 使用 智普AI 只能 在控制
一、介绍 在实际的软件系统开发过程中,由于业务的需求,在代码层面实现数据的脱敏还是远远不够的,往往还需要在数据库层面针对某些关键性的敏感信息,例如:身份证号、银行卡号、手机号、工资等信息进行加密存储
Selenium Selenium是一个用于Web应用程序自动化测试的开源工具套件。它主要用于以下目的: 浏览器自动化:Selenium能够模拟真实用户在不同浏览器(如Chrome、Fire
一、简介 在实际的项目开发过程中,经常需要用到邮件通知功能。例如,通过邮箱注册,邮箱找回密码,邮箱推送报表等等,实际的应用场景非常的多。 早期的时候,为了能实现邮件的自动发送功能,通常会使用 Ja
SpringBoot:基于redis自定义注解实现后端接口防重复提交校验 一、添加依赖 org.springframework.boot spring
SpringBoot:使用Jackson完成全局序列化配置 一、测试准备 com.fasterxml.jackson.core jackson-cor
springboot:整合rocketmq 一、简易消息操作 生产者整合mq 导入依赖 org.springframework.boot
springboot:常用注解 一、spring常用注解 包扫描+组件标注注解 @Component:泛指各种组件 @Controller、@Service、@Repository都可以称为@Comp
我们经常需要在两个系统之间进行一些数据的交互,这时候我们就需要开发数据交互接口。 一般来说,遇到比较多的接口有HTTP接口、WebService接口、FTP文件传输。今天我要来学习一下在SpringB
背景 近期项目上线,甲方要求通过安全检测才能进行验收,故针对扫描结果对系统进行了一系列的安全加固,本文对一些常见的安全问题及防护策略进行介绍,提供对应的解决方案 跨站脚本攻击 XSS常发生于论坛评论等
1.排除 Spring-boot-starter 默认的日志配置 将原本的 spring-boot-starter 改为 org.springframework.boot
springboot:解决跨域问题 一、跨域简介 URL的组成: // 协议 + 域名(子域名 + 主域名) + 端口号 + 资源地址 http://www.baidu.com:8080/ 只要协
一、自定义Starter 的思路: 创建一个Maven工程,创建三个模块 一个模块为demo-app,一个模块为demo-module,一个模块为demo-module-springboot-star
1.pom.xml 4.0.0 org.springframework.boot spring-boot-starter-parent
我是一名优秀的程序员,十分优秀!