MyBatis添加Sharding-JDBC实现分库分表二维拆分

Sharding-jdbc不需要第三方服务支持,只需要将对应jar包及配置信息添加到项目中即可。这样做的优点和缺点都很明显,不需要第三发服务,效率高,但是如果修改逻辑,需要调整代码。

pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
    dependency>
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
        <version>2.1.1.RELEASEversion>
    dependency>
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        <version>2.1.1.RELEASEversion>
    dependency>
    <dependency>
        <groupId>org.mybatis.spring.bootgroupId>
        <artifactId>mybatis-spring-boot-starterartifactId>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
    dependency>
    <dependency>
        <groupId>org.apache.shardingspheregroupId>
        <artifactId>sharding-jdbc-spring-namespaceartifactId>
        <version>4.1.0version>
    dependency>
    <dependency>
        <groupId>org.apache.shardingspheregroupId>
        <artifactId>sharding-jdbc-spring-boot-starterartifactId>
        <version>4.1.0version>
    dependency>
    <dependency>
        <groupId>com.baomidougroupId>
        <artifactId>mybatis-plus-boot-starterartifactId>
        <version>3.4.0version>
    dependency>
    <dependency>
        <groupId>org.apache.commonsgroupId>
        <artifactId>commons-dbcp2artifactId>
        <version>2.8.0version>
    dependency>
dependencies>

Application

@MapperScan("com.cloud.demo.sharding.mapper")
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class ShardingJdbcApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShardingJdbcApplication.class, args);
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

User

@TableName("t_user")
public class User {

    @TableId(type = IdType.AUTO)
    private Integer id;
    private Integer userId;
    private String name;
    private  Integer age;

	// getter and setter...
}

UserMapper

public interface UserMapper extends BaseMapper<User> {
}

UserService

public interface UserService extends IService<User> {
}

UserServiceImpl

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

bootstrap.yml

指定两个数据库,每个数据库有3个t_user表,求余获取存放表位置

server:
  port: 8078

spring:
  application:
    name: sharding

  cloud:
    nacos:
      config:
        enable: true
        server-addr: localhost:8848
      discovery:
        enabled: true
        server-addr: localhost:8848


  shardingsphere:
    datasource:
      names: sharding0,sharding1 # 此处name应和数据库name一致
      sharding0:
        type: org.apache.commons.dbcp2.BasicDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding0
        username: root
        password: root
      sharding1:
        type: org.apache.commons.dbcp2.BasicDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding1
        username: root
        password: root

    sharding:
      default-database-strategy:
        inline:
          sharding-column: user_id
          algorithm-expression: sharding$->{user_id % 2}

      tables:
        t_user:
          table-strategy:
            inline:
              sharding-column: user_id
              algorithm-expression: t_user_$->{user_id % 3}

          actual-data-nodes: sharding$->{0..1}.t_user_$->{0..2}

初始化sql

创建两个MySQL数据库,名称sharding0,sharding1,分别执行以下sql

/*
Navicat MySQL Data Transfer

Source Server         : 127.0.0.1
Source Server Version : 50728
Source Host           : 127.0.0.1:3306
Source Database       : sharding0

Target Server Type    : MYSQL
Target Server Version : 50728
File Encoding         : 65001

Date: 2020-11-02 17:37:00
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user_0
-- ----------------------------
DROP TABLE IF EXISTS `t_user_0`;
CREATE TABLE `t_user_0` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user_1
-- ----------------------------
DROP TABLE IF EXISTS `t_user_1`;
CREATE TABLE `t_user_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user_2
-- ----------------------------
DROP TABLE IF EXISTS `t_user_2`;
CREATE TABLE `t_user_2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

UserController

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/detail")
    public String detail(@RequestParam("userId") Integer userId) {
        User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
        return JSONObject.toJSONString(user);
    }

    @GetMapping("/add")
    public String add() {
        User user = new User();
        user.setUserId(Long.valueOf(System.currentTimeMillis() % 10000).intValue());
        System.out.println("User id: " + user.getUserId() + ", routed for db: " + user.getUserId() % 2 + " table:" + user.getUserId() % 3);
        user.setAge(new Random().nextInt(80) + 1);
        user.setName("Sharding_" + user.getUserId());
        userService.save(user);
        return "success";
    }

    @GetMapping("/list")
    public String list(@RequestParam("current") Integer current, @RequestParam("size") Integer size) {
        IPage<User> page = new Page<>(current, size);
        page = userService.page(page, new LambdaQueryWrapper<User>().orderByDesc(User::getUserId));
        return JSONArray.toJSONString(page.getRecords());
    }
}

你可能感兴趣的:(Sharding-JDBC)