解决spring boot 1.5.4 配置多数据源的问题

 更新时间:2017年06月18日 09:08:21   投稿:jingxian  
下面小编就为大家带来一篇解决spring boot 1.5.4 配置多数据源的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

spring boot 已经支持多数据源配置了,无需网上好多那些编写什么类的,特别麻烦,看看如下解决方案,官方的,放心!

1.首先定义数据源配置

#=====================multiple database config============================
#ds1
first.datasource.url=jdbc:mysql://localhost/test?characterEncoding=utf8&useSSL=true
first.datasource.username=root
first.datasource.password=123456
first.datasource.driver-class-name=com.mysql.jdbc.Driver
first.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
first.datasource.max-wait=10000
first.datasource.max-active=200
first.datasource.test-on-borrow=true
first.datasource.initial-size=10

#ds2
second.datasource.url=jdbc:mysql://localhost/test2?characterEncoding=utf8&useSSL=true
second.datasource.username=root
second.datasource.password=123456
second.datasource.driver-class-name=com.mysql.jdbc.Driver
second.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
second.datasource.max-wait=10000
second.datasource.max-active=200
second.datasource.test-on-borrow=true
second.datasource.initial-size=10

#=====================jpa config================================
#实体类维护数据库表结构的具体行为:update/create/create-drop/validate/none
spring.jpa.hibernate.ddl-auto=none
#打印sql语句
spring.jpa.show-sql=true
#格式化输出的json字符串
spring.jackson.serialization.indent_output=true

2.配置ds1的相关注入对象和启用jpa支持

/**
 * Created by hdwang on 2017-06-16.
 * 第一个数据源配置
 * If you are using Spring Data, you need to configure @EnableJpaRepositories
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.hdwang.dao.datajpa.firstDs",entityManagerFactoryRef = "firstEntityManagerFactory",transactionManagerRef="firstTransactionManager")
public class FirstDsConfig {

  /**
   * 数据源配置对象
   * Primary 表示默认的对象,Autowire可注入,不是默认的得明确名称注入
   * @return
   */
  @Bean
  @Primary
  @ConfigurationProperties("first.datasource")
  public DataSourceProperties firstDataSourceProperties() {
    return new DataSourceProperties();
  }

  /**
   * 数据源对象
   * @return
   */
  @Bean
  @Primary
  @ConfigurationProperties("first.datasource")
  public DataSource firstDataSource() {
    return firstDataSourceProperties().initializeDataSourceBuilder().build();
  }

  /**
   * 实体管理对象
   * @param builder 由spring注入这个对象,首先根据type注入(多个就取声明@Primary的对象),否则根据name注入
   * @return
   */
  @Bean
  @Primary
  public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(
      EntityManagerFactoryBuilder builder) {
    return builder
        .dataSource(firstDataSource())
        .packages("com.hdwang.entity.dbFirst")
        .persistenceUnit("firstDs")
        .build();
  }

  /**
   * 事务管理对象
   * @return
   */
  @Bean(name = "firstTransactionManager")
  @Primary
  public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);
    return transactionManager;
  }

  @Bean
  @Primary
  public JdbcTemplate jdbcTemplate(){
    return new JdbcTemplate(firstDataSource());
  }

  @Bean
  @Primary
  public TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager){
    return new TransactionTemplate(platformTransactionManager);
  }
}

相关知识点:

1.使用@Bean可以创建一个bean对象交给spring容器管理

2.@Bean创建的bean对象的名称默认为方法名,也可以指定

3.@Bean方法参数表示,接收一个bean对象,默认按照type类型接收注入的对象,若要修改为byName方式,可以使用@Qualifier注解注入准确的对象

4.@Primary表示该bean为此类型的默认bean,在其他地方引用的时候用@Autowired即可按照类型注入,不受同类型多个对象影响

5.EnableJpaRepositories表示启用spring data jpa的支持,也就是jpa的新使用方式,注意basePackages指的事 @Repository接口的所在包位置,可配置多个

其他注解就不清楚了!

2.配置ds2的相关注入对象和启用jpa支持

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.hdwang.dao.datajpa.secondDs", entityManagerFactoryRef = "secondEntityManagerFactory",transactionManagerRef = "secondTransactionManager")
public class SecondDsConfig {

  @Bean
  @ConfigurationProperties("second.datasource")
  public DataSourceProperties secondDataSourceProperties() {
    return new DataSourceProperties();
  }

  @Bean
  @ConfigurationProperties("second.datasource")
  public DataSource secondDataSource() {
    return secondDataSourceProperties().initializeDataSourceBuilder().build();
  }

  /**
   * 实体管理对象
   * @param builder 由spring注入这个对象,首先根据type注入(多个就取声明@Primary的对象),否则根据name注入
   * @return
   */
  @Bean
  public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(
      EntityManagerFactoryBuilder builder) {
    return builder
        .dataSource(secondDataSource())
        .packages("com.hdwang.entity.dbSecond")
        .persistenceUnit("secondDs")
        .build();
  }

  /**
   * 事物管理对象
   * @param secondEntityManagerFactory 实体管理工厂对象(按照名称注入)
   * @return 平台事物管理器
   */
  @Bean(name = "secondTransactionManager")
  public PlatformTransactionManager transactionManager(@Qualifier("secondEntityManagerFactory")LocalContainerEntityManagerFactoryBean secondEntityManagerFactory){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(secondEntityManagerFactory.getObject());
    return transactionManager;
  }

  @Bean(name="jdbcTemplate2")
  public JdbcTemplate jdbcTemplate(){
    return new JdbcTemplate(secondDataSource());
  }

  @Bean(name = "transactionTemplate2")
  public TransactionTemplate transactionTemplate(@Qualifier("secondTransactionManager")PlatformTransactionManager transactionManager){
    return new TransactionTemplate(transactionManager);
  }
}

3.Repository数据持久层

package com.hdwang.dao.datajpa.firstDs;

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
  /**
   * spring data jpa 会自动注入实现(根据方法命名规范)
   * @return
   */
  User findByNumber(String number);


  @Modifying
  @Query("delete from User u where u.id = :id")
  void deleteUser(@Param("id")int id);
}
package com.hdwang.dao.datajpa.secondDs;

@Repository
public interface OrderRepository extends JpaRepository<Order, Integer> {
  /**
   * spring data jpa 会自动注入实现(根据方法命名规范)
   * @return
   */
  User findByNumber(String number);


  @Modifying
  @Query("delete from Order o where o.id = :id")
  void deleteUser(@Param("id") int id);
}

上面两个接口分属两个数据源,在@EnableJpaRepositories配置好后,这里就可以正确操作相应的数据源了

4.Service服务层,注意事物(接口我就不贴了)

@Service
@Transactional("firstTransactionManager")
public class UserServiceImpl implements UserService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public User findById(int id) {
    return this.userRepository.findOne(id);
  }

  @Override
  public User findByNumber(String number) {
    return this.userRepository.findByNumber(number);
  }

  @Override
  public List<User> findAllUserByPage(int page,int size) {
    Pageable pageable = new PageRequest(page, size);
    Page<User> users = this.userRepository.findAll(pageable);
    return users.getContent();
  }

  @Override
  public User updateUser(User user,boolean throwEx) {
    User userNew = this.userRepository.save(user);
    if(throwEx){
      throw new RuntimeException("throw a ex");
    }
    return userNew;
  }

  @Override
  public void deleteUser(int id) {
    this.userRepository.deleteUser(id);
  }
}
@Service
@Transactional("secondTransactionManager")
public class OrderServiceImpl implements OrderService {

  @Autowired
  private OrderRepository orderRepository;


  @Override
  public Order findById(int id) {
    return this.orderRepository.findOne(id);
  }

  @Override
  public Order updateOrder(Order order, boolean throwEx) {
    Order orderNew = this.orderRepository.save(order);
    if(throwEx){
      throw new RuntimeException("throw a ex");
    }
    return orderNew;
  }
}

知识扩展

1.如果采用传统jpa方式,@EnableJpaRepositories无需配置,配置了也无影响。实现方式如下:

ds1相关DaoImpl
@PersistenceContext
private EntityManager entityManager;

ds2相关DaoImpl
@PersistenceContext(unitName = "secondDs")
private EntityManager entityManager;

因为ds1的entityManger声明了@Primary,所以无需指明unitName,ds2必须指明。注入了准确的entityManager,就可以直接拿来操作数据库了。service层和上面一样的,@Transactional("xxxManager")指明事物管理器即可!

2.采用jdbcTemplate方式,直接注入到Service层对象即可,so easy!

@Autowired
private JdbcTemplate jdbcTemplate;

@Autowired
private TransactionTemplate transactionTemplate;

@Resource(name="jdbcTemplate2")
private JdbcTemplate jdbcTemplate2;

@Resource(name="transactionTemplate2")
private TransactionTemplate transactionTemplate2;

好了,spring boot 多数据源,完美解决! 而且三种数据库操作方法均支持,包括事物。已经经过实践证明了! 这是官方给出的最佳实践,只是官方文档没写细。导致整整坑了我几天。至此,spring boot框架的使用就告一段落了!

以上这篇解决spring boot 1.5.4 配置多数据源的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot项目中同时操作多个数据库的实现方法

    SpringBoot项目中同时操作多个数据库的实现方法

    在实际项目开发中可能存在需要同时操作两个数据库的场景,本文主要介绍了SpringBoot项目中同时操作多个数据库的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java中的@Repeatable注解的作用详解

    Java中的@Repeatable注解的作用详解

    这篇文章主要介绍了Java中的@Repeatable注解的作用详解,@Repeatable注解是用来标注一个注解在同一个地方可重复使用的一个注解,使被他注释的注解可以在同一个地方重复使用,需要的朋友可以参考下
    2024-01-01
  • Java Integer如何获取第一位和最后一位,并截取

    Java Integer如何获取第一位和最后一位,并截取

    这篇文章主要介绍了Java Integer如何获取第一位和最后一位并截取,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • springMVC如何将controller中Model数据传递到jsp页面

    springMVC如何将controller中Model数据传递到jsp页面

    本篇文章主要介绍了springMVC如何将controller中Model数据传递到jsp页面,具有一定的参考价值,有兴趣的可以了解一下
    2017-07-07
  • Java连接Redis全过程讲解

    Java连接Redis全过程讲解

    这篇文章主要介绍了Java连接Redis全过程讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • java基础知识之FileInputStream流的使用

    java基础知识之FileInputStream流的使用

    这篇文章主要介绍了java基础知识之FileInputStream流的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringBoot整合BootStrap实战

    SpringBoot整合BootStrap实战

    这篇文章主要介绍了SpringBoot整合BootStrap实战,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Maven的几个常用plugin

    Maven的几个常用plugin

    本文主要介绍了Maven的几个常用plugin。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • Java后台防止客户端重复请求、提交表单实现原理

    Java后台防止客户端重复请求、提交表单实现原理

    这篇文章主要介绍了Java后台防止客户端重复请求、提交表单实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 使用@CachePut 更新数据库和更新缓存

    使用@CachePut 更新数据库和更新缓存

    这篇文章主要介绍了使用@CachePut 更新数据库和更新缓存方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12

最新评论