springboot整合sharding-jdbc操作

shardingjdbc,挺好的一个框架,现在改名叫shardingsphere了,话不多说,开始使用。

 <!-- sharding-jdbc -->
		<dependency>
		    <groupId>io.shardingsphere</groupId>
		    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
		    <version>3.0.0</version>
		</dependency>
		
		<dependency>
		    <groupId>io.shardingsphere</groupId>
		    <artifactId>sharding-jdbc-spring-namespace</artifactId>
		    <version>3.1.0</version>
		</dependency>

一、单库分表
其他的配置就不贴上去了,这是sharding相关的配置信息,根据sex取模分表

sharding:
  jdbc:
    datasource:
      names: ds0
      # 数据源ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/ljw?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true
        username: root
        password: root
    config:
      sharding:
        props:
          sql.show: true
        tables:
          t_user:  #t_user表
            key-generator-column-name: id  #主键
            actual-data-nodes: ds0.t_user${0..1}    #数据节点,均匀分布
            table-strategy:  #分表策略
              inline: #行表达式
                sharding-column: sex
                algorithm-expression: t_user${sex % 2}  #根据性别按模运算分配

这样启动会报错如下:

Description:

The bean 'dataSource', defined in class path resource [io/shardingsphere/shardingjdbc/spring/boot/SpringBootConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

所以呢,我又增加了这一行配置spring.main.allow-bean-definition-overriding=true,我懒得弄,所以直接放在property配置文件里面了,这样启动就不会出错了

-- 表结构
CREATE TABLE `t_user0` (
  `id` bigint(20) NOT NULL,
  `name` varchar(64) DEFAULT NULL COMMENT '名称',
  `city_id` int(12) DEFAULT NULL COMMENT '城市',
  `sex` tinyint(1) DEFAULT NULL COMMENT '性别',
  `phone` varchar(32) DEFAULT NULL COMMENT '电话',
  `email` varchar(32) DEFAULT NULL COMMENT '邮箱',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  `password` varchar(32) DEFAULT NULL COMMENT '密码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `t_user1` (
  `id` bigint(20) NOT NULL,
  `name` varchar(64) DEFAULT NULL COMMENT '名称',
  `city_id` int(12) DEFAULT NULL COMMENT '城市',
  `sex` tinyint(1) DEFAULT NULL COMMENT '性别',
  `phone` varchar(32) DEFAULT NULL COMMENT '电话',
  `email` varchar(32) DEFAULT NULL COMMENT '邮箱',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  `password` varchar(32) DEFAULT NULL COMMENT '密码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

实体类

@Data
public class User {

	private Long id;
	private String name;
	private String phone;
	private String email;
	private String password;
	private Integer cityId;
    private Date createTime;
    private Integer sex;
}
/**
	 * 保存用户
	 * @return
	 */
	@GetMapping("/saveUser")
	public Result saveUser() {
		 for (int i = 0; i <35 ; i++) {
            User user=new User();
            user.setName("test"+i);
            user.setCityId(new Random().nextInt(1000));
            user.setCreateTime(new Date());
            user.setSex(i%2==0?1:2);
            user.setPhone("11111111"+i);
            user.setEmail("xxxxx");
            user.setCreateTime(new Date());
            user.setPassword("eeeeeeeeeeee");
            userMapper.saveUser(user);
	    }
		return Result.ok();
	}
	
	/**
	 * 根据用户id
	 * @param id
	 * @return
	 */
	@GetMapping("/getUser/{id}")
	public Result getUser(@PathVariable("id")String id) {
		System.err.println(id);
		User user = userMapper.getUserById(id);
		return Result.ok(user);
	}
	
	/**
	 * 分页查询
	 * @param pageNum
	 * @return
	 */
	@GetMapping("/getUserTotal/{pageNum}")
	public Result getUserTotal(@PathVariable("pageNum")int pageNum) {
		PageHelper.startPage(pageNum,10);
        List<User> list = userMapper.selectList();
        PageInfo<User> pageInfo = new PageInfo<User>(list);
        pageInfo.setList(list);
		return Result.ok(pageInfo);
	}

mapper接口

public interface UserMapper {

	@Insert(" insert into t_user(name,phone,email,city_id,sex,password) values(#{user.name},#{user.phone},#{user.email},#{user.cityId},#{user.sex},#{user.password}) ")
	int saveUser(@Param("user")User user);

	@Select(" select * from t_user where id=#{id} ")
	User getUserById(@Param("id")String id);

	@Select(" select * from t_user order by name ")
	List<User> selectList();

}

二、分库分表,在刚才的基础之上加以修改就行,其他不用动,修改一下配置信息即可,按照city_id取模分库

sharding:
  jdbc:
    datasource:
      #数据源名称,多数据源以逗号分隔
      names: ds0,ds1
      # 数据源ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/ljw?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true
        username: root
        password: root
      # 数据源ds1
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/ljw_0?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true
        username: root
        password: root
    config:
      sharding:
        props:
          sql.show: true
        tables:
          #逻辑表名称(随意取名),在项目中sql使用
          t_user:  #t_user表
            key-generator-column-name: id  #主键
            actual-data-nodes: ds0.t_user${0..1}    #数据节点,均匀分布
            table-strategy:  #分表策略
              inline: #行表达式
                sharding-column: sex
                algorithm-expression: t_user${sex % 2}  #根据性别按模运算分配
            #库分片策略
            database-strategy:
              inline:
                #分片字段的名称
                sharding-column: city_id
                #分片算法
                algorithm-expression: ds$->{city_id % 2}
上一篇:sharding-jdbc使用笔记


下一篇:sharding-jdbc处理流程源码分析