多数据源

我是相当新的春季启动,我想为我的项目创建一个多数据源。 这是我目前的情况。我有两个包的实体多个数据库。让我们说

com.test.entity.db.mysql ; for entities that belong to MySql
com.test.entity.db.h2 ; for entities that belong to H2 Databases

现在我有两个实体类

UserMySql.java

@Entity
@Table(name="usermysql")
public class UserMysql{


@Id
@GeneratedValue
public int id;


public String name;


}

UserH2.java

@Entity
@Table(name="userh2")
public class Userh2 {


@Id
@GeneratedValue
public int id;


public String name;
}

我想实现一个配置,如果我从 UserMySql 创建用户,它将被保存到 MySql 数据库,如果我从 Userh2创建用户,它将被保存到 H2数据库。因此,我还有两个 DBConfig,比如 MySqlDbConfig 和 H2DbConfig。

Model 是我放置 Repositories 类的包,它将在下面定义

Java

@Configuration
@EnableJpaRepositories(
basePackages="com.test.model",
entityManagerFactoryRef = "mysqlEntityManager")
public class MySqlDBConfig {


@Bean
@Primary
@ConfigurationProperties(prefix="datasource.test.mysql")
public DataSource mysqlDataSource(){
return DataSourceBuilder
.create()
.build();
}


@Bean(name="mysqlEntityManager")
public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(
EntityManagerFactoryBuilder builder){
return builder.dataSource(mysqlDataSource())
.packages("com.test.entity.db.mysql")
.build();
}


}

H2DbConfig.java

@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "h2EntityManager")
public class H2DbConfig {


@Bean
@ConfigurationProperties(prefix="datasource.test.h2")
public DataSource h2DataSource(){
return DataSourceBuilder
.create()
.driverClassName("org.h2.Driver")
.build();
}


@Bean(name="h2EntityManager")
public LocalContainerEntityManagerFactoryBean h2EntityManagerFactory(
EntityManagerFactoryBuilder builder){
return builder.dataSource(h2DataSource())
.packages("com.test.entity.db.h2")
.build();
}
}

我的 application.properties 文件

#DataSource settings for mysql
datasource.test.mysql.jdbcUrl = jdbc:mysql://127.0.0.1:3306/test
datasource.test.mysql.username = root
datasource.test.mysql.password = root
datasource.test.mysql.driverClassName = com.mysql.jdbc.Driver


#DataSource settings for H2
datasource.test.h2.jdbcUrl = jdbc:h2:~/test
datasource.test.h2.username = sa


# DataSource settings: set here configurations for the database connection
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.validation-query=SELECT 1




# Specify the DBMS
spring.jpa.database = MYSQL


# Show or not log for each sql query
spring.jpa.show-sql = true


# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.hibernate.show_sql = true
spring.jpa.hibernate.format_sql = true


server.port=8080
endpoints.shutdown.enabled=false

然后是 UserMySqlDao 和 UserH2Dao

UserMySqlDa.java

@Transactional
@Repository
public interface UserMysqlDao extends CrudRepository<UserMysql, Integer>{


public UserMysql findByName(String name);
}

UserH2Da.java

@Transactional
@Repositories
public interface UserH2Dao extends CrudRepository<Userh2, Integer>{


public Userh2 findByName(String name);
}

最后,我有一个用户控制器作为端点来访问我的服务

UserController.java

@Controller
@RequestMapping("/user")
public class UserController {




@Autowired
private UserMysqlDao userMysqlDao;


@Autowired
private UserH2Dao userH2Dao;


@RequestMapping("/createM")
@ResponseBody
public String createUserMySql(String name){
UserMysql user = new UserMysql();
try{
user.name = name;
userMysqlDao.save(user);
return "Success creating user with Id: "+user.id;
}catch(Exception ex){
return "Error creating the user: " + ex.toString();
}
}


@RequestMapping("/createH")
@ResponseBody
public String createUserH2(String name){
Userh2 user = new Userh2();
try{
user.name = name;
userH2Dao.save(user);
return "Success creating user with Id: "+user.id;
}catch(Exception ex){
return "Error creating the user: " + ex.toString();
}
}
}

应用程序

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@EntityScan(basePackages="com.test.entity.db")
@ComponentScan
public class Application {


public static void main(String[] args) {
System.out.println("Entering spring boot");
ApplicationContext ctx = SpringApplication.run(Application.class, args);


System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.print(beanName);
System.out.print(" ");
}


System.out.println("");
}


}

通过这个配置,我的 Spring 启动运行良好,但是当我访问

http://localhost/user/createM?name=myname it writes an exception


Error creating the user: org.springframework.dao.InvalidDataAccessResourceUsageException:   could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement

我到处搜索,还没找到解决办法。知道为什么会出现这种异常吗?这是实现多个数据源来实现我上面的案例的最佳方式吗?如果需要,我愿意进行全面重构。

谢谢

164133 次浏览

我想你会发现它很有用

Http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources

它展示了如何定义多个数据源并指定其中一个作为主要数据源。

这里有一个相当完整的示例,还包含分布事务——如果您需要的话。

Http://fabiomaffioletti.me/blog/2014/04/15/distributed-transactions-multiple-databases-spring-boot-spring-data-jpa-atomikos/

您所需要的是创建2个配置类,分离模型/存储库包等,使配置变得简单。

此外,在上面的示例中,它还手动创建数据源。您可以使用 Spring doc 上的方法,使用@ConfigurationProperties 注释来避免这种情况。这里有一个例子:

Http://xantorohara.blogspot.com.tr/2013/11/spring-boot-jdbc-with-multiple.html

希望这些有用。

我用这种方法解决了这个问题(如何使用 spring 和 Hibernate 连接多个数据库) ,希望对您有所帮助:)

注意: 我已经添加了相关的代码,请使道的帮助下,我用在下面提到的代码。

Xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>MultipleDatabaseConnectivityInSpring</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
</param-value>
</context-param>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>

Xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="localPersistenceUnitOne"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>in.india.entities.CustomerDetails</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.jdbc.batch_size" value="0" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/shankar?sslmode=require" />
<property name="hibernate.connection.username" value="username" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
<persistence-unit name="localPersistenceUnitTwo"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>in.india.entities.CompanyDetails</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.jdbc.batch_size" value="0" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/shankarTwo?sslmode=require" />
<property name="hibernate.connection.username" value="username" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>

调度程序-servlet

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
default-autowire="byName"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Configure messageSource -->


<mvc:annotation-driven />
<context:component-scan base-package="in.india.*" />
<bean id="messageResource"
class="org.springframework.context.support.ResourceBundleMessageSource"
autowire="byName">
<property name="basename" value="messageResource"></property>
</bean>


<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>






<bean id="entityManagerFactoryOne"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
autowire="constructor">
<property name="persistenceUnitName" value="localPersistenceUnitOne" />
</bean>


<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
autowire="byName">
<property name="basename" value="messageResource" />
</bean>


<bean id="entityManagerFactoryTwo"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
autowire="constructor">
<property name="persistenceUnitName" value="localPersistenceUnitTwo" />
</bean>


<bean id="manager1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryOne" />
</bean>


<bean id="manager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryTwo" />
</bean>


<tx:annotation-driven transaction-manager="manager1" />
<tx:annotation-driven transaction-manager="manager2" />


<!-- declare dependies here -->


<bean class="in.india.service.dao.impl.CustomerServiceImpl" />
<bean class="in.india.service.dao.impl.CompanyServiceImpl" />


<!-- Configure MVC annotations -->
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</beans>

Java 类保存到一个数据库中

package in.india.service.dao.impl;


import in.india.entities.CompanyDetails;
import in.india.service.CompanyService;


import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;


import org.springframework.transaction.annotation.Transactional;


public class CompanyServiceImpl implements CompanyService {


@PersistenceContext(unitName = "entityManagerFactoryTwo")
EntityManager entityManager;


@Transactional("manager2")
@Override
public boolean companyService(CompanyDetails companyDetails) {


boolean flag = false;
try
{
entityManager.persist(companyDetails);
flag = true;
}
catch (Exception e)
{
flag = false;
}


return flag;
}


}

Java 类保存在另一个数据库

package in.india.service.dao.impl;


import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;


import org.springframework.transaction.annotation.Transactional;


import in.india.entities.CustomerDetails;
import in.india.service.CustomerService;


public class CustomerServiceImpl implements CustomerService {


@PersistenceContext(unitName = "localPersistenceUnitOne")
EntityManager entityManager;


@Override
@Transactional(value = "manager1")
public boolean customerService(CustomerDetails companyData) {


boolean flag = false;
entityManager.persist(companyData);
return flag;
}
}

Customer.jsp

<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<center>
<h1>SpringWithMultipleDatabase's</h1>
</center>
<form:form method="GET" action="addCustomer.htm"  modelAttribute="customerBean" >
<table>
<tr>
<td><form:label path="firstName">First Name</form:label></td>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td><form:label path="lastName">Last Name</form:label></td>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td><form:label path="emailId">Email Id</form:label></td>
<td><form:input path="emailId" /></td>
</tr>
<tr>
<td><form:label path="profession">Profession</form:label></td>
<td><form:input path="profession" /></td>
</tr>
<tr>
<td><form:label path="address">Address</form:label></td>
<td><form:input path="address" /></td>
</tr>
<tr>
<td><form:label path="age">Age</form:label></td>
<td><form:input path="age" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
</body>
</html>

公司

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ScheduleJobs</title>
</head>
<body>
<center><h1>SpringWithMultipleDatabase's</h1></center>
<form:form method="GET" action="addCompany.htm"  modelAttribute="companyBean" >
<table>
<tr>
<td><form:label path="companyName">Company Name</form:label></td>
<td><form:input path="companyName" /></td>
</tr>
<tr>
<td><form:label path="companyStrength">Company Strength</form:label></td>
<td><form:input path="companyStrength" /></td>
</tr>
<tr>
<td><form:label path="companyLocation">Company Location</form:label></td>
<td><form:input path="companyLocation" /></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>

Jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>
<center><h1>Multiple Database Connectivity In Spring sdfsdsd</h1></center>


<a href='customerRequest.htm'>Click here to go on Customer page</a>
<br>
<a href='companyRequest.htm'>Click here to go on Company page</a>
</body>
</html>

成功

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ScheduleJobs</title>
</head>
<body>
<center><h1>SpringWithMultipleDatabase</h1></center>
<b>Successfully Saved</b>
</body>
</html>

公司总监

package in.india.controller;


import in.india.bean.CompanyBean;
import in.india.entities.CompanyDetails;
import in.india.service.CompanyService;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;


@Controller
public class CompanyController {


@Autowired
CompanyService companyService;


@RequestMapping(value = "/companyRequest.htm", method = RequestMethod.GET)
public ModelAndView addStudent(ModelMap model) {
CompanyBean companyBean = new CompanyBean();
model.addAttribute(companyBean);
return new ModelAndView("company");
}


@RequestMapping(value = "/addCompany.htm", method = RequestMethod.GET)
public ModelAndView companyController(@ModelAttribute("companyBean") CompanyBean companyBean, Model model) {
CompanyDetails  companyDetails = new CompanyDetails();
companyDetails.setCompanyLocation(companyBean.getCompanyLocation());
companyDetails.setCompanyName(companyBean.getCompanyName());
companyDetails.setCompanyStrength(companyBean.getCompanyStrength());
companyService.companyService(companyDetails);
return new ModelAndView("success");


}
}

客户控制器

package in.india.controller;


import in.india.bean.CustomerBean;
import in.india.entities.CustomerDetails;
import in.india.service.CustomerService;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;


@Controller
public class CustomerController {


@Autowired
CustomerService customerService;


@RequestMapping(value = "/customerRequest.htm", method = RequestMethod.GET)
public ModelAndView addStudent(ModelMap model) {
CustomerBean customerBean = new CustomerBean();
model.addAttribute(customerBean);
return new ModelAndView("customer");
}


@RequestMapping(value = "/addCustomer.htm", method = RequestMethod.GET)
public ModelAndView customerController(@ModelAttribute("customerBean") CustomerBean customer, Model model) {
CustomerDetails customerDetails = new CustomerDetails();
customerDetails.setAddress(customer.getAddress());
customerDetails.setAge(customer.getAge());
customerDetails.setEmailId(customer.getEmailId());
customerDetails.setFirstName(customer.getFirstName());
customerDetails.setLastName(customer.getLastName());
customerDetails.setProfession(customer.getProfession());
customerService.customerService(customerDetails);
return new ModelAndView("success");


}
}

公司详细信息实体

package in.india.entities;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


@Entity
@Table(name = "company_details")
public class CompanyDetails {


@Id
@SequenceGenerator(name = "company_details_seq", sequenceName = "company_details_seq", initialValue = 1, allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "company_details_seq")
@Column(name = "company_details_id")
private Long companyDetailsId;
@Column(name = "company_name")
private String companyName;
@Column(name = "company_strength")
private Long companyStrength;
@Column(name = "company_location")
private String companyLocation;


public Long getCompanyDetailsId() {
return companyDetailsId;
}


public void setCompanyDetailsId(Long companyDetailsId) {
this.companyDetailsId = companyDetailsId;
}


public String getCompanyName() {
return companyName;
}


public void setCompanyName(String companyName) {
this.companyName = companyName;
}


public Long getCompanyStrength() {
return companyStrength;
}


public void setCompanyStrength(Long companyStrength) {
this.companyStrength = companyStrength;
}


public String getCompanyLocation() {
return companyLocation;
}


public void setCompanyLocation(String companyLocation) {
this.companyLocation = companyLocation;
}
}

CustomerDetails 实体

package in.india.entities;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;


@Entity
@Table(name = "customer_details")
public class CustomerDetails {


@Id
@SequenceGenerator(name = "customer_details_seq", sequenceName = "customer_details_seq", initialValue = 1, allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customer_details_seq")
@Column(name = "customer_details_id")
private Long customerDetailsId;
@Column(name = "first_name ")
private String firstName;
@Column(name = "last_name ")
private String lastName;
@Column(name = "email_id")
private String emailId;
@Column(name = "profession")
private String profession;
@Column(name = "address")
private String address;
@Column(name = "age")
private int age;
public Long getCustomerDetailsId() {
return customerDetailsId;
}


public void setCustomerDetailsId(Long customerDetailsId) {
this.customerDetailsId = customerDetailsId;
}


public String getFirstName() {
return firstName;
}


public void setFirstName(String firstName) {
this.firstName = firstName;
}


public String getLastName() {
return lastName;
}


public void setLastName(String lastName) {
this.lastName = lastName;
}


public String getEmailId() {
return emailId;
}


public void setEmailId(String emailId) {
this.emailId = emailId;
}


public String getProfession() {
return profession;
}


public void setProfession(String profession) {
this.profession = profession;
}


public String getAddress() {
return address;
}


public void setAddress(String address) {
this.address = address;
}


public int getAge() {
return age;
}


public void setAge(int age) {
this.age = age;
}
}

几天前我遇到了同样的问题,我按照下面提到的链接,我可以克服这个问题

Http://www.baeldung.com/spring-data-jpa-multiple-databases

使用多个数据源或实现读写分离。 你必须有类 AbstractRoutingDataSource的知识,支持动态数据源的选择。

这是我的 datasource.yaml,我知道如何解决这个问题。您可以参考此项目 弹簧靴 + 石英。希望这个能帮到你。

dbServer:
default: localhost:3306
read: localhost:3306
write: localhost:3306
datasource:
default:
type: com.zaxxer.hikari.HikariDataSource
pool-name: default
continue-on-error: false
jdbc-url: jdbc:mysql://${dbServer.default}/schedule_job?useSSL=true&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf8
username: root
password: lh1234
connection-timeout: 30000
connection-test-query: SELECT 1
maximum-pool-size: 5
minimum-idle: 2
idle-timeout: 600000
destroy-method: shutdown
auto-commit: false
read:
type: com.zaxxer.hikari.HikariDataSource
pool-name: read
continue-on-error: false
jdbc-url: jdbc:mysql://${dbServer.read}/schedule_job?useSSL=true&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf8
username: root
password: lh1234
connection-timeout: 30000
connection-test-query: SELECT 1
maximum-pool-size: 5
minimum-idle: 2
idle-timeout: 600000
destroy-method: shutdown
auto-commit: false
write:
type: com.zaxxer.hikari.HikariDataSource
pool-name: write
continue-on-error: false
jdbc-url: jdbc:mysql://${dbServer.write}/schedule_job?useSSL=true&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf8
username: root
password: lh1234
connection-timeout: 30000
connection-test-query: SELECT 1
maximum-pool-size: 5
minimum-idle: 2
idle-timeout: 600000
destroy-method: shutdown
auto-commit: false

使用两个数据源,您需要它们自己的事务管理器。

@Configuration
public class MySqlDBConfig {
@Bean
@Primary
@ConfigurationProperties(prefix="datasource.test.mysql")
public DataSource mysqlDataSource(){
return DataSourceBuilder
.create()
.build();
}


@Bean("mysqlTx")
public DataSourceTransactionManager mysqlTx() {
return new DataSourceTransactionManager(mysqlDataSource());
}


// same for another DS
}

然后在@Transaction 中相应地使用它

@Transactional("mysqlTx")
@Repository
public interface UserMysqlDao extends CrudRepository<UserMysql, Integer>{
public UserMysql findByName(String name);
}

感谢您的帮助,但它并不复杂,因为它似乎;

在我的案例中,我想用 Mysql 和 Mongodb和解决方案是在我的应用程序类中使用 EnableMongoRepositoriesEnableJpaRepositories注释。

@SpringBootApplication
@EnableTransactionManagement
@EnableMongoRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MongoRepository))
@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MongoRepository))
class TestApplication { ...

注意: 所有 mysql 实体必须扩展 JpaRepository,而 mongo 实体必须扩展 MongoRepository

数据源配置如 Spring 文档所示,非常简单:

//mysql db config
spring.datasource.url= jdbc:mysql://localhost:3306/tangio
spring.datasource.username=test
spring.datasource.password=test


#mongodb config
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=tangio
spring.data.mongodb.username=tangio
spring.data.mongodb.password=tangio
spring.data.mongodb.repositories.enabled=true

一旦您开始使用 jpa,并且某个驱动程序在您的类路径中,Spring 启动就会立即将其作为您的数据源(例如 h2)放入其中 使用默认数据源,因此您只需要定义

spring.datasource.url= jdbc:mysql://localhost:3306/
spring.datasource.username=test
spring.datasource.password=test

如果我们再进一步,你想用两个 我建议使用两个数据源,比如这里解释的: Spring 启动配置和使用两个数据源

用 Spring Boot 1.5.8更新2018-01-07

如果您想知道如何配置它,如何使用它,以及如何控制事务。我也许能给你答案。

您可以在 https://www.surasint.com/spring-boot-with-multiple-databases-example/中看到可运行的示例和一些解释

我复制了一些代码。

首先,您必须像这样设置 application.properties

#Database
database1.datasource.url=jdbc:mysql://localhost/testdb
database1.datasource.username=root
database1.datasource.password=root
database1.datasource.driver-class-name=com.mysql.jdbc.Driver


database2.datasource.url=jdbc:mysql://localhost/testdb2
database2.datasource.username=root
database2.datasource.password=root
database2.datasource.driver-class-name=com.mysql.jdbc.Driver

然后将它们定义为提供者(@Bean) ,如下所示:

@Bean(name = "datasource1")
@ConfigurationProperties("database1.datasource")
@Primary
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}


@Bean(name = "datasource2")
@ConfigurationProperties("database2.datasource")
public DataSource dataSource2(){
return DataSourceBuilder.create().build();
}

注意,我有@Bean (name = “ datource1”)和@Bean (name = “ datource2”) ,那么当我们需要数据源时,例如@Qualifier (“ datource1”)和@Qualifier (“ datource2”)就可以使用它

@Qualifier("datasource1")
@Autowired
private DataSource dataSource;

如果您确实关心事务,则必须为它们定义 DataSourceTransactionManager,如下所示:

@Bean(name="tm1")
@Autowired
@Primary
DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) {
DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
return txm;
}


@Bean(name="tm2")
@Autowired
DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) {
DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
return txm;
}

然后你就可以像

@Transactional //this will use the first datasource because it is @primary

或者

@Transactional("tm2")

这应该足够了。请参阅上面的链接中的例子和细节。

编译: pestwave

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "PACKAGE OF YOUR CRUDS USING MYSQL DATABASE",entityManagerFactoryRef = "mysqlEmFactory" ,transactionManagerRef = "mysqlTransactionManager")
public class MySqlBDConfig{


@Autowired
private Environment env;


@Bean(name="mysqlProperities")
@ConfigurationProperties(prefix="spring.mysql")
public DataSourceProperties mysqlProperities(){
return new  DataSourceProperties();
}




@Bean(name="mysqlDataSource")
public DataSource interfaceDS(@Qualifier("mysqlProperities")DataSourceProperties dataSourceProperties){
return dataSourceProperties.initializeDataSourceBuilder().build();


}


@Primary
@Bean(name="mysqlEmFactory")
public LocalContainerEntityManagerFactoryBean mysqlEmFactory(@Qualifier("mysqlDataSource")DataSource mysqlDataSource,EntityManagerFactoryBuilder builder){
return builder.dataSource(mysqlDataSource).packages("PACKAGE OF YOUR MODELS").build();
}




@Bean(name="mysqlTransactionManager")
public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysqlEmFactory")EntityManagerFactory factory){
return new JpaTransactionManager(factory);
}
}

H2DBConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "PACKAGE OF YOUR CRUDS USING MYSQL DATABASE",entityManagerFactoryRef = "dsEmFactory" ,transactionManagerRef = "dsTransactionManager")
public class H2DBConfig{


@Autowired
private Environment env;


@Bean(name="dsProperities")
@ConfigurationProperties(prefix="spring.h2")
public DataSourceProperties dsProperities(){
return new  DataSourceProperties();
}




@Bean(name="dsDataSource")
public DataSource dsDataSource(@Qualifier("dsProperities")DataSourceProperties dataSourceProperties){
return dataSourceProperties.initializeDataSourceBuilder().build();


}


@Bean(name="dsEmFactory")
public LocalContainerEntityManagerFactoryBean dsEmFactory(@Qualifier("dsDataSource")DataSource dsDataSource,EntityManagerFactoryBuilder builder){
LocalContainerEntityManagerFactoryBean em =  builder.dataSource(dsDataSource).packages("PACKAGE OF YOUR MODELS").build();
HibernateJpaVendorAdapter ven = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(ven);
HashMap<String, Object> prop = new HashMap<>();
prop.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
prop.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));


em.setJpaPropertyMap(prop);
em.afterPropertiesSet();
return em;
}




@Bean(name="dsTransactionManager")
public PlatformTransactionManager dsTransactionManager(@Qualifier("dsEmFactory")EntityManagerFactory factory){
return new JpaTransactionManager(factory);
}
}

应用性能

#---mysql DATASOURCE---
spring.mysql.driverClassName = com.mysql.jdbc.Driver
spring.mysql.url = jdbc:mysql://127.0.0.1:3306/test
spring.mysql.username = root
spring.mysql.password = root
#----------------------


#---H2 DATASOURCE----
spring.h2.driverClassName = org.h2.Driver
spring.h2.url = jdbc:h2:file:~/test
spring.h2.username = root
spring.h2.password = root
#---------------------------


#------JPA-----
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

应用程序

@SpringBootApplication
public class Application {




public static void main(String[] args)   {
ApplicationContext ac=SpringApplication.run(KeopsSageInvoiceApplication.class, args);
UserMysqlDao userRepository = ac.getBean(UserMysqlDao.class)
//for exemple save a new user using your repository
userRepository.save(new UserMysql());


}
}