Spring Boot中JPA多数据源配置案例——基础演示 - 顺顺博客-

顺顺博客

顺雷特Snet
   
首页>> Java教程 >>Spring Boot中JPA多数据源配置案例——基础演示 - 顺顺博客
2020-4-3
分类: Java教程

Spring Boot中JPA多数据源配置案例——基础演示

文章作者:顺子
手机扫码查看

JPA 在 Spring Boot中和MyBatis配置多数据源大多都很相似, 而JPA主要提供与MyBatis不同的是Loca......


JPA Spring Boot中和MyBatis配置多数据源大多都很相似,

而JPA主要提供与MyBatis不同的是LocalContainerEntityManagerFactoryBean与事务管理器

本案例使用基于最新版2.2.6.RELEASE(貌似最近个把月出来的)+ mysql(上面图很清楚)

大多详细内容介绍写在注解里,案例源码在文章后

#1. 准备工作

添加基础依赖(注意下使用的是druid-spring-boot-starter而不是单单是druid

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId><!--这里使用阿里的 Druid 数据库连接池-->
            <artifactId>druid-spring-boot-starter</artifactId><!--这部分别看错了,不是单单druid-->
            <version>1.1.20</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

建库no1no2(使用的是MySql):

create database `no1` default character set utf8;
use `no1`;
create table `customer` (
`id` int(12) not null auto_increment,
`name` varchar(56) default null,
`gender` char(2) default null, 
`age` tinyint(100) default null,
`email` varchar(128) default null,
primary key (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

create database `no2`;
use `no2`;
create table `customer` (
`id` int(12) not null auto_increment,
`name` varchar(56) default null,
`gender` char(2) default null, 
`age` tinyint(100) default null,
`email` varchar(128) default null,
primary key (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;


application.properties 

# 数据源 1
spring.datasource.no1.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.no1.username=**
spring.datasource.no1.password=*****
spring.datasource.no1.url=jdbc:mysql://**/no1
# 数据源 2
spring.datasource.no2.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.no2.username=**
spring.datasource.no2.password=***
spring.datasource.no2.url=jdbc:mysql://**/no2
#与单独的JPA有所区别,因为后面在JpaProperties中getProperties 方法获取所有JPA的相关配置
#所以属性前缀都是spring.jpa.properties
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect
#在配置spring data jpa时,如果spring.jpa.properties.hibernate.hbm2ddl.auto设置为update,
# 会自动更新数据表结构,比如Entity中增加成员变量,数据表中也会增加相应的字段,但是需要注意的是,如果删除一个成员变量,
# 这时数据表中不会自动删除对应的字段,如果删除的那个成员变量在数据表中被设置为not null
spring.jpa.properties.database=mysql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.show-sql=true

#2.实体类Customer

package com.slt6.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity(name = "customer")
public class Customer {
    @Id
    //@GeneratedValue表示主键自动生成,strategy表示生成主键的策略
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String gender;
    private Integer age;
    private String email;

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}


#3. 创建RepositoryCustomerDao1CustomerDao2

//自定义CustomerDao1继承自JpaRepository
public interface CustomerDao1 extends JpaRepository<Customer,Integer> {
    List<Customer> getCustomersByNameStartingWith(String name);
    List<Customer> getCustomersByAgeGreaterThan(Integer age);
    @Query(value = "select  * from customer where age = (select max(age) from customer)",nativeQuery = true)//nativeQuery表示使用原生的SQL查询
    Customer getMaxIdCustomer();
    //利用:name这种方式进行命名绑定
    @Query("select email from customer where name=:name")
    String getCustomerByName(@Param("name") String name);
}

public interface CustomerDao2 extends JpaRepository<Customer,Integer> {
    List<Customer> getCustomersByNameStartingWith(String name);
    List<Customer> getCustomersByAgeGreaterThan(Integer age);
    @Query(value = "select  * from customer where age = (select max(age) from customer)",nativeQuery = true)//nativeQuery表示使用原生的SQL查询
    Customer getMaxIdCustomer();
    //利用?1这种方式进行命名绑定
    @Query("select email from customer where name=?1")
    String getCustomerByName(String name);
}


#4. Config配置环节

    创建DatasourceConfig配置

    Spring Boot还可以根据我们使用的数据库自动配置dataSource bean。

    对于类型为H2,HSQLDB和Apache、Derby的内存数据库,如果该类中

    存在相应的数据库依赖关系,则Spring Boot会自动配置DataSource


@Configuration
public class DataSourceConfig {
    @Bean
    //@ConfigurationProperties注解表示使用不同前缀的配置文件来创建不同的Datasource实例
    @ConfigurationProperties("spring.datasource.no1")
    //@Primary优选
    @Primary
    DataSource dsNo1(){
        return DruidDataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.no2")
    DataSource dsNo2(){
        return DruidDataSourceBuilder.create().build();
    }
}


    创建JPA配置(总共两个JpaConfigNo1JpaConfigNo2

@Configuration
//开启实事务管理器
@EnableTransactionManagement
//@EnableJpaRepositories注解进行JPA配置
//basePackages用来指定Repository所在的位置
//entityManagerFactoryRef用来指定实体类管理工厂Bean的名称
//transactionmanagerRef则用来指定事务管理器的引用名称,这里引用的名称是JpaConfigNo1类中注册的Bean的名称
@EnableJpaRepositories(basePackages = "com.slt6.dao1",entityManagerFactoryRef = "entityManagerFactoryBeanNo1",transactionManagerRef = "platformTransactionManagerNo1")
public class JpaConfigNo1 {
    @Resource(name = "dsNo1")
    DataSource dsNo1;
    @Autowired
    //获取所有JPA的相关配置
    JpaProperties jpaProperties;
    @Bean
    //因为有两个所以这个优选
    @Primary
    //该Bean用来提供EntityManager实例
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanNo1(EntityManagerFactoryBuilder builder){
        return builder.dataSource(dsNo1)    //配置数据源
                .properties(jpaProperties.getProperties())  //设置JPA相关配置,系统自动加载
                .packages("com.slt6.model") //设置实体类所在位置
                .persistenceUnit("pu1") //配置持久化单元名(注:项目中只有一个EntityManagerFactory,则可以忽略,多个必须设置)
                .build();
    }
    @Bean
    PlatformTransactionManager platformTransactionManagerNo1(EntityManagerFactoryBuilder builder){
        LocalContainerEntityManagerFactoryBean factoryNo1 = entityManagerFactoryBeanNo1(builder);
        //对单个EntityManagerFactory的事务支持,解决JPA中的事务管理
        return new JpaTransactionManager(factoryNo1.getObject());
    }
}
//第二个
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.slt6.dao2",entityManagerFactoryRef = "entityManagerFactoryBeanNo2",transactionManagerRef = "platformTransactionManagerNo2")
public class JpaConfigNo2 {
   @Resource(name = "dsNo2")
   DataSource dsNo2;
   @Autowired
   JpaProperties jpaProperties;
   @Bean
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanNo2(EntityManagerFactoryBuilder builder){
       return builder.dataSource(dsNo2)
               .properties(jpaProperties.getProperties())
               .packages("com.slt6.model")
               .persistenceUnit("pu2")
               .build();
   }
   @Bean
    PlatformTransactionManager platformTransactionManagerNo2(EntityManagerFactoryBuilder builder){
       LocalContainerEntityManagerFactoryBean factoryNo2 = entityManagerFactoryBeanNo2(builder);
       return new JpaTransactionManager(factoryNo2.getObject());
   }
}



#5. 创建ServiceService1Service2

@Service
public class Service1 {
    @Autowired
    CustomerDao1 customerDao1;
    //与Dao基本依依对应
    public void addCustomer(Customer customer){
        customerDao1.save(customer);
    }
    public List<Customer> getCustomersByNameStartingWith(String name){
        return customerDao1.getCustomersByNameStartingWith(name);
    }
    public List<Customer> getCustomersByAgeGreaterThan(int age){
        return customerDao1.getCustomersByAgeGreaterThan(age);
    }
    public Customer getMaxIdCustomer(){
        return customerDao1.getMaxIdCustomer();
    }
    public String getCustomerByName(String name){
        return customerDao1.getCustomerByName(name);
    }
}
//第二个
@Service
public class Service2 {
    @Autowired
    CustomerDao2 customerDao2;
    public void addCustomer(Customer customer){
        customerDao2.save(customer);
    }
    public List<Customer> getCustomersByNameStartingWith(String name){
        return customerDao2.getCustomersByNameStartingWith(name);
    }
    public List<Customer> getCustomersByAgeGreaterThan(int age){
        return customerDao2.getCustomersByAgeGreaterThan(age);
    }
    public Customer getMaxIdCustomer(){
        return customerDao2.getMaxIdCustomer();
    }
    public String getCustomerByName(String name){
        return customerDao2.getCustomerByName(name);
    }
}


#6. 创建Controller

@RestController
public class CustomerController {
    @Autowired
    Service1 service1;
    @Autowired
    Service2 service2;
    //先执行保存(/save)再执行/p
    @GetMapping("/save")
    public void save(){
        Customer customer1 = new Customer();
        customer1.setName("顺子");
        customer1.setAge(20);
        customer1.setGender("男");
        customer1.setEmail("[email protected]");
        Customer customer2 = new Customer();
        customer2.setName("老王");
        customer2.setAge(55);
        customer2.setGender("女");
        customer2.setEmail("[email protected]");
        service1.addCustomer(customer1);
        service1.addCustomer(customer2);
        service2.addCustomer(customer2);
        service2.addCustomer(customer1);
    }
    @GetMapping("/q")
    public void p(){
        Customer ld = service1.getMaxIdCustomer();
        List<Customer> l1 = service1.getCustomersByAgeGreaterThan(20);
        List<Customer> l2 = service1.getCustomersByNameStartingWith("顺");
        String l3 = service1.getCustomerByName("老王");
        Customer zd = service2.getMaxIdCustomer();
        List<Customer> z1 = service2.getCustomersByAgeGreaterThan(20);
        List<Customer> z2 = service2.getCustomersByNameStartingWith("老");
        String z3 = service2.getCustomerByName("顺子");
        System.out.println("第一个数据库:");
        System.out.println("ld:" + ld);
        System.out.println("l1:" + l1);
        System.out.println("l2:" + l2);
        System.out.println("l3:" + l3);
        System.out.println("第二个数据库:");
        System.out.println("zd:" + zd);
        System.out.println("z1:" + z1);
        System.out.println("z2:" + z2);
        System.out.println("z3:" + z3);
    }
}
运行的效果




下载慢,请在我的Box工具中粘贴下载的连接可起到加速下载的效果



×

感谢您的支持,我们会一直保持!

扫码支持
请土豪扫码随意打赏

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

打赏作者
版权所有,转载注意明处:顺顺博客 » Spring Boot中JPA多数据源配置案例——基础演示
标签: SpringBoot Spring
版权所有:《顺顺博客
文章标题:《Spring Boot中JPA多数据源配置案例——基础演示
除非注明,文章均为 《顺顺博客》 原创
转载请注明本文短网址:https://bk.shunleite.com/post-53.html  [生成短网址]

发表评论

路人甲 表情
Ctrl+Enter快速提交

网友评论(0)