Hibernate5+Spring Boot多数据库连接:为SessionFactory指定名称
配置多数据源与多SessionFactory(Hibernate)
核心实现思路
通过给@Bean指定唯一名称,结合@Qualifier注解区分不同的数据源、SessionFactory和事务管理器,实现多数据库独立操作。
1. 配置双数据源
为每个数据源Bean指定专属名称,后续SessionFactory绑定对应数据源:
@Configuration @PropertySource("classpath:application.properties") public class HibernateConfig { @Autowired private Environment env; // 第一个数据源,指定名称:firstDataSource @Bean(name = "firstDataSource") public DataSource firstDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getProperty("db1.driver-class-name")); dataSource.setUrl(env.getProperty("db1.url")); dataSource.setUsername(env.getProperty("db1.username")); dataSource.setPassword(env.getProperty("db1.password")); return dataSource; } // 第二个数据源,指定名称:secondDataSource @Bean(name = "secondDataSource") public DataSource secondDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getProperty("db2.driver-class-name")); dataSource.setUrl(env.getProperty("db2.url")); dataSource.setUsername(env.getProperty("db2.username")); dataSource.setPassword(env.getProperty("db2.password")); return dataSource; } }
2. 配置双SessionFactory
每个SessionFactory绑定对应数据源,同时指定Bean名称:
// 续上面的HibernateConfig类 // 第一个SessionFactory,指定名称:firstSessionFactory @Bean(name = "firstSessionFactory") public LocalSessionFactoryBean firstSessionFactory(@Qualifier("firstDataSource") DataSource dataSource) { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(dataSource); // 指定第一个库对应的实体类包路径 sessionFactory.setPackagesToScan("com.yourpackage.entity.db1"); sessionFactory.setHibernateProperties(hibernateProperties()); return sessionFactory; } // 第二个SessionFactory,指定名称:secondSessionFactory @Bean(name = "secondSessionFactory") public LocalSessionFactoryBean secondSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(dataSource); // 指定第二个库对应的实体类包路径 sessionFactory.setPackagesToScan("com.yourpackage.entity.db2"); sessionFactory.setHibernateProperties(hibernateProperties()); return sessionFactory; } // 通用Hibernate属性配置 private Properties hibernateProperties() { Properties properties = new Properties(); properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql")); properties.put("hibernate.format_sql", env.getProperty("hibernate.format_sql")); return properties; }
3. 配置双事务管理器
每个事务管理器绑定对应SessionFactory,指定专属名称:
// 续上面的HibernateConfig类 // 第一个事务管理器,指定名称:firstTransactionManager @Bean(name = "firstTransactionManager") public HibernateTransactionManager firstTransactionManager(@Qualifier("firstSessionFactory") SessionFactory sessionFactory) { HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory); return txManager; } // 第二个事务管理器,指定名称:secondTransactionManager @Bean(name = "secondTransactionManager") public HibernateTransactionManager secondTransactionManager(@Qualifier("secondSessionFactory") SessionFactory sessionFactory) { HibernateTransactionManager txManager = new HibernateTransactionManager(); txManager.setSessionFactory(sessionFactory); return txManager; }
4. 调用指定的SessionFactory操作数据
在DAO/Service中,通过@Qualifier指定要注入的SessionFactory,同时绑定对应事务管理器:
@Repository public class Db1UserDao { // 注入第一个SessionFactory @Autowired @Qualifier("firstSessionFactory") private SessionFactory firstSessionFactory; @Transactional(value = "firstTransactionManager") public User getDb1UserById(Long id) { return firstSessionFactory.getCurrentSession().get(User.class, id); } }
@Repository public class Db2ProductDao { // 注入第二个SessionFactory @Autowired @Qualifier("secondSessionFactory") private SessionFactory secondSessionFactory; @Transactional(value = "secondTransactionManager") public Product getDb2ProductById(Long id) { return secondSessionFactory.getCurrentSession().get(Product.class, id); } }
关键注意点
- 两个库的实体类建议分不同包存放,避免SessionFactory扫描冲突
@Transactional必须指定对应事务管理器名称,否则会默认使用第一个注册的事务管理器- 配置文件需分别维护两个库的连接参数(如
db1.url、db2.url等)
内容的提问来源于stack exchange,提问作者Yves J
相关产品推荐
相关产品推荐

