接
主从复制
读写分离
本文介绍使用spring-data-jpa连接mycat实现应用的读写分离.
原文地址:spring-data-jpa连接mycat实现应用的读写分离
这个很传统,指定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
这个配置类是重点.
在使用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)
@Configuration
public class JpaTransactionConfig {
}
弄懂了这两个配置,剩下的就简单了.
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 + '\'' +
'}';
}
}
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 findAll();
}
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.
*/
@Service
public 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 findAll() {
return repository.findAll();
}
}
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);
}
}
注意看图中红框内的内容
好吧我们确定是走的从库.
从图中红框内的内容我们发现走的是主库.
使用spring-data-jpa连接mycat的重点就在于关闭spring-data-jpa的默认事务管理机制并使用@Transactional注解来进行声明式事务管理.
注意这点就可以了.
spring-boot-jpa连接mycat实现读写分离