1. 程式人生 > >springBoot+Hibernate(Jpa)多資料來源配置與使用

springBoot+Hibernate(Jpa)多資料來源配置與使用

在學習的過程中,大多時候專案與資料庫都在本機上,使用hibernate或者mybatits加上簡單的配置就能夠打通程式到資料庫路徑,讓程式能夠訪問到資料庫。然而在一些情況下,我們不僅需要訪問本機的資料庫,還需要訪問到另外一個數據庫中的資源。本文書寫的目的便在於解決訪問多資源庫的問題,更多的是為了交流與學習。學習,原始碼是很重要的。文末給出了我的Github中的原始碼連結,感興趣的可以下載閱覽。

一、專案建立與資原始檔配置

建立一個初始的spring專案的方式在我的另一篇文章《springboot整合mybatis註解版與XML配置版》已經詳細介紹了,在這裡就不多贅述。當然,網上也有很多詳細的教程,你也可以自行搜尋閱覽。新建好的專案的pom.xml檔案中已經集成了必要的依賴包。本文所用到的pom.xml檔案如下。

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId
>
mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope
>
test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.40</version> </dependency> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency> <!--部署熱啟動依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.7.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.1.1.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!--熱啟動配置--> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build>

當初始化好一個專案後,首先要進行的便是各類資原始檔的配置,這時springboot的強大便體現的淋漓盡致,僅需要少量的資訊配置就能替代spring大量的xml檔案配置。在springboot中甚至都不需要配置web.xml,僅需要在自帶的application.properties檔案中進行資料庫等資訊配置。
對於本文的工程Demo資原始檔配置,首先,需要資料庫吧,還是兩個,所以兩個資料庫源都得配置吧。其次,用到了hibernate,也需要配置一下。至此必要的配置就結束了,就這麼簡單。

spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.primary.username=root
spring.datasource.primary.password=xxxxx
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-active=10
spring.datasource.primary.max-idle=5
spring.datasource.primary.min-idle=0

spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.secondary.username=root
spring.datasource.secondary.password=xxxxx
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.max-active=10
spring.datasource.secondary.max-idle=5
spring.datasource.secondary.min-idle=0

#新設定訪問介面,預設為8080
server.port=80

#hibernate配置
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true

#前端html的配置,解除嚴格語法檢查,前端才用到
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5

二、多資源庫配置

細心的你或許發現了多資源庫時的資原始檔配置與單資源庫時的配置不一樣,預設時的配置為

spring.datasource.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=xxxxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-active=10
spring.datasource.max-idle=5
spring.datasource.min-idle=0

而本文的配置為

spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.primary.username=root
spring.datasource.primary.password=xxxxx
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-active=10
spring.datasource.primary.max-idle=5
spring.datasource.primary.min-idle=0

資料庫欄位做了一些更改,一點變動貌似看起來沒啥關係,但是變了之後springboot就不認識這東西,不知道它是資料庫的資訊配置,因此我們需要重新定義。
首先,定義資料來源,並且註明一個主資料來源,一個從資料來源。直接在java目錄下,你所定義的專案檔案包(假如為com.springboot.xxx)下,新建一個DataSourceConfig.java檔案。

@Configuration
public class DataSourcesConfig {
    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.primary")
    public DataSource primaryDataSource() {
        System.out.println("primary db built");
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix="spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        System.out.println("secondary db built");
        return DataSourceBuilder.create().build();
    }
}

這樣就相當於告訴程式,程式要用到兩個資料庫,於是程式就去連線這兩個資料庫。怎麼連線呢,預設的連線已經行不通了,因此,對於每個資料庫還需要有一個定義檔案告訴程式如何去連線它。
同樣,我們在com.springboot.xxx包下新建兩個資料庫定義檔案PrimaryConfig.java與SecondaryConfig.java,分別定義主資料庫與從資料庫。
PrimaryConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryPrimary",
        transactionManagerRef="transactionManagerPrimary",
        basePackages= { "com.springboot.multi_resources.repository.user" }) //設定Repository所在位置
public class PrimaryConfig {

    @Autowired @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Primary
    @Bean(name = "entityManagerPrimary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDataSource)
                .properties(getVendorProperties(primaryDataSource))
                .packages("com.springboot.multi_resources.entity.user") //設定實體類所在位置
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    @Autowired(required=false)
    private JpaProperties jpaProperties;

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Primary
    @Bean(name = "transactionManagerPrimary")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }

}

SecondaryConfig.java

package com.springboot.multi_resources;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactorySecondary",
        transactionManagerRef="transactionManagerSecondary",
        basePackages= { "com.springboot.multi_resources.repository.work" }) //設定Repository所在位置
public class SecondaryConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

    @Bean(name = "entityManagerSecondary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactorySecondary(builder).getObject().createEntityManager();
    }

    @Bean(name = "entityManagerFactorySecondary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secondaryDataSource)
                .properties(getVendorProperties(secondaryDataSource))
                .packages("com.springboot.multi_resources.entity.work") //設定實體類所在位置
                .persistenceUnit("secondaryPersistenceUnit")
                .build();
    }


    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Bean(name = "transactionManagerSecondary")
    PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
    }

}

3、功能實現

至此,所有的配置類資訊就都搞定了,剩下的就是標準化的建四個層,controller層,entity實體層,service層,repository層,先來看下專案結構

兩個資料庫對應了兩個實體,分別為User與Work,對應這來自兩個資料庫的資訊。repository層與service層與單資料來源時的配置一樣,只是多了一套處理資訊。我們來看下較為核心的控制層

@Controller
public class MyController {
    @Autowired
    MyService myService;

    @RequestMapping("/")
    public String index()
    {
        return "index";
    }

    @RequestMapping("/all")
    @ResponseBody
    public JSONObject findAll()
    {
        List<User> userList = myService.findAll();
        JSONObject json = new JSONObject();
        json.put("data",userList);
        return json;
    }

    @RequestMapping("/add")
    @ResponseBody
    public JSONObject addOne(User user)
    {
        myService.addOne(user);
        JSONObject json = new JSONObject();
        json.put("data",user);
        return json;
    }

    @RequestMapping("/del")
    public void delOne(Integer id)
    {
        myService.delOne(id);
    }

    @RequestMapping("/find")
    @ResponseBody
    public JSONObject findOne(Integer id)
    {
        User user = myService.findOne(id);
        JSONObject json = new JSONObject();
        json.put("data",user);
        return json;
    }


    @RequestMapping("/modify")
    @ResponseBody
    public JSONObject modifyOne(User user)
    {
        User user1 = myService.modifyOne(user);
        JSONObject json = new JSONObject();
        json.put("data",user1);
        return json;
    }

    @RequestMapping("/workAll")
    @ResponseBody
    public JSONObject workAll(){
        List<Work> workList = myService.findWorkAll();
        JSONObject json = new JSONObject();
        json.put("data",workList);
        return json;
    }

在服務層中,則是對應了兩個注入的資料庫訪問介面,其實現類如下

 @Autowired
    MyRepository myRepository;

    @Autowired
    WorkRepository workRepository;

    @Override
    public List<User> findAll() {
        return myRepository.findAll();
    }

    @Override
    public void addOne(User user) {
        myRepository.saveAndFlush(user);
    }

    @Override
    public void delOne(Integer id) {
        myRepository.delete(id);
    }

    @Override
    public User findOne(Integer id) {
        return myRepository.findOne(id);
    }

    @Override
    public User modifyOne(User user) {
        myRepository.modifyOne(user.getUserName(),user.getPassword(),user.getAuthority(),user.getPhone(),user.getId());
        return myRepository.findOne(user.getId());
    }

    @Override
    public List<Work> findWorkAll() {
        return workRepository.findAll();
    }

在MyRepository資源層檔案中,筆者定義了一個自定義的查詢語句,雖然Jpa提供了豐富而便捷的自帶方法,但是總會用到自定義查詢的。

@Repository
public interface MyRepository extends JpaRepository<User,Integer>{

    @Modifying
    @Transactional
    @Query("update User u set u.userName=?1,u.password=?2,u.authority=?3,u.phone=?4 where u.id=?5")
    void modifyOne(String userName, String password, String authority, String phone, int id);
}

本片筆者寫的比較概括,詳細介紹篇幅可能就比較大了,閱讀起來就比較困難。一些主要的地方都介紹到了,細節配合原始碼基本上也能理解。有任何疑問或者建議歡迎留言交流。
原始碼

相關推薦

springBoot+Hibernate(Jpa)資料來源配置使用

在學習的過程中,大多時候專案與資料庫都在本機上,使用hibernate或者mybatits加上簡單的配置就能夠打通程式到資料庫路徑,讓程式能夠訪問到資料庫。然而在一些情況下,我們不僅需要訪問本機的資料庫,還需要訪問到另外一個數據庫中的資源。本文書寫的目的便在於解

springboot 資料來源配置使用

多資料來源配置 application.properties 配置兩個資料庫 #資料庫配置# spring.datasource.primary.driverClassName = com.mysql.jdbc.Driver spring.datasourc

springboot2.0.5+jpa資料來源配置

1.首先配置資料來源連線總裝類DataSourcesConfig package com.cpic.dataSources; import org.springframework.beans.factory.annotation.Qualifier; import org.springfr

Spring Boot Jpa資料來源配置

前言隨著業務量發展,我們通常會進行資料庫拆分或是引入其他資料庫,從而我們需要配置多個數據源,如:user一個庫,business一個庫。那麼接下來我們就要考慮怎麼去在spring boot中實現多個數據源的配置。 ××× 實現建表首先是建表語句,我們要建立兩個資料庫,並各庫內新建一張表user表mysql

Spring Boot之JdbcTemplate資料來源配置使用

之前在介紹使用JdbcTemplate和Spring-data-jpa時,都使用了單資料來源。在單資料來源的情況下,Spring Boot的配置非常簡單,只需要在application.properties檔案中配置連線引數即可。但是往往隨著業務量發展,我們通常會進行資料庫拆分或是引入其他資料庫,從而我們需要

SpringBoot(三):資料來源配置

簡介 說起多資料來源,一般都來解決那些問題呢,主從模式或者業務比較複雜需要連線不同的分庫來支援業務,配置多資料來源重點是配置檔案,所以資料庫,pox檔案,實體類我都不發出來了,自己建立兩個資料庫,配置實體類就行了 版權宣告:本文由 低調小熊貓 發表於 低調小熊貓的部落格 轉

SpringBoot2.0 jpa資料來源配置

隨著Springboot升級到2.0,原來1.5.x的Jpa多資料來源配置不能用了。現在總結一下Springboot2.0的jpa多資料來源配置連線池還是用druid,但是不能用druid的starter了,譬如在1.5.x時用的是<dependency>

Springboot+Mybatis實現資料來源配置

1、預設application.properties配置檔案增加多資料來源配置,也可另行自己增加新的配置檔案獨立維護 ## master資料來源[主端業務]:用於mybatis自動程式碼生成呼叫及spring對資料庫的系列操作 master.datasource.url=j

sping4 + jpa 資料來源配置, 多種實現

persistence-mysql.xml   及   orm-mysql.xml 的配置請參考我另外博文中 xml配置    ( 這裡是最簡單的配置方式,    後面的文章中有更智慧的配置方式)          搞外包,他們公司用到jpa,可是沒有一個人會. 真的是

Spring Boot資料來源配置使用

之前在介紹使用JdbcTemplate和Spring-data-jpa時,都使用了單資料來源。在單資料來源的情況下,Spring Boot的配置非常簡單,只需要在application.properties檔案中配置連線引數即可。但是往往隨著業務量發展,我

SpringBoot 的 MyBatis 資料來源配置

最近在專案開發中,需要為一個使用 MySQL 資料庫的 SpringBoot 專案,新新增一個 PLSQL 資料庫資料來源,那麼就需要進行 SpringBoot 的多資料來源開發。程式碼很簡單,下面是實現的過程。 ## 環境準備 實驗環境: - JDK 1.8 - SpringBoot 2.4.1 -

springboot+hibernate(jpa)配置資料來源

 個人在配置完spring boot多資料來源後報錯!仔細看了報錯的資訊提示建立從資料來源bean失敗,最後還是因為自己不仔細造成的,從資料庫少建立一張表。廢話不說直接貼程式碼! pom.xml 檔案就不上了,正常的依賴包。 application.properties 配置資訊: #

springboot+jpa 實現不同資料庫的資料來源配置

廢話不多說,直接看配置! 1、application.yml # 多資料來源配置 #primary spring: primary: datasource: url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/dico_d

Srping + JPA + Hibernate 資料來源配置

專案中有配置多資料來源的需求,查了一些資料最終實現,主要參考資料: http://www.cnblogs.com/linjiqin/archive/2011/02/12/1952904.html https://my.oschina.net/frankly/blog/277

Springboot 2.1.5 配置JPA資料來源

最近在學springboot,照著網上部落格想試著配一下Jpa的多資料來源,但發現因為springboot版本太高的問題,網上的d

Spring Boot的Spring-data-jpa資料來源配置實戰

一 新建pom <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>

實現SpringBoot資料來源配置

【場景】 當業務資料量達到了一定程度,DBA 需要合理配置資料庫資源。即配置主庫的機器高配置,把核心高頻的資料放在主庫上;把次要的資料放在從庫,低配置。 –(引自 https://www.cnblogs.com/Alandre/p/6611813.html 泥瓦匠BYSocket

springboot+mybatis資料來源配置,AOP註解動態切換資料來源

轉載至:https://blog.csdn.net/xiaosheng_papa/article/details/80218006 親測有效。 注:有些系統中已經配置了單資料來源,現在要轉成多資料來源,可能需要額外的配置。拿我自己當前專案來說: 專案在啟動類中配置了單資料來源:

基於SpirngBoot2.0+ 的 SpringBoot+Mybatis 資料來源配置

Github 地址:github.com/Snailclimb/…(SpringBoot和其他常用技術的整合,可能是你遇到的講解最詳細的學習案例,力爭新手也能看懂並且能夠在看完之後獨立實踐。基於最新的 SpringBoot2.0+,是你學習SpringBoot 的最佳指南。) ,歡迎各位 Star。

Spring Boot整合Hibernate(資料來源配置).md

配置資料來源: 定義兩個DataSource用來讀取application.properties中的不同配置: @Configuration public class DataSourceConfig { @Bean(