spring-data-jpa连接mycat实现应用的读写分离

来源:互联网 发布:舍伍德算法理解 编辑:程序博客网 时间:2024/05/29 16:28

主从复制

读写分离

本文介绍使用spring-data-jpa连接mycat实现应用的读写分离.

原文地址:spring-data-jpa连接mycat实现应用的读写分离

系统环境

  • spring-boot 1.4.3-RELEASE
  • jdk1.8

进入正题

application.yml配置文件

这个很传统,指定mysql以及datasource就可以.

特别说一句:mycat跟应用是相互独立的,mycat后边的mysql集群对于应用来说就相当于一台单独的mysql server,所以,不要纠结与应用该用什么数据库连接工具

spring:  application:    name: mycat-jpa  datasource:    platform: mysql    type: com.zaxxer.hikari.HikariDataSource    driver-class-name: com.mysql.jdbc.Driver    url: jdbc:mysql://localhost:8066/mall?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&useSSL=false    username: root    password: jiabin  jpa:    hibernate:      ddl-auto: none    show-sql: true

JpaTransactionConfig类文件

这个配置类是重点.

在使用mycat时需要关闭spring-data-jpa默认的事务管理机制.
原因如下:

  • mycat对于开启了事务的查询,插入等操作,都会走主库
  • spring-data-jpa默认的事务管理机制对查询操作执行的是只读事务,话说只读事务也是事务啊

鉴于以上两个原因.我们就得使用enableDefaultTransactions = false来关闭spring-data-jpa默认的事务管理机制.

好吧,既然我们关闭了默认的事务管理机制,我们就得使用@Transactional来开启声明式事务处理.哈哈,也就是说,我们需要用添加@Transactional注解的硬编码方式来实现事务管理.见SalesmanService

package jpa.mycat;import org.springframework.context.annotation.Configuration;import org.springframework.data.jpa.repository.config.EnableJpaRepositories;/** * Created by ssab on 17-1-4. */@EnableJpaRepositories(basePackages = "jpa.mycat", enableDefaultTransactions = false)@Configurationpublic class JpaTransactionConfig {}

弄懂了这两个配置,剩下的就简单了.

Salesman实体类

package jpa.mycat;import org.hibernate.annotations.GenericGenerator;import javax.persistence.*;/** * Created by ssab on 17-1-5. */@Entity@Table(name = "salesman")public class Salesman {  @Id  @GenericGenerator(name = "idgen", strategy = "increment")  @GeneratedValue(generator = "idgen")  @Column(name = "id")  private Long id;//业务员ID  private String userNum;//工号  private String trueName;//真实姓名  private String address;//地址  private String avatarPicUrl;//头像的图片地址  private String telephone;//固定电话:区号-号码  private String mobile;//手机号码  private int disabled;//是否作废0否1是  private String remark;//备注  private String appUserId;//备用userId字段(外勤APP用)  public Long getId() {    return id;  }  public void setId(Long id) {    this.id = id;  }  public String getUserNum() {    return userNum;  }  public void setUserNum(String userNum) {    this.userNum = userNum;  }  public String getTrueName() {    return trueName;  }  public void setTrueName(String trueName) {    this.trueName = trueName;  }  public String getAddress() {    return address;  }  public void setAddress(String address) {    this.address = address;  }  public String getAvatarPicUrl() {    return avatarPicUrl;  }  public void setAvatarPicUrl(String avatarPicUrl) {    this.avatarPicUrl = avatarPicUrl;  }  public String getTelephone() {    return telephone;  }  public void setTelephone(String telephone) {    this.telephone = telephone;  }  public String getMobile() {    return mobile;  }  public void setMobile(String mobile) {    this.mobile = mobile;  }  public int getDisabled() {    return disabled;  }  public void setDisabled(int disabled) {    this.disabled = disabled;  }  public String getRemark() {    return remark;  }  public void setRemark(String remark) {    this.remark = remark;  }  public String getAppUserId() {    return appUserId;  }  public void setAppUserId(String appUserId) {    this.appUserId = appUserId;  }  @Override  public String toString() {    return "Salesman{" +        "id=" + id +        ", userNum='" + userNum + '\'' +        ", trueName='" + trueName + '\'' +        ", address='" + address + '\'' +        ", avatarPicUrl='" + avatarPicUrl + '\'' +        ", telephone='" + telephone + '\'' +        ", mobile='" + mobile + '\'' +        ", disabled=" + disabled +        ", remark='" + remark + '\'' +        ", appUserId='" + appUserId + '\'' +        '}';  }}

SalesmanRepository

package jpa.mycat;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.Query;import java.util.List;/** * Created by ssab on 17-1-5. */public interface SalesmanRepository extends JpaRepository<Salesman, Long> {  Salesman save(Salesman salesman);  @Query(value = "select * from salesman limit 0,18", nativeQuery = true)  List<Salesman> findAll();}

SalesmanService

package jpa.mycat;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.util.List;/** * Created by ssab on 17-1-5. */@Servicepublic class SalesmanService {  @Autowired  private SalesmanRepository repository;  @Transactional(propagation = Propagation.REQUIRED)  public Salesman save(Salesman salesman) {    return repository.save(salesman);  }  @Transactional(propagation = Propagation.NOT_SUPPORTED)  public List<Salesman> findAll() {    return repository.findAll();  }}

测试

SalesmanServiceTest

package jpa.mycat;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;/** * Created by ssab on 17-1-5. */@SpringBootTest@RunWith(SpringRunner.class)public class SalesmanServiceTest {  @Autowired  private SalesmanService service;  @Test  public void testFindAll() {    service.findAll().forEach(salesman -> System.out.println(salesman.toString()));  }  @Test  public void testSave(){    Salesman salesman = new Salesman();    salesman.setUserNum("3333333");    salesman.setTrueName("ssab");    salesman.setAddress("山东省莱芜市");    salesman.setMobile("152222222");    salesman.setDisabled(0);    service.save(salesman);  }}

运行testFindAll方法,查看mycat日志

testfindall

注意看图中红框内的内容

好吧我们确定是走的从库.

运行testSave方法,查看mycat日志

testsave

从图中红框内的内容我们发现走的是主库.

总结

使用spring-data-jpa连接mycat的重点就在于关闭spring-data-jpa的默认事务管理机制并使用@Transactional注解来进行声明式事务管理.

注意这点就可以了.

代码

spring-boot-jpa连接mycat实现读写分离

0 0
原创粉丝点击