当前位置: 首页 > news >正文

石家庄网站建设外包/域名污染查询网站

石家庄网站建设外包,域名污染查询网站,安装wordpress步骤,网页设计和网站建设是同一回事吗文章目录 一、水平分库1. 将原有order_db库拆分为order_db_1、order_db_22. 分片规则修改分片策略standardcomplexinlinehintnone 3. 插入测试4. 查询测试5. 使用分库分片键查询测试总结 二、公共表1. 创建数据库2. 在Sharding-JDBC规则中修改3. 数据操作4. 字典操作测试5. 字典…

文章目录

  • 一、水平分库
    • 1. 将原有order_db库拆分为order_db_1、order_db_2
    • 2. 分片规则修改
      • 分片策略
        • standard
        • complex
        • inline
        • hint
        • none
    • 3. 插入测试
    • 4. 查询测试
    • 5. 使用分库分片键查询测试
    • 总结
  • 二、公共表
    • 1. 创建数据库
    • 2. 在Sharding-JDBC规则中修改
    • 3. 数据操作
    • 4. 字典操作测试
    • 5. 字典关联查询测试
    • 总结分库分表配置大概流程:
  • 三、读写分离
    • 1.理解读写分离
    • 2.实现sharding-jdbc读写分离
      • 1. 在Sharding-JDBC规则中修改


一、水平分库

前面已经介绍过,水平分表是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。并且在前面的文章中(快速入门),我们已经对水平分库进行代码实现,这里不再重复介绍。

水平分库是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。接下来看一下如何使用Sharding-JDBC实现水平分库,咱们继续对快速入门中的例子进行完善。

1. 将原有order_db库拆分为order_db_1、order_db_2

在这里插入图片描述
数据库表

CREATE DATABASE `order_db_1` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
CREATE DATABASE `order_db_2` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';DROP TABLE IF EXISTS `t_order_1`;
CREATE TABLE `t_order_1` (
`order_id` bigint(20) NOT NULL COMMENT '订单id',
`price` decimal(10, 2) NOT NULL COMMENT '订单价格',
`user_id` bigint(20) NOT NULL COMMENT '下单用户id',
`status` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `t_order_2`;
CREATE TABLE `t_order_2` (
`order_id` bigint(20) NOT NULL COMMENT '订单id',
`price` decimal(10, 2) NOT NULL COMMENT '订单价格',
`user_id` bigint(20) NOT NULL COMMENT '下单用户id',
`status` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

引入maven依赖

<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding‐jdbc‐spring‐boot‐starter</artifactId><version>4.0.0‐RC1</version>
</dependency>

2. 分片规则修改

由于数据库拆分了两个,这里需要配置两个数据源。
分库需要配置分库的策略,和分表策略的意义类似,通过分库策略实现数据操作针对分库的数据库进行操作。

# 定义多个数据源
server.port=8889spring.application.name = sharding-jdbc-simple-demoserver.servlet.context-path = /sharding-jdbc-simple-demo
spring.http.encoding.enabled = true
spring.http.encoding.charset = UTF-8
spring.http.encoding.force = truespring.main.allow-bean-definition-overriding = truemybatis.configuration.map-underscore-to-camel-case = true#sharding-jdbc分片规则配置
#数据源
spring.shardingsphere.datasource.names = m1,m2spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url = jdbc:mysql://localhost:3308/order_db_1?useUnicode=true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 123456spring.shardingsphere.datasource.m2.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url = jdbc:mysql://localhost:3308/order_db_2?useUnicode=true
spring.shardingsphere.datasource.m2.username = root
spring.shardingsphere.datasource.m2.password = 123456# 分库策略,以user_id为分片键,分片策略为user_id % 2 + 1,user_id为偶数操作m1数据源,否则操作m2。
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression = m$->{user_id % 2 + 1}# 指定t_order表的数据分布情况,配置数据节点 m.t_order_1,m1.t_order_2,m2.t_order_1,m2.t_order_21
# 如果这里配置如m1.t_order_$->{1..2},则查询时只会查询m1库的表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes = m$->{1..2}.t_order_$->{1..2}# 指定t_order表的主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE# 指定t_order表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column = order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$->{order_id % 2 + 1}# 打开sql输出日志
spring.shardingsphere.props.sql.show = trueswagger.enable = truelogging.level.root = info
logging.level.org.springframework.web = info
logging.level.com.itheima.dbsharding  = debug
logging.level.druid.sql = debug

分库策略定义方式如下:

#分库策略,如何将一个逻辑表映射到多个数据源
spring.shardingsphere.sharding.tables.<逻辑表名称>.database‐strategy.<分片策略>.<分片策略属性名> = #分片策略属性值
#分表策略,如何将一个逻辑表映射为多个实际表
spring.shardingsphere.sharding.tables.<逻辑表名称>.table‐strategy.<分片策略>.<分片策略属性名> = #分片策略属性值

分片策略

Sharding-JDBC支持以下几种分片策略:
不管理分库还是分表,策略基本一样。

standard

standard:标准分片策略,对应StandardShardingStrategy。
提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。
StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。
PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。
RangeShardingAlgorithm是可选的,用于处理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

complex

complex:符合分片策略,对应ComplexShardingStrategy。复合分片策略。
提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。
ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

inline

inline:行表达式分片策略,对应InlineShardingStrategy。
使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。
对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为 t_user_0 到t_user_7 。

hint

hint:Hint分片策略,对应HintShardingStrategy。
通过Hint而非SQL解析的方式分片的策略。对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。
例:内部系统,按照员工登录主键分库,而数据库中并无此字段。SQL Hint支持通过Java API和SQL注释(待实现)两种方式使用。

none

none:不分片策略,对应NoneShardingStrategy。不分片的策略。

目前例子中都使用inline分片策略,若对其他分片策略细节若感兴趣,请查阅官方文档:
https://shardingsphere.apache.org

3. 插入测试

修改testInsertOrder方法,插入数据中包含不同的user_id

@Test
public void testInsertOrder(){for(int i=1;i<20;i++){//插入时根据分库策略,userId为奇数时插入到sharding_db_2中(偶数则sharding_db_1)orderDao.insertOrder(new BigDecimal(i),2L,"SUCCESS");}
}

执行testInsertOrder输出:

...
2024-09-02 21:21:50.473  INFO 25308 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 21:21:50.473  INFO 25308 --- [           main] ShardingSphere-SQL                       : Logic SQL: insert into t_order(price,user_id,status)values(?,?,?)
2024-09-02 21:21:50.473  INFO 25308 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=t_order, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=user_id, tableName=t_order), operator=EQUAL, compareOperator=null, positionValueMap={}, positionIndexMap={0=1})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_order, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=19)], parametersIndex=3, logicSQL=insert into t_order(price,user_id,status)values(?,?,?)), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[price, user_id, status], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@518ddd3b, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@939ff41, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@6e0e5dec])])
2024-09-02 21:21:50.474  INFO 25308 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: insert into t_order_1 (price, user_id, status, order_id) VALUES (?, ?, ?, ?) ::: [18, 1, SUCCESS, 1037476657251745792]
2024-09-02 21:21:50.476 DEBUG 25308 --- [           main] c.i.d.simple.dao.OrderDao.insertOrder    : <==    Updates: 1
2024-09-02 21:21:50.476 DEBUG 25308 --- [           main] c.i.d.simple.dao.OrderDao.insertOrder    : ==>  Preparing: insert into t_order(price,user_id,status)values(?,?,?)
2024-09-02 21:21:50.476 DEBUG 25308 --- [           main] c.i.d.simple.dao.OrderDao.insertOrder    : ==> Parameters: 19(BigDecimal), 1(Long), SUCCESS(String)
2024-09-02 21:21:50.476  INFO 25308 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 21:21:50.476  INFO 25308 --- [           main] ShardingSphere-SQL                       : Logic SQL: insert into t_order(price,user_id,status)values(?,?,?)
2024-09-02 21:21:50.476  INFO 25308 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=t_order, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=user_id, tableName=t_order), operator=EQUAL, compareOperator=null, positionValueMap={}, positionIndexMap={0=1})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_order, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=19)], parametersIndex=3, logicSQL=insert into t_order(price,user_id,status)values(?,?,?)), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[price, user_id, status], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@518ddd3b, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@939ff41, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@6e0e5dec])])
2024-09-02 21:21:50.476  INFO 25308 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: insert into t_order_2 (price, user_id, status, order_id) VALUES (?, ?, ?, ?) ::: [19, 1, SUCCESS, 1037476657264328705]
2024-09-02 21:21:50.478 DEBUG 25308 --- [           main] c.i.d.simple.dao.OrderDao.insertOrder    : <==    Updates: 1

通过日志可以看出,根据user_id的奇偶不同,数据分别落在了不同数据源,达到目标。

4. 查询测试

调用快速入门的查询接口进行测试:

@Test
public void testSelectOrderbyIds(){List<Long> ids = new ArrayList<>();ids.add(1037479531180457984L);ids.add(1037479530777804801L);List<Map> maps = orderDao.selectOrderbyIds(ids);System.out.println(maps);
}

通过日志发现,sharding-jdbc将sql路由到m1和m2:

2024-09-02 21:34:14.292 DEBUG 29104 --- [           main] c.i.d.s.dao.OrderDao.selectOrderbyIds    : ==>  Preparing: select * from t_order t where t.order_id in ( ? , ? )
2024-09-02 21:34:14.308 DEBUG 29104 --- [           main] c.i.d.s.dao.OrderDao.selectOrderbyIds    : ==> Parameters: 1037479531180457984(Long), 1037479530777804801(Long)
2024-09-02 21:34:14.678  INFO 29104 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 21:34:14.679  INFO 29104 --- [           main] ShardingSphere-SQL                       : Logic SQL: select *  from t_order t  where t.order_id in   (   ?   ,  ?   )
2024-09-02 21:34:14.679  INFO 29104 --- [           main] ShardingSphere-SQL                       : SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=t_order, alias=Optional.of(t))]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=order_id, tableName=t_order), operator=IN, compareOperator=null, positionValueMap={}, positionIndexMap={0=0, 1=1})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_order, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=2, logicSQL=select *  from t_order t  where t.order_id in   (   ?   ,  ?   ))), containStar=true, firstSelectItemStartIndex=7, selectListStopIndex=7, groupByLastIndex=0, items=[StarSelectItem(owner=Optional.absent())], groupByItems=[], orderByItems=[], limit=null, subqueryStatement=null, subqueryStatements=[], subqueryConditions=[])
2024-09-02 21:34:14.680  INFO 29104 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: select *  from t_order_1 t  where t.order_id in   (   ?   ,  ?   ) ::: [1037479531180457984, 1037479530777804801]
2024-09-02 21:34:14.680  INFO 29104 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: select *  from t_order_2 t  where t.order_id in   (   ?   ,  ?   ) ::: [1037479531180457984, 1037479530777804801]
2024-09-02 21:34:14.680  INFO 29104 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: select *  from t_order_1 t  where t.order_id in   (   ?   ,  ?   ) ::: [1037479531180457984, 1037479530777804801]
2024-09-02 21:34:14.680  INFO 29104 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: select *  from t_order_2 t  where t.order_id in   (   ?   ,  ?   ) ::: [1037479531180457984, 1037479530777804801]
2024-09-02 21:34:14.721 DEBUG 29104 --- [           main] c.i.d.s.dao.OrderDao.selectOrderbyIds    : <==      Total: 2

当只查询偶数结尾的id时

    @Testpublic void testSelectOrderbyId(){//观察查询一个id和多个id的区别List<Long> ids = new ArrayList<>();ids.add(1037479531180457984L);
//        ids.add(1037479530777804801L);List<Map> maps = orderDao.selectOrderbyIds(ids);System.out.println(maps);}

通过日志发现,sharding-jdbc将sql路由到m1和m2,并且只查询两个库中的t_order_1表:

2024-09-02 21:35:15.602 DEBUG 35388 --- [           main] c.i.d.s.dao.OrderDao.selectOrderbyIds    : ==>  Preparing: select * from t_order t where t.order_id in ( ? )
2024-09-02 21:35:15.616 DEBUG 35388 --- [           main] c.i.d.s.dao.OrderDao.selectOrderbyIds    : ==> Parameters: 1037479531180457984(Long)
2024-09-02 21:35:15.989  INFO 35388 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 21:35:15.990  INFO 35388 --- [           main] ShardingSphere-SQL                       : Logic SQL: select *  from t_order t  where t.order_id in   (   ?   )
2024-09-02 21:35:15.991  INFO 35388 --- [           main] ShardingSphere-SQL                       : SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=t_order, alias=Optional.of(t))]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=order_id, tableName=t_order), operator=IN, compareOperator=null, positionValueMap={}, positionIndexMap={0=0})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_order, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=1, logicSQL=select *  from t_order t  where t.order_id in   (   ?   ))), containStar=true, firstSelectItemStartIndex=7, selectListStopIndex=7, groupByLastIndex=0, items=[StarSelectItem(owner=Optional.absent())], groupByItems=[], orderByItems=[], limit=null, subqueryStatement=null, subqueryStatements=[], subqueryConditions=[])
2024-09-02 21:35:15.991  INFO 35388 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: select *  from t_order_1 t  where t.order_id in   (   ?   ) ::: [1037479531180457984]
2024-09-02 21:35:15.991  INFO 35388 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: select *  from t_order_1 t  where t.order_id in   (   ?   ) ::: [1037479531180457984]
2024-09-02 21:35:16.073 DEBUG 35388 --- [           main] c.i.d.s.dao.OrderDao.selectOrderbyIds    : <==      Total: 1

5. 使用分库分片键查询测试

由于查询语句中并没有使用分片键user_id,所以sharding-jdbc将广播路由到每个数据结点。
下边我们在sql中添加分片键进行查询。
在OrderDao中定义接口:

@Mapper
@Component
public interface OrderDao {/*** 根据id列表和用户id查询订单* @param orderIds* @return*/@Select("<script>" +"select" +" * " +" from t_order t " +" where t.order_id in " +" <foreach collection='orderIds' open='(' separator=',' close=')' item='id'>" +" #{id} " +" </foreach>" +" and user_id = #{userId} " +"</script>")List<Map> selectOrderbyUserAndIds(@Param("userId") Long userId,@Param("orderIds") List<Long> orderIds);
}

编写测试方法:

    @Testpublic void testSelectOrderbyUserAndIds(){List<Long> ids = new ArrayList<>();ids.add(1037479531180457984L);
//        ids.add(1037479530777804801L);List<Map> maps = orderDao.selectOrderbyUserAndIds(2L,ids);System.out.println(maps);}

查看输出日志:

2024-09-02 21:42:30.440 DEBUG 16652 --- [           main] c.i.d.s.d.O.selectOrderbyUserAndIds      : ==>  Preparing: select * from t_order t where t.order_id in ( ? ) and user_id = ?
2024-09-02 21:42:30.455 DEBUG 16652 --- [           main] c.i.d.s.d.O.selectOrderbyUserAndIds      : ==> Parameters: 1037479531180457984(Long), 2(Long)
2024-09-02 21:42:30.867  INFO 16652 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 21:42:30.869  INFO 16652 --- [           main] ShardingSphere-SQL                       : Logic SQL: select *  from t_order t  where t.order_id in   (   ?   )  and user_id = ?
2024-09-02 21:42:30.869  INFO 16652 --- [           main] ShardingSphere-SQL                       : SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=t_order, alias=Optional.of(t))]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=order_id, tableName=t_order), operator=IN, compareOperator=null, positionValueMap={}, positionIndexMap={0=0}), Condition(column=Column(name=user_id, tableName=t_order), operator=EQUAL, compareOperator==, positionValueMap={}, positionIndexMap={0=1})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_order, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=2, logicSQL=select *  from t_order t  where t.order_id in   (   ?   )  and user_id = ?)), containStar=true, firstSelectItemStartIndex=7, selectListStopIndex=7, groupByLastIndex=0, items=[StarSelectItem(owner=Optional.absent())], groupByItems=[], orderByItems=[], limit=null, subqueryStatement=null, subqueryStatements=[], subqueryConditions=[])
2024-09-02 21:42:30.869  INFO 16652 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: select *  from t_order_1 t  where t.order_id in   (   ?   )  and user_id = ? ::: [1037479531180457984, 2]
2024-09-02 21:42:30.895 DEBUG 16652 --- [           main] c.i.d.s.d.O.selectOrderbyUserAndIds      : <==      Total: 1

查询条件user_id为2,根据分片策略m$->{user_id % 2 + 1}计算得出m1,此sharding-jdbc将sql路由到m1。

总结

当使用user_id查询时,因为分库策略中以user_id为分片键,所以会在user_id为偶数操作m1数据源,又根据当查询偶数结尾的id时,根据t_order表的分片策略使用t_order_1表。所以结果为使用m1库中t_order_1表查询。
在分库分表中查条件查询时,能加上分片的字段就一定要加上查询,没有分片键时会广播路由,查询所有的数据源。

二、公共表

公共表属于系统中数据量较小,变动少,而且属于高频联合查询的依赖表。参数表、数据字典表等属于此类型。可以将这类表在每个数据库都保存一份,所有更新操作都同时发送到所有分库执行。接下来看一下如何使用Sharding-JDBC实现公共表。

1. 创建数据库

分别在user_db、order_db_1、order_db_2中创建t_dict表:

CREATE TABLE `t_user` (`user_id` bigint NOT NULL COMMENT '用户id',`fullname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户姓名',`user_type` char(1) DEFAULT NULL COMMENT '用户类型',PRIMARY KEY (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;CREATE TABLE `t_dict` (
`dict_id` bigint(20) NOT NULL COMMENT '字典id',
`type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典类型',
`code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典编码',
`value` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '字典值',
PRIMARY KEY (`dict_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2. 在Sharding-JDBC规则中修改

# 指定t_dict为公共表
spring.shardingsphere.sharding.broadcast‐tables=t_dict

完整配置

server.port=8889spring.application.name = sharding-jdbc-simple-demoserver.servlet.context-path = /sharding-jdbc-simple-demo
spring.http.encoding.enabled = true
spring.http.encoding.charset = UTF-8
spring.http.encoding.force = truespring.main.allow-bean-definition-overriding = truemybatis.configuration.map-underscore-to-camel-case = true#sharding-jdbc分片规则配置
#数据源
spring.shardingsphere.datasource.names = m1,m2,m0spring.shardingsphere.datasource.m0.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m0.url = jdbc:mysql://localhost:3308/user_db?useUnicode=true
spring.shardingsphere.datasource.m0.username = root
spring.shardingsphere.datasource.m0.password = 123456spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url = jdbc:mysql://localhost:3308/order_db_1?useUnicode=true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 123456spring.shardingsphere.datasource.m2.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url = jdbc:mysql://localhost:3308/order_db_2?useUnicode=true
spring.shardingsphere.datasource.m2.username = root
spring.shardingsphere.datasource.m2.password = 123456# 分库策略,以user_id为分片键,分片策略为user_id % 2 + 1,user_id为偶数操作m1数据源,否则操作m2。
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression = m$->{user_id % 2 + 1}# 指定t_order表的数据分布情况,配置数据节点 m.t_order_1,m1.t_order_2,m2.t_order_1,m2.t_order_21
# 如果这里配置如m1.t_order_$->{1..2},则查询时只会查询m1库的表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes = m$->{1..2}.t_order_$->{1..2}
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes = m$->{0}.t_user# 指定t_order表的主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE# 指定t_order表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column = order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$->{order_id % 2 + 1}spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression = t_user# 指定t_dict为公共表
spring.shardingsphere.sharding.broadcast‐tables=t_dict# 打开sql输出日志
spring.shardingsphere.props.sql.show = trueswagger.enable = truelogging.level.root = info
logging.level.org.springframework.web = info
logging.level.com.itheima.dbsharding  = debug
logging.level.druid.sql = debug

3. 数据操作

新增DictDao:

@Mapper
@Component
public interface DictDao {
/**
* 新增字典
* @param type 字典类型
* @param code 字典编码
* @param value 字典值
* @return
*/
@Insert("insert into t_dict(dict_id,type,code,value) value(#{dictId},#{type},#{code},#{value})")
int insertDict(@Param("dictId") Long dictId,@Param("type") String type, @Param("code")String code, @Param("value")String value);
/**
* 删除字典
* @param dictId 字典id
* @return
*/
@Delete("delete from t_dict where dict_id = #{dictId}")
int deleteDict(@Param("dictId") Long dictId);
}

4. 字典操作测试

新增单元测试方法:

@Test
public void testInsertDict(){//t_dict设置为公共表后,插入数据时会同时插入所有数据源dictDao.insertDict(1L,"user_type","1","超级管理员");dictDao.insertDict(2L,"user_type","2","二级管理员");
}

输出

2024-09-02 22:19:45.760 DEBUG 8620 --- [           main] c.i.d.simple.dao.DictDao.insertDict      : ==>  Preparing: insert into t_dict(dict_id,type,code,value) value(?,?,?,?)
2024-09-02 22:19:45.774 DEBUG 8620 --- [           main] c.i.d.simple.dao.DictDao.insertDict      : ==> Parameters: 1(Long), user_type(String), 1(String), 超级管理员(String)
2024-09-02 22:19:46.148  INFO 8620 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 22:19:46.149  INFO 8620 --- [           main] ShardingSphere-SQL                       : Logic SQL: insert into t_dict(dict_id,type,code,value) value(?,?,?,?)
2024-09-02 22:19:46.149  INFO 8620 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=t_dict, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_dict, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=18)], parametersIndex=4, logicSQL=insert into t_dict(dict_id,type,code,value) value(?,?,?,?)), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[dict_id, type, code, value], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@74d6736, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@52a33c3f, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@668625f5, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@19a20bb2])])
2024-09-02 22:19:46.150  INFO 8620 --- [           main] ShardingSphere-SQL                       : Actual SQL: m0 ::: insert into t_dict (dict_id, type, code, value) VALUES (?, ?, ?, ?) ::: [1, user_type, 1, 超级管理员]
2024-09-02 22:19:46.150  INFO 8620 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: insert into t_dict (dict_id, type, code, value) VALUES (?, ?, ?, ?) ::: [1, user_type, 1, 超级管理员]
2024-09-02 22:19:46.150  INFO 8620 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: insert into t_dict (dict_id, type, code, value) VALUES (?, ?, ?, ?) ::: [1, user_type, 1, 超级管理员]
2024-09-02 22:19:46.220 DEBUG 8620 --- [           main] c.i.d.simple.dao.DictDao.insertDict      : <==    Updates: 1
2024-09-02 22:19:46.225 DEBUG 8620 --- [           main] c.i.d.simple.dao.DictDao.insertDict      : ==>  Preparing: insert into t_dict(dict_id,type,code,value) value(?,?,?,?)
2024-09-02 22:19:46.225 DEBUG 8620 --- [           main] c.i.d.simple.dao.DictDao.insertDict      : ==> Parameters: 2(Long), user_type(String), 2(String), 二级管理员(String)
2024-09-02 22:19:46.226  INFO 8620 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 22:19:46.226  INFO 8620 --- [           main] ShardingSphere-SQL                       : Logic SQL: insert into t_dict(dict_id,type,code,value) value(?,?,?,?)
2024-09-02 22:19:46.226  INFO 8620 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=t_dict, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_dict, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=18)], parametersIndex=4, logicSQL=insert into t_dict(dict_id,type,code,value) value(?,?,?,?)), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[dict_id, type, code, value], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@74d6736, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@52a33c3f, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@668625f5, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@19a20bb2])])
2024-09-02 22:19:46.226  INFO 8620 --- [           main] ShardingSphere-SQL                       : Actual SQL: m0 ::: insert into t_dict (dict_id, type, code, value) VALUES (?, ?, ?, ?) ::: [2, user_type, 2, 二级管理员]
2024-09-02 22:19:46.226  INFO 8620 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: insert into t_dict (dict_id, type, code, value) VALUES (?, ?, ?, ?) ::: [2, user_type, 2, 二级管理员]
2024-09-02 22:19:46.226  INFO 8620 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: insert into t_dict (dict_id, type, code, value) VALUES (?, ?, ?, ?) ::: [2, user_type, 2, 二级管理员]
2024-09-02 22:19:46.232 DEBUG 8620 --- [           main] c.i.d.simple.dao.DictDao.insertDict      : <==    Updates: 1

通过日志可以看出,对t_dict的表的操作被广播至所有数据源。
测试删除字典,观察是否把所有数据源中该 公共表的记录删除。

@Test
public void testDeleteDict(){//删除公共表同理dictDao.deleteDict(2L);
}

输出

2024-09-02 22:21:37.006 DEBUG 8464 --- [           main] c.i.d.simple.dao.DictDao.deleteDict      : ==>  Preparing: delete from t_dict where dict_id = ?
2024-09-02 22:21:37.026 DEBUG 8464 --- [           main] c.i.d.simple.dao.DictDao.deleteDict      : ==> Parameters: 2(Long)
2024-09-02 22:21:37.366  INFO 8464 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 22:21:37.367  INFO 8464 --- [           main] ShardingSphere-SQL                       : Logic SQL: delete from t_dict where dict_id = ?
2024-09-02 22:21:37.367  INFO 8464 --- [           main] ShardingSphere-SQL                       : SQLStatement: DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=t_dict, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_dict, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=1, logicSQL=delete from t_dict where dict_id = ?), deleteStatement=true, updateTableAlias={t_dict=t_dict}, updateColumnValues={}, whereStartIndex=19, whereStopIndex=35, whereParameterStartIndex=0, whereParameterEndIndex=0)
2024-09-02 22:21:37.367  INFO 8464 --- [           main] ShardingSphere-SQL                       : Actual SQL: m0 ::: delete from t_dict where dict_id = ? ::: [2]
2024-09-02 22:21:37.367  INFO 8464 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: delete from t_dict where dict_id = ? ::: [2]
2024-09-02 22:21:37.367  INFO 8464 --- [           main] ShardingSphere-SQL                       : Actual SQL: m2 ::: delete from t_dict where dict_id = ? ::: [2]
2024-09-02 22:21:37.425 DEBUG 8464 --- [           main] c.i.d.simple.dao.DictDao.deleteDict      : <==    Updates: 1

5. 字典关联查询测试

字典表已在各各分库存在,各业务表即可和字典表关联查询。
定义用户关联查询dao
在UserDao中定义:

/*** 根据id列表查询多个用户* @param userIds 用户id列表* @return*/
@Select({"<script>"," select"," * "," from t_user t ,t_dict b"," where t.user_type = b.code and t.user_id in","<foreach collection='userIds' item='id' open='(' separator=',' close=')'>","#{id}","</foreach>","</script>"
})
List<Map> selectUserInfobyIds(@Param("userIds") List<Long> userIds);

测试方法:

@Test
public void testSelectUserInfobyIds(){//分库的表可以直接在库中关联查询公共表List<Long> userIds = new ArrayList<>();userIds.add(11L);userIds.add(12L);List<Map> users = userDao.selectUserInfobyIds(userIds);System.out.println(users);
}

输出

2024-09-02 22:22:53.729 DEBUG 22356 --- [           main] c.i.d.s.dao.UserDao.selectUserInfobyIds  : ==>  Preparing: select * from t_user t ,t_dict b where t.user_type = b.code and t.user_id in ( ? , ? )
2024-09-02 22:22:53.743 DEBUG 22356 --- [           main] c.i.d.s.dao.UserDao.selectUserInfobyIds  : ==> Parameters: 11(Long), 12(Long)
2024-09-02 22:22:54.081  INFO 22356 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-02 22:22:54.083  INFO 22356 --- [           main] ShardingSphere-SQL                       : Logic SQL: select  *   from t_user t ,t_dict b  where t.user_type = b.code and t.user_id in  (   ?  ,  ?  )
2024-09-02 22:22:54.083  INFO 22356 --- [           main] ShardingSphere-SQL                       : SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=t_user, alias=Optional.of(t)), Table(name=t_dict, alias=Optional.of(b))]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=user_id, tableName=t_user), operator=IN, compareOperator=null, positionValueMap={}, positionIndexMap={0=0, 1=1})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_user, quoteCharacter=NONE, schemaNameLength=0), TableToken(tableName=t_dict, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=2, logicSQL=select  *   from t_user t ,t_dict b  where t.user_type = b.code and t.user_id in  (   ?  ,  ?  ))), containStar=true, firstSelectItemStartIndex=8, selectListStopIndex=8, groupByLastIndex=0, items=[StarSelectItem(owner=Optional.absent())], groupByItems=[], orderByItems=[], limit=null, subqueryStatement=null, subqueryStatements=[], subqueryConditions=[])
2024-09-02 22:22:54.083  INFO 22356 --- [           main] ShardingSphere-SQL                       : Actual SQL: m0 ::: select  *   from t_user t ,t_dict b  where t.user_type = b.code and t.user_id in  (   ?  ,  ?  ) ::: [11, 12]
2024-09-02 22:22:54.120 DEBUG 22356 --- [           main] c.i.d.s.dao.UserDao.selectUserInfobyIds  : <==      Total: 2
[{dict_id=1, user_type=1, code=1, user_id=11, fullname=姓名11, type=user_type, value=超级管理员}, {dict_id=1, user_type=1, code=1, user_id=12, fullname=姓名12, type=user_type, value=超级管理员}]

总结分库分表配置大概流程:

  1. 先配置数据源
  2. 是否分库,是则配置分库策略
  3. 必须配置数据节点
  4. 是否要配置主键生成策略
  5. 配置每个表的分片策略

三、读写分离

1.理解读写分离

MySQL的读写分离是一种常见的数据库架构模式,用于提高数据库的可用性和扩展性。通过将读取请求分散到多个从服务器(slave servers),可以减轻主服务器(master server)的负载,从而提高读取性能。同时,写入请求仍然集中在一个主服务器上执行,保证了数据的一致性和完整性。
在这里插入图片描述

面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。 对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。
在这里插入图片描述
通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理能力。 使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。
在这里插入图片描述
读写分离的数据节点中的数据内容是一致的,而水平分片的每个数据节点的数据内容却并不相同。将水平分片和读写分离联合使用,能够更加有效的提升系统的性能。

Sharding-JDBC读写分离则是根据SQL语义的分析,将读操作和写操作分别路由至主库与从库。它提供透明化读写分离,让使用方尽量像使用一个数据库一样使用主从数据库集群。
在这里插入图片描述
Sharding-JDBC提供
一主多从
的读写分离配置,可独立使用,也可配合分库分表使用,同一线程且同一数据库连接内,如有写入操作,以后的读操作均从主库读取,用于保证数据一致性。Sharding-JDBC不提供主从数据库的数据同步功能,需要采用其他机制支持。
在这里插入图片描述

接下来,咱们对上面例子中user_db进行读写分离实现。为了实现Sharding-JDBC的读写分离,首先,要进行mysql的主从同步配置。
配置mysql主从同步可以看这篇文章:Windows环境下搭建MySQL主从同步实现读写分离

2.实现sharding-jdbc读写分离

1. 在Sharding-JDBC规则中修改

server.port=56081spring.application.name = sharding-jdbc-simple-demoserver.servlet.context-path = /sharding-jdbc-simple-demo
spring.http.encoding.enabled = true
spring.http.encoding.charset = UTF-8
spring.http.encoding.force = truespring.main.allow-bean-definition-overriding = truemybatis.configuration.map-underscore-to-camel-case = true#sharding-jdbc分片规则配置
#数据源
spring.shardingsphere.datasource.names = m1,m2,m0,s0spring.shardingsphere.datasource.m0.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m0.url = jdbc:mysql://localhost:3308/user_db?useUnicode=true
spring.shardingsphere.datasource.m0.username = root
spring.shardingsphere.datasource.m0.password = 123456spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url = jdbc:mysql://localhost:3308/order_db_1?useUnicode=true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 123456spring.shardingsphere.datasource.m2.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url = jdbc:mysql://localhost:3308/order_db_2?useUnicode=true
spring.shardingsphere.datasource.m2.username = root
spring.shardingsphere.datasource.m2.password = 123456spring.shardingsphere.datasource.s0.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver‐class‐name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.url = jdbc:mysql://localhost:3309/user_db?useUnicode=true
spring.shardingsphere.datasource.s0.username = root
spring.shardingsphere.datasource.s0.password = 123456# 主库从库逻辑数据源定义 ds0为user_db
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=s0# 分库策略,以user_id为分片键,分片策略为user_id % 2 + 1,user_id为偶数操作m1数据源,否则操作m2。
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression = m$->{user_id % 2 + 1}# 指定t_order表的数据分布情况,配置数据节点 m.t_order_1,m1.t_order_2,m2.t_order_1,m2.t_order_21
# 如果这里配置如m1.t_order_$->{1..2},则查询时只会查询m1库的表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes = m$->{1..2}.t_order_$->{1..2}
#spring.shardingsphere.sharding.tables.t_user.actual-data-nodes = m$->{0}.t_user
# t_user分表策略,固定分配至ds0的t_user真实表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes = ds0.t_user# 指定t_order表的主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE# 指定t_order表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column = order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$->{order_id % 2 + 1}spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression = t_user# 指定t_dict为公共表
spring.shardingsphere.sharding.broadcast‐tables=t_dict# 打开sql输出日志
spring.shardingsphere.props.sql.show = trueswagger.enable = truelogging.level.root = info
logging.level.org.springframework.web = info
logging.level.com.itheima.dbsharding  = debug
logging.level.druid.sql = debug...
  1. 测试
    执行testInsertUser单元测试:
@Test
public void testInsertUser2() {userDao.insertUser(16L, "姓名" + 16);//插入时在m0(主库)中
}

输出

2024-09-24 07:27:54.672 DEBUG 25836 --- [           main] c.i.d.simple.dao.UserDao.insertUser      : ==>  Preparing: insert into t_user(user_id, fullname) value(?,?)
2024-09-24 07:27:54.690 DEBUG 25836 --- [           main] c.i.d.simple.dao.UserDao.insertUser      : ==> Parameters: 16(Long), 姓名16(String)
2024-09-24 07:27:55.055  INFO 25836 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-24 07:27:55.056  INFO 25836 --- [           main] ShardingSphere-SQL                       : Logic SQL: insert into t_user(user_id, fullname) value(?,?)
2024-09-24 07:27:55.056  INFO 25836 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=t_user, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=user_id, tableName=t_user), operator=EQUAL, compareOperator=null, positionValueMap={}, positionIndexMap={0=0})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_user, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=18)], parametersIndex=2, logicSQL=insert into t_user(user_id, fullname) value(?,?)), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[user_id, fullname], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@3e36b7a0, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@60c1663c])])
2024-09-24 07:27:55.056  INFO 25836 --- [           main] ShardingSphere-SQL                       : Actual SQL: m0 ::: insert into t_user (user_id, fullname) VALUES (?, ?) ::: [16, 姓名16]
2024-09-24 07:27:55.080 DEBUG 25836 --- [           main] c.i.d.simple.dao.UserDao.insertUser      : <==    Updates: 1

可以发现插入时在m0(主库)中
通过日志可以看出,所有写操作落入m0数据源。

执行testSelectUserbyIds单元测试:

@Test
public void testSelectUserInfobyIds2() {//分库的表可以直接在库中关联查询公共表List<Long> userIds = new ArrayList<>();userIds.add(16L);List<Map> users = userDao.selectUserInfobyIds(userIds);System.out.println(users);//查询时在s0(从库)中
}

输出

2024-09-24 07:29:46.292 DEBUG 4776 --- [           main] c.i.d.s.dao.UserDao.selectUserInfobyIds  : ==>  Preparing: select * from t_user t ,t_dict b where t.user_type = b.code and t.user_id in ( ? )
2024-09-24 07:29:46.310 DEBUG 4776 --- [           main] c.i.d.s.dao.UserDao.selectUserInfobyIds  : ==> Parameters: 16(Long)
2024-09-24 07:29:46.653  INFO 4776 --- [           main] ShardingSphere-SQL                       : Rule Type: sharding
2024-09-24 07:29:46.656  INFO 4776 --- [           main] ShardingSphere-SQL                       : Logic SQL: select  *   from t_user t ,t_dict b  where t.user_type = b.code and t.user_id in  (   ?  )
2024-09-24 07:29:46.656  INFO 4776 --- [           main] ShardingSphere-SQL                       : SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=t_user, alias=Optional.of(t)), Table(name=t_dict, alias=Optional.of(b))]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=user_id, tableName=t_user), operator=IN, compareOperator=null, positionValueMap={}, positionIndexMap={0=0})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=t_user, quoteCharacter=NONE, schemaNameLength=0), TableToken(tableName=t_dict, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=1, logicSQL=select  *   from t_user t ,t_dict b  where t.user_type = b.code and t.user_id in  (   ?  ))), containStar=true, firstSelectItemStartIndex=8, selectListStopIndex=8, groupByLastIndex=0, items=[StarSelectItem(owner=Optional.absent())], groupByItems=[], orderByItems=[], limit=null, subqueryStatement=null, subqueryStatements=[], subqueryConditions=[])
2024-09-24 07:29:46.656  INFO 4776 --- [           main] ShardingSphere-SQL                       : Actual SQL: s0 ::: select  *   from t_user t ,t_dict b  where t.user_type = b.code and t.user_id in  (   ?  ) ::: [16]
2024-09-24 07:29:46.694 DEBUG 4776 --- [           main] c.i.d.s.dao.UserDao.selectUserInfobyIds  : <==      Total: 1
[{dict_id=2, user_type=1, code=1, user_id=16, fullname=姓名16, type=order_type, value=1}]

通过日志可以看出,所有查询操作落入s0数据源,达到目标。


相关文章:

Sharding-JDBC笔记03-分库分表代码示例

文章目录 一、水平分库1. 将原有order_db库拆分为order_db_1、order_db_22. 分片规则修改分片策略standardcomplexinlinehintnone 3. 插入测试4. 查询测试5. 使用分库分片键查询测试总结 二、公共表1. 创建数据库2. 在Sharding-JDBC规则中修改3. 数据操作4. 字典操作测试5. 字典…...

气膜健身馆:提升运动体验与健康的理想选择—轻空间

近年来&#xff0c;气膜健身馆作为一种新兴的运动场所&#xff0c;正逐渐受到越来越多健身爱好者的青睐。这种独特的建筑形式不仅提供了良好的运动环境&#xff0c;更在健康和运动表现上展现出诸多优势。 优越的空气质量 气膜结构的核心技术通过内外气压差形成稳定的气膜&#…...

选择更轻松:山海鲸可视化与PowerBI的深度对比

在数据分析与可视化的时代&#xff0c;选择合适的报表工具显得尤为重要。山海鲸可视化和PowerBI是市场上颇受欢迎的两款免费报表软件&#xff0c;各有特色。接下来&#xff0c;我们将从功能、优缺点等方面进行对比&#xff0c;帮助你找到最适合的工具。 山海鲸可视化 山海鲸可…...

Python Daphne库:ASGI服务的高效Web服务器

更多Python学习内容&#xff1a;ipengtao.com 随着 Web 开发技术的不断发展&#xff0c;异步编程逐渐成为构建高性能 Web 应用的主流方式。传统的 WSGI 接口已经不能满足现代异步 Web 应用的需求。ASGI&#xff08;Asynchronous Server Gateway Interface&#xff09;作为 WSGI…...

如何保护自己电脑以及服务器的ip地址

保护你的电脑和服务器的IP地址&#xff0c;可以采取以下措施&#xff1a; 1. 使用代理服务器 HTTP/HTTPS代理&#xff1a;通过代理服务器访问网络&#xff0c;隐藏真实IP地址。SOCKS代理&#xff1a;提供更高级的网络流量转发&#xff0c;可以更好地处理各种网络协议。 2. 配…...

我的创作纪念日---256days

机缘 1.总结自己的学习过程面遇到的困难的解决方案&#xff1b; 2.总结自己日常学习过程中的知识&#xff0c;以及自己的理解和看法&#xff1b; 3.帮助需要的小伙伴在自己的文章里面找到想要的答案&#xff1b; 4.共同推进CSDN社区建设&#xff1b; 5.让自己每天都去写博…...

前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革

除了调用别人的api接口使用transformer技术&#xff0c;你是否想过将大模型在浏览器中运行呢&#xff1f;尤其是WebGPU的出现&#xff0c;性能比WebGL高不少&#xff0c;很多小任务真的不再需要在一个中心运行了。 不少同学买课学python了&#xff0c;但我还是在坚持用js尝试&a…...

计算机性能指标之MFLOPS

1. MFLOPS的定义与计算方式 定义&#xff1a;MFLOPS&#xff0c;全称Million Floating-point Operations Per Second&#xff0c;即每秒百万次浮点运算&#xff0c;是衡量计算机系统浮点运算能力的一个重要技术指标。 计算方式&#xff1a;MFLOPS的计算公式为“浮点操作次数 /…...

Sharp.js:简单而又实用的图像处理库

前言 在现代Web开发中&#xff0c;图像处理是一个不可或缺的部分。 前端开发者经常需要处理图像&#xff0c;以确保它们在不同的设备和分辨率上都能保持良好的显示效果。 sharp.js是一个高性能的Node.js模块&#xff0c;它利用了libvips库&#xff0c;提供了快速且高效的图像…...

Rust环境安装配置

要加速安装 Rust 和 git-cliff&#xff0c;可以配置国内的镜像源。特别是在国内访问 Rust 官方的安装源时&#xff0c;可能会遇到速度较慢的问题。通过配置 TUNA&#xff08;清华大学开源软件镜像站&#xff09;的镜像源&#xff0c;可以大幅提升安装速度。 1. 配置国内镜像加…...

衡石分析平台系统管理手册-功能配置之全局 JS 设置

全局 JS 设置​ 衡石系统提供了全局 JS 设置功能&#xff0c;用户可以通过自定义 JS 代码实现系统的个性化需求&#xff0c;如使用第三方统计工具对系统平台的 PV 、UV 进行监测。 使用场景​ 场景1&#xff1a;增加百度统计​ 下图示例中使用 js 代码引用了百度网站统计功…...

OpenHarmony(鸿蒙南向)——平台驱动开发【MIPI DSI】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DSI&#xff08;Display Serial Interface&#x…...

C++_一篇文章让你弄懂各类(运算符)

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 内置了丰富的运算符&#xff0c;并提供了以下类型的运算符&#xff1a; 算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符 本章将逐一介绍算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和…...

顺序表算法题 —— 移除元素、删除有序数组中的重复项、合并两个有序数组

目录 一、顺序表算法题 1、移除元素 2、删除有序数组中的重复项 3、 合并两个有序数组 二、顺序表问题与思考 一、顺序表算法题 1、移除元素 移除元素 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 思路一&#xff1a;创建一个新数组&#xff0c;开辟…...

配置ssh后又报错git@github.com: Permission denied (publickey)

再添加一次ssh有用 ssh-add ~/.ssh/你的id_rsa的名字可以先运行 eval "$(ssh-agent -s)"再添加&#xff0c;Jesus每次重启terminal都要输入一遍 报错 gitgithub.com: Permission denied (publickey) 通常是由于 SSH 公钥没有正确配置或者 GitHub 上未能识别你的公钥…...

yolov10安装体验

按照官网 conda create -n yolov10 python=3.9 conda activate yolov10 pip install -r requirements.txt pip install -e . 一路安装,运行yolov10的问题,初次接触的同学可以注意。 Set arbitrary_types_allowed=True in the model_config to ignore this error f you got th…...

使用Docker-Compose部署SpringBoot项目的案例

Docker-Compose是Docker官方的一个开源项目&#xff0c;主要用于实现对Docker容器集群的快速编排和管理。该项目由Python编写&#xff0c;通过调用Docker服务提供的API来管理容器。只要所操作的平台支持Docker API&#xff0c;就可以利用Docker-Compose进行编排管理。Docker-Co…...

大话 RCU (read copy update)

还得是看官方文档。kernel/Document/RCU/WhatisRCU.rst. 首先&#xff0c;我们要搞清楚一件事&#xff0c;指针它是一个变量&#xff0c;他在内存上也是占了空间的&#xff0c;然后他里面的值&#xff0c;是你申请的内存块的首地址。文档开篇就讲咱们的基本原理&#xff0c;就…...

vue项目npm run serve 报错,Error: read ECONNRESET at TCP.onStreamRead

背景&#xff1a;vue2的项目&#xff0c;之前npm run serve一直可以正常使用&#xff0c;突然每次启动都会报错了&#xff0c;报错信息如下&#xff1a; node:events:492 throw er; // Unhandled error event ^ Error: read ECONNRESET at TCP.onStreamRead (n…...

十二、MySQL数据类型精讲

文章目录 1. MySQL中的数据类型2. 整数类型2.1 类型介绍2.2 可选属性2.2.1 M2.2.2 UNSIGNED2.2.3 ZEROFILL 2.3 适用场景2.4 如何选择&#xff1f; 3. 浮点类型3.1 类型介绍3.2 数据精度说明3.3 精度误差说明 4. 定点数类型4.1 类型介绍4.2 开发中经验 5. 位类型&#xff1a;BI…...

不同参数对分类精度的影响以及思考

1 问题 探索不同的batch_size对分类精度的影响探索不同的损失函数对分类精度的影响 2 方法 问题一 要知道的是Batch_size的作用&#xff1a;决定了下降的方向。在合理范围内&#xff0c;增大Batch_size的好处&#xff1a; 一是提高了内存利用率以及大矩阵乘法的并行化效率&…...

开源AI智能名片小程序源码:私域电商构建独特竞争力的新机遇

摘要&#xff1a;本文旨在探讨私域电商如何利用开源AI智能名片小程序源码构建独特竞争力。在强调独特性是通向成功的必要条件的基础上&#xff0c;分析开源AI智能名片小程序源码在私域电商发展独特性方面的作用及相关策略。 一、引言 在竞争激烈的商业环境中&#xff0c;让自己…...

从Web2到Web3:探索下一代互联网的无限可能性

互联网经历了从Web1到Web2的重大变革&#xff0c;现在正迈向Web3。Web2通过社交媒体、电子商务和内容平台改变了我们的数字生活&#xff0c;但同时也伴随着中心化平台的垄断和用户数据被广泛控制的问题。而Web3的出现&#xff0c;则试图通过去中心化技术解决这些挑战&#xff0…...

POE供电支持画中画的摄像头解决方案

首先他的主芯片由嵌入式操作系统和高性能硬件处理平台&#xff0c;具有较高稳定性和可靠性&#xff0c;有丰富的接口&#xff0c;可以支持二次开发定制的. 首先&#xff0c;什么是poe供电呢&#xff1f;Poe供电是通过网络线&#xff08;网线&#xff09;供电的一种技术&#x…...

Python 3 字典

Python 3 字典 引言 Python 字典(Dictionary)是一种非常有用的内置数据类型,用于存储键值对。在 Python 3 中,字典保持了一些基本特性,同时也有一些新的改进和特性。本文将详细介绍 Python 3 中的字典,包括其基本操作、常用方法以及一些高级特性。 字典的基本操作 创…...

CFR( Java 反编译器)

一、安装教程 CFR&#xff08;Class File Reader&#xff09;是一个流行的Java反编译器&#xff0c;它可以将编译后的.class文件或整个.jar文件转换回Java源代码。以下是CFR的下载和使用教程&#xff1a; 下载CFR 访问CFR的官方网站或GitHub仓库&#xff1a;CFR的最新版本和所…...

单片机的两种看门狗原理解析——IWDG和WWDG

一、IWDG独立开门狗的主要性能 计时机制&#xff1a; 递减计数器 独立开门狗的初始频率&#xff1a; LSI低速内部时钟&#xff1a;RC震荡器&#xff0c;40kHz 独立开门狗是以LSI为初始频率的&#xff0c;所以独立开门狗的初始时钟频率取决与单片机本身&#xff0c;因此在使…...

SQL进阶技巧:如何获取状态一致的分组? | 最大、最小值法

目录 0 需求描述 1 数据准备 2 问题分析 方法1&#xff1a;最大、最小值法&#xff08;技巧&#xff09; 方法2&#xff1a;常规思路 3 小结 如果觉得本文对你有帮助&#xff0c;那么不妨也可以选择去看看我的博客专栏 &#xff0c;部分内容如下&#xff1a; 数字化建设通…...

windows10使用bat脚本安装前后端环境之msyql5.7安装配置并重置用户密码

首先需要搞清楚msyql在本地是怎么安装配置、然后在根据如下步骤编写bat脚本&#xff1a; 思路 1.下载mysql5.7 zip格式安装包 2.新增data文件夹与my.ini配置文件 3.初始化数据库 4.安装mysql windows服务 5.启动并修改root密码&#xff08;新增用户初始化授予权限&#xff09…...

文件上传、amrkdown编辑器

一、文件上传 这里我以图片为例&#xff0c;进行上传&#xff0c;上传到阿里云oss&#xff08;对象存在中&#xff09; 首先&#xff0c;我们先梳理一下&#xff0c;图片上传的流程 1、前端选择文件&#xff0c;提交文件 前端提交文件&#xff0c;我们可以使用ElementUI中的…...