配置多数据源
1.什么是数据源?
在数据源中存储了所有建立数据库连接的信息,通过数据源名称可以找到相应的数据库连接。
2.什么是多数据源?
就是多个数据源对应多个数据库,他们是一对一的关系。
3.为什么使用多数据源?
减少每个数据库的压力。
4.正式学习多数据源
4.1 配置多数据源
#与单数据源的区别是多了个数据源的名称
#test数据源
spring.datasource.test.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test.jdbc-url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.test.username=root
spring.datasource.test.password=123456abc
#test2数据源
spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.test2.username=root
spring.datasource.test2.password=123456abc
#版本在5及以上的要加上MySQL5Dialect而不是MySQLDialect
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.hbm22dl.auto=update
4.2 配置好数据源后,新建一个数据源配置类,用于接收配置的参数
@Configuration
public class DataSourceConfig {
//test库
@Primary
@Bean(name = "testDataSourceProperties")
@Qualifier("testDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.test")
public DataSourceProperties testDataSourceProperties() {
return new DataSourceProperties();
}
@Primary
@Bean(name = "testDataSource")
@Qualifier("testDataSource")
@ConfigurationProperties(prefix = "spring.datasource.test")
public DataSource testDataSource(@Qualifier("testDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
//test2库
@Bean(name = "test2DataSourceProperties")
@Qualifier("test2DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSourceProperties test2DataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "test2DataSource")
@Qualifier("test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource test2DataSource(@Qualifier("test2DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
}
或者
@Configuration
public class DataSourceConfig {
@Bean(name = "testDataSource")
@Qualifier("testDataSource")
@Primary
@ConfigurationProperties(prefix="spring.datasource.test")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test2DataSource")
@Qualifier("test2DataSource")
@ConfigurationProperties(prefix="spring.datasource.test2")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
也是可以的。
4.3 接下来对每个数据源进行详细配置
//主要数据源加primary 其余不用加
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "testEntityManagerFactory",
transactionManagerRef = "testTransactionManager",
//设计repository所在位置
basePackages = {"com.mrcoder.sbjpamultidb.entity"})
public class testConfig {
@Autowired
private HibernateProperties hibernateProperties;
@Resource
@Qualifier("testDataSource")
private DataSource testDataSource;
@Primary
@Bean(name = "testEntityManager")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return testEntityManagerFactory(builder).getObject().createEntityManager();
}
@Resource
private JpaProperties jpaProperties;
/**
* 设置实体类所在位置
*/
@Primary
@Bean(name = "testEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean testEntityManagerFactory(EntityManagerFactoryBuilder builder) {
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
jpaProperties.getProperties(), new HibernateSettings());
return builder
.dataSource(testDataSource)
.packages("com.mrcoder.sbjpamultidb.entity")
.persistenceUnit("testPersistenceUnit")
.properties(properties)
.build();
}
@Primary
@Bean(name = "testTransactionManager")
public PlatformTransactionManager testTransactionManager(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(testEntityManagerFactory(builder).getObject());
}
}
其他是一样的,只是不加primary,注意两个包的位置放对就行了。
4.4 基于JPA使用多数据源
@Entity
@Table(name="city")
public class City {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int cityId;
private String cityName;
private String cityIntroduce;
//set get
}
@Entity
@Table(name="house")
public class House {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int houseId;
private String houseName;
private String houseIntroduce;
//set get
}
public interface CityDao extends JpaRepository<City, Integer> {
}
public interface HouseDao extends JpaRepository<House,Integer> {
}
4.5 Controller
@RestController
public class JpaMultidbController {
@Autowired
private CityDao cityDao;
@Autowired
private HouseDao houseDao;
@GetMapping("/testDataSource")
public String testDataSource(){
City city = new City("北京","中国首都");
cityDao.save(city);
House house = new House("豪宅","特别大的豪宅");
houseDao.save(house);
return "success";
}
}
测试成功。
基于mybatis使用多数据源
mapper
@Mapper
public interface CityMapper {
@Select("SELECT * FROM City")
@Results({
@Result(property = "cityId", column = "city_id"),
@Result(property = "cityName", column = "city_name"),
@Result(property = "cityIntroduce", column = "city_introduce")
})
List<City> getAllCity();
}
@Mapper
public interface HouseMapper {
@Select("SELECT * FROM House")
@Results({
@Result(property = "houseId", column = "house_id"),
@Result(property = "houseName", column = "house_name"),
@Result(property = "houseIntroduce", column = "house_introduce")
})
List<House> getAllHouse();
}
操作数据源于JPA略有不同:
@Configuration
@MapperScan(basePackages = "com.springboot.mapper.datasource",
sqlSessionTemplateRef = "sqlSessionTemplatePrimary")
public class TestDataSourceConfig {
@Bean(name = "sqlSessionFactoryPrimary")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//如果使用xml写SQL的话在这里配置
//bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/datasource/*.xml"));
return bean.getObject();
}
@Bean(name = "transactionManagerPrimary")
@Primary
public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("testDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplatePrimary")
@Primary
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
controller:
@RestController
public class TestController {
@Autowired
HouseMapper houseMapper;
@Autowired
CityMapper cityMapper;
@GetMapping("/testDataSource")
public Map testDataSource(){
Map map = new HashMap();
List<City> cityList=cityMapper.getAllCity();
List<House> houseList=houseMapper.getAllHouse();
map.put("cityList",cityList);
map.put("houseList",houseList);
return map;
}
}
测试ok。