今天临下班时遇到了一个需求,我的管理平台需要从不同的数据库中获取数据信息,这就需要进行spring的多数据源配置,对于这种配置,第一次永远都是痛苦的,不过经历了这次的折磨,今后肯定会对这种配置印象深刻。我们这里简单回顾一下流程。
我们配置了两个数据库,一个是公司的数据库,另一个是我本地的一个数据库。首先是application.yml的配置(其中对于公司的数据库我们采取了假的地址,而本机的数据库是真是存在对应的表和库的)
数据库信息:
数据表信息:
1、application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
datasource:
primary:
url: jdbc:mysql: //companyurl.com:5002/db1
username: unameq
password: passwd1
driver- class -name: com.mysql.jdbc.driver
secondary:
url: jdbc:mysql: //localhost:3306/django_test
username: root
password: 123456
driver- class -name: com.mysql.jdbc.driver
jpa:
database-platform: org.hibernate.dialect.mysql5dialect
hibernate:
ddl-auto: update
show-sql: true
|
2、创建总的datasource配置文件以及两个repostory的配置文件primaryconfig以及secondaryconfig
datasourceconfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@configuration
public class datasourceconfig {
@bean (name = "primarydatasource" )
@qualifier ( "primarydatasource" )
@configurationproperties (prefix= "spring.datasource.primary" ) //对应的数据库配置信息
public datasource primarydatasource() {
return datasourcebuilder.create().build();
}
@bean (name = "secondarydatasource" )
@qualifier ( "secondarydatasource" )
@primary
@configurationproperties (prefix= "spring.datasource.secondary" )
public datasource secondarydatasource() {
return datasourcebuilder.create().build();
}
}
|
primaryconfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
@configuration
@enabletransactionmanagement
@enablejparepositories (
entitymanagerfactoryref= "entitymanagerfactoryprimary" ,
transactionmanagerref= "transactionmanagerprimary" ,
basepackages= { "数据访问层所在的包" }) //设置repository所在位置
public class primaryconfig {
@autowired @qualifier ( "primarydatasource" )
private datasource primarydatasource;
@primary
@bean (name = "entitymanagerprimary" )
public entitymanager entitymanager(entitymanagerfactorybuilder builder) {
return entitymanagerfactoryprimary(builder).getobject().createentitymanager();
}
@primary
@bean (name = "entitymanagerfactoryprimary" )
public localcontainerentitymanagerfactorybean entitymanagerfactoryprimary (entitymanagerfactorybuilder builder) {
return builder
.datasource(primarydatasource)
.properties(getvendorproperties(primarydatasource))
.packages( "实体类所在的包" ) //设置实体类所在位置
.persistenceunit( "primarypersistenceunit" )
.build();
}
@autowired
private jpaproperties jpaproperties;
private map<string, string> getvendorproperties(datasource datasource) {
return jpaproperties.gethibernateproperties(datasource);
}
@primary
@bean (name = "transactionmanagerprimary" )
public platformtransactionmanager transactionmanagerprimary(entitymanagerfactorybuilder builder) {
return new jpatransactionmanager(entitymanagerfactoryprimary(builder).getobject());
}
}
|
secondaryconfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
@configuration
@enabletransactionmanagement
@enablejparepositories (
entitymanagerfactoryref= "entitymanagerfactorysecondary" ,
transactionmanagerref= "transactionmanagersecondary" ,
basepackages= { "数据访问层所在的包" }) //设置repository所在位置
public class secondaryconfig {
@autowired
@qualifier ( "secondarydatasource" )
private datasource secondarydatasource;
@bean (name = "entitymanagersecondary" )
public entitymanager entitymanager(entitymanagerfactorybuilder builder) {
return entitymanagerfactorysecondary(builder).getobject().createentitymanager();
}
@bean (name = "entitymanagerfactorysecondary" )
public localcontainerentitymanagerfactorybean entitymanagerfactorysecondary(entitymanagerfactorybuilder builder) {
return builder
.datasource(secondarydatasource)
.properties(getvendorproperties(secondarydatasource))
.packages( "实体类所在的包" ) //设置实体类所在位置
.persistenceunit( "secondarypersistenceunit" )
.build();
}
@autowired
private jpaproperties jpaproperties;
private map<string, string> getvendorproperties(datasource datasource) {
return jpaproperties.gethibernateproperties(datasource);
}
@bean (name = "transactionmanagersecondary" )
platformtransactionmanager transactionmanagersecondary(entitymanagerfactorybuilder builder) {
return new jpatransactionmanager(entitymanagerfactorysecondary(builder).getobject());
}
}
|
3、然后我对于本地数据库新建实体类peopleperson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
@entity
@table (name = "people_person" )
public class peopleperson implements serializable {
@id
@generatedvalue
private integer id;
@column (name = "name" )
private string name;
@column (name = "age" )
private integer age;
public peopleperson() {
}
public integer getid() {
return id;
}
public void setid(integer id) {
this .id = id;
}
public string getname() {
return name;
}
public void setname(string name) {
this .name = name;
}
public integer getage() {
return age;
}
public void setage(integer age) {
this .age = age;
}
@override
public string tostring() {
return "peopleperson{" +
"id=" + id +
", name='" + name + '\ '' +
", age=" + age +
'}' ;
}
}
|
并创建对应的repositoy,peoplepersondao并创建了一个findall的方法
1
2
3
4
|
@transactional @repositorypublic interface peoplepersondao extends jparepository<peopleperson, long >
{
list<peopleperson> findall();
}
|
4、最后,在test包中进行测试
1
2
3
4
5
6
7
8
9
|
@autowired
private peoplepersondao peoplepersondao;
@test
public void testmultidatasource() {
list<peopleperson> list = peoplepersondao.findall();
for ( int i = 0 ; i < list.size(); i++) {
logger.info(list.get(i).tostring());
}
}
|
测试结果
一些坑
不仅仅是dao层扫描的包需要区分,对于实体类所在的包,不同的datasource的配置中也需要区分开
对于这种套路性的东西,总结一遍是非常必要的,下次可以节省许多不必要的时间,对于内部原理,我将在完成对ioc和aop分析后反过来分析其原理。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://bryantchang.github.io/2018/07/31/spring-multidatasource/