个人学习系列 - Spring Boot + ShardingSphere + JPA 实现读写分离

最近想要学习一下分库分表,可是分库分表之前可以先用数据库的读写分离来过渡一下,当然这还需要主从服务器来配合。今天就先写数据库的读写分离,以后再介绍主从服务器。。。

Mysql

1. 新建三个数据库

CREATE DATABASE database0;
USE database0;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`(
    id bigint(64) not null auto_increment,
    city varchar(20) not null,
    name varchar(20) not null,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE DATABASE database1;
USE database1;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`(
    id bigint(64) not null auto_increment,
    city varchar(20) not null,
    name varchar(20) not null,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `database1`.`user`(`id`, `city`, `name`) VALUES (001, '青岛', '测试库1');

CREATE DATABASE database2;
USE database2;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`(
    id bigint(64) not null auto_increment,
    city varchar(20) not null,
    name varchar(20) not null,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `database2`.`user`(`id`, `city`, `name`) VALUES (002, '胶州', '测试库2');

2. 新建springboot项目

2.1 pom.xml
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.3
        

        
        
            mysql
            mysql-connector-java
        

        
        
            com.alibaba
            druid-spring-boot-starter
            1.1.23
        

        
        
            io.shardingsphere
            sharding-jdbc-spring-boot-starter
            3.1.0
        

        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
2.2 application.yml
server: # 端口号
  port: 8888
sharding:
  jdbc:
    dataSource:
      names: db-test0,db-test1,db-test2
      # 配置主库
      db-test0:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://ip:3306/database0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: 账户
        password: 密码
        #最大连接数
        maxPoolSize: 20
      db-test1: # 配置第一个从库
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://ip:3306/database1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT
        username: 账户
        password: 密码
        maxPoolSize: 20
      db-test2: # 配置第二个从库
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://ip:3306/database2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT
        username: 账户
        password: 密码
        maxPoolSize: 20
    config:
      masterslave: # 配置读写分离
        load-balance-algorithm-type: round_robin # 配置从库选择策略,提供轮询与随机,这里选择用轮询//random 随机 //round_robin 轮询
        name: db1s2
        master-data-source-name: db-test0
        slave-data-source-names: db-test1,db-test2
    props:
      sql:
        show: true # 开启SQL显示,默认值: false,注意:仅配置读写分离时不会打印日志!!!
spring:
  main:
    allow-bean-definition-overriding: true # 允许重名的bean可以被覆盖
  jpa:
    hibernate:
      ddl-auto: update # 每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
      naming: # 驼峰命名法
        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
    show-sql: true # 打印sql

2.3 新建User实体类

/**
 * 实体类
 *
 * @author zhouzhaodong
 */
@Entity
@Table(name = "user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String city;

    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.4 新建 UserRepository

/**
 * 数据访问层
 *
 * @author zhouzhaodong
 */
@Repository
public interface UserRepository extends JpaRepository {
}

2.5 新建服务层UserService

/**
 * 服务层
 *
 * @author zhouzhaodong
 */
public interface UserService {

    /**
     * 新增
     *
     * @param user
     * @return
     */
    User addUser(User user);

    /**
     * 查询所有
     *
     * @return
     */
    List list();

}

2.6 新建服务层实现类UserServiceImpl

/**
 * 服务层实现类
 *
 * @author zhouzhaodong
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    UserRepository userRepository;

    @Override
    public User addUser(User user) {

        // 强制路由主库
//        HintManager.getInstance().setMasterRouteOnly();
        return userRepository.save(user);
    }

    @Override
    public List list() {
        return userRepository.findAll();
    }
}

2.7 新建控制层 UserController

/**
 * 控制层
 *
 * @author zhouzhaodong
 */
@RestController
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/users")
    public Object list() {
        return userService.list();
    }

    @PostMapping("/add")
    public Object add(String name, String city) {
        User user = new User();
        user.setCity(city);
        user.setName(name);
        return userService.addUser(user);
    }

}

2.8 启动类不需要任何操作

3. 启动项目进行测试即可

3.1 第一次访问 localhost:8888/users

个人学习系列 - Spring Boot + ShardingSphere + JPA 实现读写分离_第1张图片

3.2 第二次访问 localhost:8888/users

个人学习系列 - Spring Boot + ShardingSphere + JPA 实现读写分离_第2张图片

发现切换查询数据库了,成功了!

3.3 存储数据

个人学习系列 - Spring Boot + ShardingSphere + JPA 实现读写分离_第3张图片

查看数据库会发现只有主库进行了新增,如果配置主从关系的话,从库也会进行新增的。不过我们还没有进行配置。。。
个人学习系列 - Spring Boot + ShardingSphere + JPA 实现读写分离_第4张图片

好了,今天的教程就结束了!!!

个人博客

http://www.zhouzhaodong.xyz

源码地址:

https://github.com/zhouzhaodo...

你可能感兴趣的:(springboot,shardingsphere,jpa)