关于
有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据。另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据库等等。
下面分享我在实际项目中配置多数据源的案例。话不多说了,来一起看看详细的介绍吧
步骤
1.application.yml文件中,配置数据库源。这里primary是主库,secondary是从库。
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
|
server:
port: 8089
# 多数据源配置
#primary
spring:
primary:
datasource:
url: jdbc:mysql: //127.0.0.1:3306/database1?autoreconnect=true&useunicode=true&characterencoding=utf-8&usessl=false&uselegacydatetimecode=false&servertimezone=asia/shanghai
username: root
password: ******
driver- class -name: com.mysql.jdbc.driver
#secondary
secondary:
datasource:
url: jdbc:mysql: //127.0.0.1:3306/database1?autoreconnect=true&useunicode=true&characterencoding=utf-8&usessl=false&uselegacydatetimecode=false&servertimezone=asia/shanghai
username: root
password: ******
driver- class -name: com.mysql.jdbc.driver
jpa:
hibernate:
primary-dialect: org.hibernate.dialect.mysql5dialect
secondary-dialect: org.hibernate.dialect.mysql5dialect
open-in-view: true
show-sql: true
|
2.创建一个spring配置类,其中spring.primary.datasource的路径参考yml文件的配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@configuration
public class datasourceconfig {
@bean (name = "primarydatasource" )
@qualifier ( "primarydatasource" )
@configurationproperties (prefix= "spring.primary.datasource" )
public datasource primarydatasource() {
return datasourcebuilder.create().build();
}
@bean (name = "secondarydatasource" )
@qualifier ( "secondarydatasource" )
@primary
@configurationproperties (prefix= "spring.secondary.datasource" )
public datasource secondarydatasource() {
return datasourcebuilder.create().build();
}
}
|
3.分别创建主库、从库的配置类。
注意:entity包和dao包的配置,以及@primary注解指定主库。
主库配置类:
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
|
@configuration
@enabletransactionmanagement
@enablejparepositories (
entitymanagerfactoryref = "entitymanagerfactoryprimary" ,
transactionmanagerref = "transactionmanagerprimary" ,
basepackages = { "com.infinitus.yunxiao_data.dao.primary" }) //设置repository所在位置
public class primaryconfig {
@autowired
private jpaproperties jpaproperties;
@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( "com.infinitus.yunxiao_data.entity.primary" ) //设置实体类所在位置
.persistenceunit( "primarypersistenceunit" )
.build();
}
private map getvendorproperties(datasource datasource) {
return jpaproperties.gethibernateproperties(datasource);
}
@primary
@bean (name = "transactionmanagerprimary" )
public platformtransactionmanager transactionmanagerprimary(entitymanagerfactorybuilder builder) {
return new jpatransactionmanager(entitymanagerfactoryprimary(builder).getobject());
}
}
|
从库的配置类:
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
|
@configuration
@enabletransactionmanagement
@enablejparepositories (
entitymanagerfactoryref = "entitymanagerfactorysecondary" ,
transactionmanagerref = "transactionmanagersecondary" ,
basepackages = { "com.infinitus.yunxiao_data.dao.secondary" }) //设置repository所在位置
public class secondaryconfig {
@autowired
private jpaproperties jpaproperties;
@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( "com.infinitus.yunxiao_data.entity.secondary" ) //设置实体类所在位置
.persistenceunit( "primarypersistenceunit" )
.build();
}
private map getvendorproperties(datasource datasource) {
return jpaproperties.gethibernateproperties(datasource);
}
@bean (name = "transactionmanagersecondary" )
platformtransactionmanager transactionmanagersecondary(entitymanagerfactorybuilder builder) {
return new jpatransactionmanager(entitymanagerfactorysecondary(builder).getobject());
}
}
|
4.分别创建主、从库dao类。
主dao:
1
2
3
4
5
6
7
|
@repository
public interface primaryrepository extends jparepository<primaryentity, long > {
@query (value = "select p from primaryentity p" )
list<primaryentity> querylist();
}
|
从dao:
1
2
3
4
5
6
7
|
@repository
public interface secondaryrepository extends jparepository<secondaryentity, long > {
@query (value = "select p from secondaryentity p" )
list<secondaryentity> querylist();
}
|
5.分别创建主、从库entity类。
主entity:
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
50
51
52
53
54
55
|
@entity
@table (name = "holiday_scheme" )
@entitylisteners (auditingentitylistener. class )
public class primaryentity extends abstractpersistable< long > {
@column (name = "date" )
public string date;
@column (name = "hour" )
public string hour;
@column (name = "holiday" )
public string holiday;
@column (name = "holiday_explain" )
public string holiday_explain;
public string getdate() {
return date;
}
public void setdate(string date) {
this .date = date;
}
public string gethour() {
return hour;
}
public void sethour(string hour) {
this .hour = hour;
}
public string getholiday() {
return holiday;
}
public void setholiday(string holiday) {
this .holiday = holiday;
}
public string getholiday_explain() {
return holiday_explain;
}
public void setholiday_explain(string holiday_explain) {
this .holiday_explain = holiday_explain;
}
@override
public string tostring() {
return "primaryentity{" +
"date='" + date + '\ '' +
", hour='" + hour + '\ '' +
", holiday='" + holiday + '\ '' +
", holiday_explain='" + holiday_explain + '\ '' +
'}' ;
}
}
|
从entity:
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
|
@entity
@table (name = "active_dashboards" )
@entitylisteners (auditingentitylistener. class )
public class secondaryentity extends abstractpersistable< long > {
@column (name = "dashboard_id" )
public string dashboard_id;
@column (name = "user_id" )
public string user_id;
@column (name = "order_index" )
public string order_index;
public string getdashboard_id() {
return dashboard_id;
}
public void setdashboard_id(string dashboard_id) {
this .dashboard_id = dashboard_id;
}
public string getuser_id() {
return user_id;
}
public void setuser_id(string user_id) {
this .user_id = user_id;
}
public string getorder_index() {
return order_index;
}
public void setorder_index(string order_index) {
this .order_index = order_index;
}
@override
public string tostring() {
return "secondaryentity{" +
"dashboard_id='" + dashboard_id + '\ '' +
", user_id='" + user_id + '\ '' +
", order_index='" + order_index + '\ '' +
'}' ;
}
}
|
6.controller请求获取不同数据库的数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@restcontroller
@requestmapping ( "/database" )
public class mailcontroller {
private final logger logger = loggerfactory.getlogger( this .getclass());
@autowired
primaryrepository primaryrepository;
@autowired
secondaryrepository secondaryrepository;
@requestmapping ( "/primary" )
@responsebody
public string primary() {
return primaryrepository.querylist().tostring();
}
@requestmapping ( "/secondary" )
@responsebody
public string secondary() {
return secondaryrepository.querylist().tostring();
}
}
|
注意
下面提两个在配置多数据源时遇到的坑点,一不注意就掉坑了。
1.application类不需要配置@enablejparepositories注解,会报如下错误。
a component required a bean named 'entitymanagerfactory' that could not be f
2.注意检查dao类,获取数据的方法上格式是否正确,有没有某个字段是表中不存在的,避免启动异常。如下,secondaryentity表中是不存在job_name字段的,所以注释掉才能启动成功等。
1
2
|
//@query(value = "select p from secondaryentity p where p.job_name = ?1")
//list<secondaryentity> queryodcrecord(string job_name);
|
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://huangweicai.github.io/2019/01/08/SpringBoot+Jpa多数据源配置/