多數據源配置
多數據源配置
實現同一個項目以不同的方式鏈接使用多個數據庫,如果只使用一個數據源,很多配置都可以省略,因為spring boot構架會有一些默認的配置可以直接使用,但是想要使用多個數據源時,就需要更多的配置來加以區分來告訴spring boot應該使用哪個數據源,事務管理、session管理等對應的是哪個數據源
1、pom.xml配置文件
在dependencies標簽對中增加兩個dependency標簽對配置數據庫的依賴包,
支持jdbc、Hibernate數據庫鏈接
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
支持mybatis數據庫鏈接
還需要增加兩個dependency標簽對配置
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
2、application.properties配置文件
profiles配置
如果使用profiles配置,可啟用不同環境的配置文件,如:開發環境,測試環境,生產環境
假如現在處於開發階段,那麽在application.properties配置文件中增加
#環境配置
spring.profiles.active=dev
不同環境的配置文件命名示例:
以上配置表明,目前生效的配置文件是application.properties和application-dev.properties兩個文件
數據庫鏈接參數配置
數據庫參數配置(jdbc、Hibernate、mybatis,三種方式的配置都是一樣的
只是定義的名稱要有所區分如dataSource1,dataSource2……,該名稱會在Java配置文件定義其他bean時被引用)
dataSource1.datasource.driverClassName=com.mysql.jdbc.Driver
dataSource1.datasource.jdbc-url=jdbc:mysql://域名:端口號/數據庫名?useUnicode=true&useSSL=false
dataSource1.datasource.username=數據庫用戶名
dataSource1.datasource.password=數據庫密碼
3、Java配置文件
選擇使用Java配置文件來配置,主要是因為項目代碼是使用java語言開發,使用Java配置文件更容易理解
這一步主要的作用是定義各種bean時,定義不同的bean名稱,並且在需要傳入數據庫的方法中,在與第2步數據庫鏈接參數配置的名稱一一對應
Jdbc
註解
@Configuration
什麽是Java配置文件,就是創建的java類,增加了@Configuration註解,這樣spring boot框架掃描bean的時候,才會把這樣的Java類文件當作是配置文件,然後是在類裏面可以隨意的手動增加一些bean
dataSource
DataSource(jdbc、Hibernate、mybatis,三種方式的DataSource配置都是一樣的
只是定義的名稱要有所區分,可以與第2步數據庫鏈接參數配置的名稱,如dataSource1,dataSource2……)
@Bean(name = "dataSource1")//因為是多數據源,所以需要取別名
@Qualifier("dataSource1")
@ConfigurationProperties(prefix = " dataSource1.datasource")//第2步數據庫鏈接參數配置的名稱
public DataSource dataSource1 (){//定義數據源bean
return DataSourceBuilder.create().build();
}
Template
這一步關鍵的生成一個重新命名並配置好數據源的JdbcTemplate
a、 重新命名:在方法前面增加@Bean
@Bean(name = "jdbcTemplate")
b、 定義該方法時要傳入帶了別名的數據源為參數
public JdbcTemplate jdbcTemplate(@Qualifier("dataSource1") DataSource dataSource)
c、 生成的JdbcTemplate並把數據源set進來,然後返回JdbcTemplate
return new JdbcTemplate(dataSource);
使用
直接使用
引入JdbcTemplate就可以調用Template裏封裝的查詢方法了,按封裝方法的要求傳入參數就可以了
@Autowired
private
JdbcTemplate
jdbcTemplate;
JdbcTemplate自帶查詢抽象方法如下:
public <T> List<T> query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper)
實際調用如下:
事先寫好String類型的sql,和要輸入的參數列表params,以及返回結果列表集
BeanPropertyRowMapper是RowMapper的實現類
List<mapper> list = jdbcTemplate.query(sql, params.toArray(), new BeanPropertyRowMapper<>( mapper.class));
b、封裝成通用工具
當然了,如果調用JdbcTemplate的抽象方法之前想多做一些事情,比如打印日誌,參數轉換等,可以按自己的想法,再封裝多一個通用工具
另創建一個類當作通用工具類,引入JdbcTemplate再調用JdbcTemplate裏封裝的查詢方法
@SuppressWarnings("unchecked")
public <T> List<T> querySpaDataList(String sql, Object[] params, Class<T> clazz) {
printSqlToConsole(sql, params);
return jdbcTemplate.query(sql, params, new BeanPropertyRowMapper<T>(clazz));
}
以上封裝的方法增加了查詢語句打印,結果類的參數的做了轉換,在調用時第三個參數可直接傳結果類class
實際調用如下:
List<mapper> list = jdbcTemplate.query(sql, params.toArray(),mapper.class);
mybatis
註解
@Configuration:同JDBC
@ MapperScan:在配置類上增加實體類掃描註解
@MapperScan(basePackages = {"com.myboot.mapper"}, sqlSessionTemplateRef = "sqlSessionTemplate")
basePackages:數據表映射接口所在路徑
sqlSessionTemplateRef:SqlSessionTemplate的bean名稱(要與後面講到的SqlSessionTemplate配置的名稱一致)
dataSource
同jdbc,但名稱要有所區分,
@Bean(name = " dataSource2")
SqlSessionFactory
這一步關鍵的生成一個配置好數據源和XML文件路徑的SqlSessionFactory
a、 重新命名:在方法前面增加@Bean
@Bean(name = "sqlSessionFactory")
b、 定義該方法時要傳入帶了別名的數據源為參數
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource2") DataSource dataSource) throws Exception
c、 在方法內生成一個默認的SqlSessionFactory,並把數據源set進來
SqlSessionFactoryBean
bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
d、 添加XML目錄
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
bean.setMapperLocations(resolver.getResources("classpath:mappings/*.xml"));
e、 記得關鍵語句要捕抓異常,不然intellij IDEA會給你一個錯誤提示
SqlSessionTemplate
這一步關鍵的生成一個配置好SqlSessionFactory的SqlSessionTemplate
a、 重新命名:在方法前面增加@Bean
@Bean(name = "sqlSessionTemplate")
b、 定義該方法時要傳入帶了別名的SqlSessionFactory為參數(要與上一步SqlSessionFactory配置的名稱一致)
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception
c、 在方法內生成一個默認的SqlSessionTemplate,並把SqlSessionFactory set進來
然後返回這個template
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory);
DataSourceTransactionManager
如果你對數據源的操作只有查詢,沒有增加、刪除、修改的操作,那這一步可以不需要
這一步的配置與SqlSessionFactory的配置也有相同之處,那就是生成一個配置好數據源DataSourceTransactionManager
a、 重新命名:在方法前面增加@Bean
@Bean(name = "transactionManager")
b、 定義該方法時要傳入帶了別名的數據源為參數
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource) throws Exception
c、 在方法內生成一個默認的DataSourceTransactionManager,並把數據源set進來
並返回DataSourceTransactionManager
return new DataSourceTransactionManager(dataSource);
使用
本項目中每一個數據表對應一個xml文件,每一個xml文件對應一個數據表映射接口,xml文件和對應的接口分別放到兩個不同的目錄下
xml文件:"classpath:mappings/*.xml"
接口:"com.myboot.mapper"
使用時引入接口,通過接口調用xml裏的sql語句執行數據庫操作
a、 xml文件中必須定義所對應的數據表映射接口的全路徑
<mapper namespace="com.myboot.mapper.Table1Mapper " >
如定義一個查詢方法(resultMap=" Table1",這個要在xml中先定義一個名為Table1的resultMap)
<select id="selectByDate" resultMap=" Table1" parameterType="java.util.HashMap">
SELECT *
FROM ` Table1`
WHERE 1=1
<if test="startDate
!= null and startDate != ‘‘">
and stat_date >= #{startDate}
</if>
<if test="endDate
!= null and endDate != ‘‘">
and stat_date <= #{endDate}
</if>
ORDER BY stat_date DESC
</select>
b、 定義接口
註解:數據訪問Dao註解
@Mapper
@Repository("Table1Mapper ")
Xml的接口(要先寫一個Table1Stat,Table1的實體類)
List< Table1Stat> selectByDate(@Param("startDate")
String startDate,
@Param("endDate") String endDate);
c、 調用接口
引入接口
@Autowired
private Table1Mapper table1Mapper;
通過table1Mapper調用
table1Mapper.selectByDate(startDate, endDate);
hibernate
註解
@Configuration:同JDBC
@EnableTransactionManagement,事務管理
@ EnableJpaRepositories:在配置類上增加實體類掃描註解
@EnableJpaRepositories(entityManagerFactoryRef = "girlEntityManagerFactory", transactionManagerRef = "girlTransactionManager", basePackages = "com.myboot.repository")
basePackages:數據表映射接口所在路徑
entityManagerFactoryRef:entityManagerFactory的bean名稱(要與後面講到的LocalContainerEntityManagerFactoryBean配置的名稱一致)
transactionManagerRef:事務管理的bean名稱(要與後面講到的PlatformTransactionManager配置的名稱一致)
dataSource
同jdbc,但名稱要有所區分,
@Bean(name = " dataSource3")
LocalContainerEntityManagerFactoryBean
這一步關鍵通過EntityManagerFactoryBuilder生成一個配置好數據源、實體類等屬性的EntityManagerFactory
a、 重新命名:在方法前面增加@Bean
@Bean(name = "girlEntityManagerFactory")
b、 定義該方法時要傳入帶了別名的數據源和EntityManagerFactoryBuilder為參數
public LocalContainerEntityManagerFactoryBean girlEntityManagerFactory (@Qualifier("dataSource3") DataSource dataSource,EntityManagerFactoryBuilder builder)
c、 在方法內通過EntityManagerFactoryBuilder 把屬性set進來
然後返回這個LocalContainerEntityManagerFactoryBean
return builder
.dataSource(dataSource)
.properties(getVendorProperties())
.packages("com.myboot.entity")
.persistenceUnit("primaryPersistenceUnit")
.build();
getVendorProperties()這個方法要先定義好
@Autowired
private JpaProperties jpaProperties;
private Map<String, Object>
getVendorProperties() {
return jpaProperties.getHibernateProperties(new HibernateSettings());
}
PlatformTransactionManager
如果你對數據源的操作只有查詢,沒有增加、刪除、修改的操作,那這一步可以不需要
這一步的配置與SqlSessionFactory的配置也有相同之處,那就是生成一個配置好數據源DataSourceTransactionManager
a、 重新命名:在方法前面增加@Bean
@Bean(name = "girlTransactionManager")
b、 定義該方法時要傳入帶了別名的數據源為參數
public PlatformTransactionManager girlTransactionManager(@Qualifier("dataSource3")DataSource dataSource, EntityManagerFactoryBuilder builder)
c、 在方法內生成一個默認的DataSourceTransactionManager,並把數據源set進來
並返回TransactionManager
return new JpaTransactionManager(girlEntityManagerFactory(dataSource, builder).getObject());
使用
本項目中每一個數據表對應一個實體類,每一個實體類對應一個數據表映射接口,實體類和對應的接口分別放到兩個不同的目錄下
實體類:"com.myboot.entity"
接口:"com.myboot.repository"
使用時引入接口,通過接口調用xml裏的sql語句執行數據庫操作
a、 實體類中必須定義所對應的數據表,並增加實體類註解@Entity
@Entity
@Table(name = "girl")
b、 定義接口(其中Girl就是實體類,JpaRepository是spring boot框架提供的數據庫訪問接口)
public interface GirlDao extends JpaRepository<Girl, Integer>
c、 數據庫執行接口
@Query("select g from Girl g where g.createTime >= startDate and g.createTime < endDate ")
List< Girl > selectByDate(String startDate, String endDate);
d、 調用接口
引入接口
@Autowired
GirlDao girlDao;
通過girlDao調用
girlDao.selectByDate(startDate, endDate);
girlDao.findAll();//JpaRepository接口自帶的查詢方法
多數據源配置