国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Boot 集成Mybatis實現主從(多數據源)分離方案示例

Spring Boot 集成Mybatis實現主從(多數據源)分離方案示例

2020-08-25 11:06險遠的奇偉詭怪 Java教程

本篇文章主要介紹了Spring Boot 集成Mybatis實現主從(多數據源)分離方案實例,具有一定的參考價值,有興趣的可以了解一下。

本文將介紹使用Spring Boot集成Mybatis并實現主從庫分離的實現(同樣適用于多數據源)。延續之前的Spring Boot 集成MyBatis。項目還將集成分頁插件PageHelper、通用Mapper以及Druid。

新建一個Maven項目,最終項目結構如下:

Spring Boot 集成Mybatis實現主從(多數據源)分離方案示例

多數據源注入到sqlSessionFactory

POM增加如下依賴:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!--JSON-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-joda</artifactId>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-parameter-names</artifactId>
    </dependency>
 
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.0.11</version>
    </dependency>
    <!--mybatis-->
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>1.1.1</version>
    </dependency>
    <!--mapper-->
    <dependency>
      <groupId>tk.mybatis</groupId>
      <artifactId>mapper-spring-boot-starter</artifactId>
      <version>1.1.0</version>
    </dependency>
    <!--pagehelper-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper-spring-boot-starter</artifactId>
      <version>1.1.0</version>
      <exclusions>
        <exclusion>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <groupId>org.mybatis.spring.boot</groupId>
        </exclusion>
      </exclusions>
    </dependency>

這里需要注意的是:項目是通過擴展mybatis-spring-boot-starter的org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration來實現多數據源注入的。在mybatis-spring-boot-starter:1.2.0中,該類取消了默認構造函數,因此本項目依舊使用1.1.0版本。需要關注后續版本是否會重新把擴展開放處理。

之所以依舊使用舊方案,是我個人認為開放擴展是合理的,相信在未來的版本中會回歸。

如果你需要其他方案可參考傳送門

增加主從庫配置(application.yml)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
druid:
  type: com.alibaba.druid.pool.DruidDataSource
  master:
    url: jdbc:mysql://192.168.249.128:3307/db-test?characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
    initial-size: 5
    min-idle: 1
    max-active: 100
    test-on-borrow: true
  slave:
    url: jdbc:mysql://192.168.249.128:3317/db-test?characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
    initial-size: 5
    min-idle: 1
    max-active: 100
    test-on-borrow: true

創建數據源

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
@EnableTransactionManagement
public class DataSourceConfiguration {
 
  @Value("${druid.type}")
  private Class<? extends DataSource> dataSourceType;
 
  @Bean(name = "masterDataSource")
  @Primary
  @ConfigurationProperties(prefix = "druid.master")
  public DataSource masterDataSource(){
    return DataSourceBuilder.create().type(dataSourceType).build();
  }
 
  @Bean(name = "slaveDataSource")
  @ConfigurationProperties(prefix = "druid.slave")
  public DataSource slaveDataSource1(){
    return DataSourceBuilder.create().type(dataSourceType).build();
  }
}

將多數據源注入到sqlSessionFactory中

前面提到了這里通過擴展mybatis-spring-boot-starter的org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration來實現多數據源注入的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
@AutoConfigureAfter({DataSourceConfiguration.class})
public class MybatisConfiguration extends MybatisAutoConfiguration {
 
  private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
 
  @Resource(name = "masterDataSource")
  private DataSource masterDataSource;
  @Resource(name = "slaveDataSource")
  private DataSource slaveDataSource;
 
  @Bean
  public SqlSessionFactory sqlSessionFactory() throws Exception {
    return super.sqlSessionFactory(roundRobinDataSouceProxy());
  }
 
  public AbstractRoutingDataSource roundRobinDataSouceProxy(){
    ReadWriteSplitRoutingDataSource proxy = new ReadWriteSplitRoutingDataSource();
    Map<Object,Object> targetDataResources = new ClassLoaderRepository.SoftHashMap();
    targetDataResources.put(DbContextHolder.DbType.MASTER,masterDataSource);
    targetDataResources.put(DbContextHolder.DbType.SLAVE,slaveDataSource);
    proxy.setDefaultTargetDataSource(masterDataSource);//默認源
    proxy.setTargetDataSources(targetDataResources);
    return proxy;
  }
}

實現讀寫分離(多數據源分離)

這里主要思路如下:

1-將不同的數據源標識記錄在ThreadLocal中

2-通過注解標識出當前的service方法使用哪個庫

3-通過Spring AOP實現攔截注解并注入不同的標識到threadlocal中

4-獲取源的時候通過threadlocal中不同的標識給出不同的sqlSession

標識存放ThreadLocal的實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class DbContextHolder {
 
  public enum DbType{
    MASTER,SLAVE
  }
 
  private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<>();
 
  public static void setDbType(DbType dbType){
    if(dbType==null)throw new NullPointerException();
    contextHolder.set(dbType);
  }
 
  public static DbType getDbType(){
    return contextHolder.get()==null?DbType.MASTER:contextHolder.get();
  }
 
  public static void clearDbType(){
    contextHolder.remove();
  }
 
}

注解實現

?
1
2
3
4
5
6
7
8
/**
 * 該注解注釋在service方法上,標注為鏈接slaves庫
 * Created by Jason on 2017/3/6.
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnlyConnection {
}

Spring AOP對注解的攔截

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Aspect
@Component
public class ReadOnlyConnectionInterceptor implements Ordered {
 
  public static final Logger logger = LoggerFactory.getLogger(ReadOnlyConnectionInterceptor.class);
 
  @Around("@annotation(readOnlyConnection)")
  public Object proceed(ProceedingJoinPoint proceedingJoinPoint,ReadOnlyConnection readOnlyConnection) throws Throwable {
    try {
      logger.info("set database connection to read only");
      DbContextHolder.setDbType(DbContextHolder.DbType.SLAVE);
      Object result = proceedingJoinPoint.proceed();
      return result;
    }finally {
      DbContextHolder.clearDbType();
      logger.info("restore database connection");
    }
  }
 
 
  @Override
  public int getOrder() {
    return 0;
  }
}

根據標識獲取不同源

這里我們通過擴展AbstractRoutingDataSource來獲取不同的源。它是Spring提供的一個可以根據用戶發起的不同請求去轉換不同的數據源,比如根據用戶的不同地區語言選擇不同的數據庫。通過查看源碼可以發現,它是通過determineCurrentLookupKey()返回的不同key到sqlSessionFactory中獲取不同源(前面已經展示了如何在sqlSessionFactory中注入多個源)

?
1
2
3
4
5
6
7
public class ReadWriteSplitRoutingDataSource extends AbstractRoutingDataSource {
 
  @Override
  protected Object determineCurrentLookupKey() {
    return DbContextHolder.getDbType();
  }
}

以上就完成了讀寫分離(多數據源)的配置方案。下面是一個具體的實例

使用方式

Entity

?
1
2
3
4
5
6
7
8
9
10
11
@Table(name = "t_sys_dic_type")
public class DicType extends BaseEntity{
 
  String code;
 
  String name;
 
  Integer status;
 
  ...
}

Mapper

?
1
2
public interface DicTypeMapper extends BaseMapper<DicType> {
}

Service

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
public class DicTypeService {
  @Autowired
  private DicTypeMapper dicTypeMapper;
 
  @ReadOnlyConnection
  public List<DicType> getAll(DicType dicType){
    if (dicType.getPage() != null && dicType.getRows() != null) {
      PageHelper.startPage(dicType.getPage(), dicType.getRows());
    }
    return dicTypeMapper.selectAll();
  }
 
}

注意這里的@ReadOnlyConnection注解

Controller

?
1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping("/dictype")
public class DicTypeController {
  @Autowired
  private DicTypeService dicTypeService;
 
  @RequestMapping(value = "/all")
  public PageInfo<DicType> getALL(DicType dicType){
    List<DicType> dicTypeList = dicTypeService.getAll(dicType);
    return new PageInfo<>(dicTypeList);
  }
}

通過mvn spring-boot:run啟動后,即可通過http://localhost:9090/dictype/all 獲取到數據

后臺打印出

?
1
c.a.d.m.ReadOnlyConnectionInterceptor  : set database connection to read only

說明使用了從庫的鏈接獲取數據

備注:如何保證多源事務呢?

1-在讀寫分離場景中不會考慮主從庫事務,在純讀的上下文上使用@ReadOnlyConnection標簽。其他則默認使用主庫。

2-在多源場景中,Spring的@Transaction是可以保證多源的事務性的。

本文使用代碼

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.jianshu.com/p/8813ec02926a

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色狠狠综合天天综合综合 | 国产精品观看 | 精品久久99| 国产精品久久国产精品 | 精品一区二区三区视频 | 亚洲免费视频网 | 欧美亚洲视频在线观看 | 超碰中文字幕 | 黄色a视频 | 久久国产经典视频 | 久久久国产视频 | 国产综合一区二区 | 久久午夜影院 | 一区二区三区高清 | 亚洲综合中文字幕在线 | 成人免费视频 | 日韩一区中文 | 中文字幕一区日韩精品欧美 | 亚洲欧美在线一区 | 九九在线精品视频 | 日本午夜视频 | 国产欧美一区二区精品久久 | 国产高清av在线一区二区三区 | 欧美日本韩国一区二区三区 | 日本免费一区二区三区四区 | 久久一区 | 久久精品色欧美aⅴ一区二区 | 国产最新视频 | 欧美日韩一区二区三区在线观看 | 在线观看免费视频a | 日韩色综合 | 亚洲一区二区三区在线免费观看 | 中文字幕第一页在线 | 国产黄色一级录像 | 日韩三级av在线 | 日韩和欧美的一区二区 | 久久精品视频免费 | 亚洲精品久久久久久下一站 | 中文av一区二区三区 | 亚洲欧美日韩精品久久亚洲区 | 夜夜操av|