SpringBoot集成Sharding-JDBC实现分库分表实战(二)

上一篇我们简单实现分库分表,:先参考文章。

1、上一篇只有在保存分库分表的 user_info表的时候,数据库不报错,其他的表操作都报错:如下

Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
### The error may involve com.huobi.earning.admin.db.mapper.TblUserMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO tbl_user   ( `name`,  city_id,  sex,  phone,  email,  create_time,  `password` )  VALUES   ( ?,  ?,  ?,  ?,  ?,  ?,  ? )
### Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
	... 122 common frames omitted
Caused by: java.lang.IllegalStateException: Missing the data source name: 'null'

tbl_user 表没有进行分库分表,执行操作时找不到默认的数据源,就报错了

2、某些表分库分表,要保证其他的表不报错,应该添加默认数据源:主要变更如下

config:
      sharding:
        tables:
          user_info:
            actual-data-nodes: pr_master_slave.user_info$->{0..1}
            database-strategy:   #分库策略
              inline: #行表达式
                sharding-column: gender        #列名称,多个列以逗号分隔
                algorithm-expression: user$->{gender % 2}    #按模运算分配
            table-strategy:  #分表策略
              inline: #行表达式
                sharding-column: user_id
                algorithm-expression: user_info$->{user_id % 2}

        default-data-source-name: pr_master_slave  #未配置分片规则的表将通过默认数据源定位
        binding-tables: user_info #绑定表规则列表
        master-slave-rules: #数据库主从的划分
          pr_master_slave:
            master-data-source-name: user0 #主数据库
            slave-data-source-names: user1 #从数据库

主从数据库,主的挂掉,用从的库;主库复制增删改,从库负责查询。

3、以上介绍单张表分库分表,下面介绍多张表分库分表,主要是该配置:

config:
      sharding:
        tables:
          user_info:
            actual-data-nodes: pr_master_slave.user_info$->{0..1}
            database-strategy:   #分库策略
              inline: #行表达式
                sharding-column: gender        #列名称,多个列以逗号分隔
                algorithm-expression: user$->{gender % 2}    #按模运算分配
            table-strategy:  #分表策略
              inline: #行表达式
                sharding-column: user_id
                algorithm-expression: user_info$->{user_id % 2}

           u_info:
            actual-data-nodes: pr_master_slave.u_info$->{0..1}
            database-strategy:   #分库策略
              inline: #行表达式
                sharding-column: gender        #列名称,多个列以逗号分隔
                algorithm-expression: user$->{gender % 2}    #按模运算分配
            table-strategy:  #分表策略
              inline: #行表达式
                sharding-column: user_id
                algorithm-expression: u_info$->{user_id % 2}

设置了两张表进行分库分表,依次往下添加。

4、当然了,分库分表有很多的规则,根据自己的实际业务场景设置是最好的方案:

比如 % 3,% 5 ,% 6  %10等等,也可以定义一个类定义分片规则:

config:
      sharding:
        tables:
          user_info:
            actual-data-nodes: pr_master_slave.user_info$->{0..9}
            table-strategy:
              standard:
                sharding-column: user_id
                precise-algorithm-class-name: com.nandan.rule.CommonShardingAlgorithm #分片规则类

CommonShardingAlgorithm 类的大概内容:


import java.util.Collection;

import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;

/**
 * 常用分表方式 实现 PreciseShardingAlgorithm 的接口
 */
public class NanDaoShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> shardingValue) {
        String tableId = shardingValue.getValue()+"";
        String key = tableId.substring(tableId.length()-1);
        int index = Integer.valueOf(key) % 10;
        for (String each : tableNames) {
            if(each.endsWith(index+"")){
                return each;
            }
        }
        return tableNames.iterator().next();
    }
}

特别注意:

A、分库分表的策略不能中途更改,取模算法的id会出错,
B、查询不支持特殊sql,包括去重,子sql,聚合等等,
C、查询会给所有表发查询sql, 带上分库, 分表的字段的查询只发一条,
D、查询数据时要注意,尽量带上分库或分表字段来查询,避免多表查sql过多,影响性能。

到此,分库分表的基本流程是可以了,下篇分享读写分离,敬请期待!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是详细流程: 1. 引入Sharding-JDBC依赖 在pom.xml文件中添加Sharding-JDBC的依赖: ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>4.1.1</version> </dependency> ``` 2. 配置数据源 在application.yml中配置数据源信息,如下所示: ```yaml spring: datasource: # 主库 master: url: jdbc:mysql://localhost:3306/db_master?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver # 从库 slave: url: jdbc:mysql://localhost:3306/db_slave?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver shardingsphere: datasource: names: master,slave # 配置主从库 master-slave-rules: ms: master-data-source-name: master slave-data-source-names: slave load-balance-algorithm-type: round_robin # 配置数据分片规则 sharding: tables: user_info: # 分库键 database-strategy: inline: sharding-column: user_id algorithm-expression: ds${user_id % 2} # 分表键 table-strategy: inline: sharding-column: order_id algorithm-expression: t_order_${order_id % 2} actual-data-nodes: master.user_info_$->{0..1} key-generator: column: id type: SNOWFLAKE ``` 3. 创建数据表 创建两个数据库db_master和db_slave,每个数据库中创建user_info表,表结构如下: ```sql CREATE TABLE `user_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `user_id` bigint(20) NOT NULL COMMENT '用户ID', `order_id` bigint(20) NOT NULL COMMENT '订单ID', `name` varchar(50) NOT NULL COMMENT '姓名', `age` int(11) NOT NULL COMMENT '年龄', `address` varchar(200) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表'; ``` 4. 测试分库分表 在代码中使用Sharding-JDBC进行数据库操作,如下所示: ```java @Service public class UserService { @Autowired private JdbcTemplate jdbcTemplate; public void addUser(UserInfo userInfo) { String sql = "INSERT INTO user_info (user_id,order_id,name,age,address) VALUES (?,?,?,?,?)"; Object[] params = new Object[]{userInfo.getUserId(), userInfo.getOrderId(), userInfo.getName(), userInfo.getAge(), userInfo.getAddress()}; jdbcTemplate.update(sql, params); } public List<UserInfo> getUserList() { String sql = "SELECT * FROM user_info"; List<UserInfo> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(UserInfo.class)); return userList; } } ``` 以上就是使用Sharding-JDBC实现单库分表的详细流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值