美文网首页微服务
SpringBoot2.0+Spring Data Jpa实现多

SpringBoot2.0+Spring Data Jpa实现多

作者: 墨倾心児 | 来源:发表于2019-11-17 16:08 被阅读0次

    Spring Boot中使用的Jpa实际上是Spring Data Jpa,Spring Data是Spring家族的一个子项目,用于简化SQL和NoSQL的访问。
    下面来做一下SpringBoot2.0+Spring Data Jpa实现多数据源。

    1. 首先,在application.yml 中做一些DataSource的配置,
    spring:
      application:
        name: ms
      jackson:
          date-format: yyyy-MM-dd HH:mm:ss.SSS
          time-zone: GMT+8
      datasource:
        primary:
              type: com.alibaba.druid.pool.DruidDataSource
              jdbc-url: jdbc:mysql://localhost:3306/db1?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
              username : 
              password : 
              driverClassName : com.mysql.cj.jdbc.Driver
        secondary:
              jdbc-url:  jdbc:postgresql://localhost:5432/postgis
              username: 
              password: 
              driverClassName: org.postgresql.Driver
      jpa:
        hibernate:
          primary-dialect: org.hibernate.dialect.MySQL5Dialect
          secondary-dialect: org.hibernate.dialect.PostgreSQL9Dialect
          ddl-auto: update
        show-sql: true
        properties:
          hibernate:
            temp:
              use_jdbc_metadata_defaults: false
    
    

    use_jdbc_metadata_defaults: false 是为了解决:这个 org.postgresql.jdbc.PgConnection.createClob() 方法尚未被实作。
    说明:平常我们配置URL的时候使用spring.datasource.primary.url,但是这里不行了,这么写会报错:jdbcUrl is required with driverClassName。

    spring.datasource.url 数据库的 JDBC URL。
    spring.datasource.jdbc-url 用来重写自定义连接池
    官方文档的解释是:
    因为连接池的实际类型没有被公开,所以在您的自定义数据源的元数据中没有生成密钥,而且在IDE中没有完成(因为DataSource接口没有暴露属性)。另外,如果您碰巧在类路径上有Hikari,那么这个基本设置就不起作用了,因为Hikari没有url属性(但是确实有一个jdbcUrl属性)。
    因此要改为 spring.datasource.primary.jdbc-url

    1. 编写DataSourceConfig
    import javax.sql.DataSource;
    
    /**
     * @create 2019-11-17 12:47
     * @desc 配置多数据源
     **/
    @Configuration
    public class DataSourceConfig {
        @Bean(name = "primaryDataSource")
        @Primary
        @Qualifier("primaryDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.primary")
        public DataSource primaryDatasource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "secondaryDataSource")
        @Qualifier("secondaryDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.secondary")
        public DataSource secondaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    }
    
    
    1. 编写PrimaryConfig
    
    /**
     * @create 2019-11-17 12:50
     * @desc MySQL数据源的配置
     **/
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryPrimary",//配置连接工厂 entityManagerFactory
            transactionManagerRef = "transactionManagerPrimary", //配置 事物管理器  transactionManager
            basePackages = {"xxx.xxx.xxx.xxx.repo"}//设置持久层所在位置
    )
    public class PrimaryConfig {
    
        @Autowired
        private Properties jpaProperties;
    
        @Autowired
        @Qualifier("primaryDataSource")
        private DataSource primaryDataSource;// 自动注入配置好的数据源
       /* @Autowired
        private HibernateProperties hibernateProperties;*/
    
        @Value("${spring.jpa.hibernate.primary-dialect}")
        private String primaryDialect;// 获取对应的数据库方言
    
        @Primary
        @Bean(name = "entityManagerPrimary")
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
        }
        /**
         *
         * @param builder
         * @return
         */
        @Bean(name = "entityManagerFactoryPrimary")
        @Primary
        public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
    
            LocalContainerEntityManagerFactoryBean entityManagerFactory = builder
                    //设置数据源
                    .dataSource(primaryDataSource)
                    //设置实体类所在位置.扫描所有带有 @Entity 注解的类
                    .packages("xxx.xxx.xxx.xxx.entity")
                    // Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
                    // Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
                    .persistenceUnit("primaryPersistenceUnit")
                    .build();
            entityManagerFactory.setJpaProperties(jpaProperties);
            return entityManagerFactory;
        }
    
    
        /**
         * 配置事物管理器
         *
         * @param builder
         * @return
         */
        @Bean(name = "transactionManagerPrimary")
        @Primary
        PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
        }
    }
    
    
    1. 编写SecondaryConfig
    /**
     * @create 2019-11-17 13:01
     * @desc postgresql 数据源的配置
     **/
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef="entityManagerFactorySecondary",
            transactionManagerRef="transactionManagerSecondary",
            basePackages= { "xxx.xxx.xxx.xxx.repo" })
    public class SecondaryConfig {
    
        @Autowired
        private Properties jpaProperties;
    
        @Autowired
        @Qualifier("secondaryDataSource")
        private DataSource secondaryDataSource;
        /*@Autowired
        private HibernateProperties hibernateProperties;*/
    
        @Value("${spring.jpa.hibernate.secondary-dialect}")
        private String secondaryDialect;
    
    
    
        @Bean(name = "entityManagerSecondary")
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactorySecondary(builder).getObject().createEntityManager();
        }
    
        @Bean(name = "entityManagerFactorySecondary")
        public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
            LocalContainerEntityManagerFactoryBean entityManagerFactory = builder
                    .dataSource(secondaryDataSource)
                    .packages("xxx.xxx.xxx.xxx.entity")
                    .persistenceUnit("secondaryPersistenceUnit")
                    .build();
            entityManagerFactory.setJpaProperties(jpaProperties);
            return entityManagerFactory;
        }
        /*
            private Map<String, String> getVendorProperties(DataSource dataSource) {
                Map<String,String> map = new HashMap<>();
                map.put("hibernate.dialect",secondaryDialect);
                jpaProperties.setProperties(map);
                return jpaProperties.getHibernateProperties(dataSource);
            }*/
        //spring boot 2.1以上版本应该这么写  JPA多数据源配置
        /*@Bean(name = "entityManagerFactorySecondary")
        public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(
                EntityManagerFactoryBuilder builder, JpaProperties jpaProperties,
                HibernateProperties hibernateProperties) {
            Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
                    jpaProperties.getProperties(), new HibernateSettings());
            return builder.dataSource(secondaryDataSource).properties(properties)
                    .packages("com.jcloud.traffic.situation.postgis.entity").build();
        }*/
    
    
        @Bean(name = "transactionManagerSecondary")
        PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
        }
    
    
    }
    
    1. 测试,写好相关数据库中对应的entity和repository,写几个service作为测试
    /**
     * @create 2019-11-16 16:08
     * @desc
     **/
    @RestController
    public class DemoController {
        @Autowired
        private DemoService demoService;
        @Autowired
        private TestService tstService;
        @GetMapping("/test")
        public Map te(){
            User u = demoService.findByid("17");
            
            List<Object> byId = tstService.getById(1L);
            
            Map map=new HashMap(2);
            map.put("user",u);
            map.put("byId",byId);
            return map;
        }
    }
    

    postman访问接口,查看结果

    {
        "code": 0,
        "message": "",
        "data": {
            "byId": [
                {
                    "id": 1,
                    "city": "杭州市",
                    "date": 1549987200000,
                    "time": 43557000,
                    .......
                }
            ],
            "user": {
                "gid": 787,
                "id": 17,
                "type": 2,
                .......
            }
        }
    }
    

    6.补充一些依赖

    <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-test</artifactId>
               <scope>test</scope>
           </dependency>
           <dependency>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok</artifactId>
               <version>1.16.18</version>
           </dependency>
    
    <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-tx</artifactId>
               <!--<version>5.1.9.RELEASE</version>-->
           </dependency>
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-data-jpa</artifactId>
           </dependency>
    
           <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
           <dependency>
               <groupId>org.postgresql</groupId>
               <artifactId>postgresql</artifactId>
               <version>42.2.5</version>
           </dependency>
           <!-- MySQL 驱动, 注意, 这个需要与 MySQL 版本对应 -->
           <dependency>
               <groupId>mysql</groupId>
               <artifactId>mysql-connector-java</artifactId>
               <version>8.0.12</version>
               <scope>runtime</scope>
           </dependency>
    
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-autoconfigure</artifactId>
               <version>2.0.2.RELEASE</version>
           </dependency>
           <!-- druid 连接池 -->
           <dependency>
               <groupId>com.alibaba</groupId>
               <artifactId>druid</artifactId>
               <version>1.1.13</version>
           </dependency>
           <dependency>
               <groupId>com.alibaba</groupId>
               <artifactId>druid-spring-boot-starter</artifactId>
               <version>1.1.13</version>
           </dependency>
           <dependency>
               <groupId>log4j</groupId>
               <artifactId>log4j</artifactId>
               <version>1.2.17</version>
           </dependency>
           <!-- sql 日志待参数输出 -->
           <dependency>
               <groupId>com.googlecode.log4jdbc</groupId>
               <artifactId>log4jdbc</artifactId>
               <version>1.2</version>
           </dependency>
    
    
    

    相关文章

      网友评论

        本文标题:SpringBoot2.0+Spring Data Jpa实现多

        本文链接:https://www.haomeiwen.com/subject/rybpictx.html