我对Spring启动很新,我想为我的项目创建一个多数据源 . 这是我目前的情况 . 我为多个数据库提供了两个实体包 . 比方说吧
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 .
(com.test.model是我将放置我的Repositories类的包 . 它将在下面定义)
MySqlDbConfig.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
然后为了crud我有UserMySqlDao和UserH2Dao
UserMySqlDao.java
@Transactional
@Repository
public interface UserMysqlDao extends CrudRepository<UserMysql, Integer>{
public UserMysql findByName(String name);
}
UserH2Dao.java
@Transactional
@Repositories
public interface UserH2Dao extends CrudRepository<Userh2, Integer>{
public Userh2 findByName(String name);
}
最后,我有一个UserController作为 endpoints 来访问我的服务
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();
}
}
}
Application.java
@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
我谷歌搜索,还没有解决方案 . 有什么想法发生这种异常?这是实现多个数据源以实现上述情况的最佳方法吗?如果需要,我愿意接受全部重构 .
谢谢
9 回答
我用这种方式解决了问题(如何使用spring和Hibernate连接多个数据库),我希望它会有所帮助:)
注意:我已经添加了相关的代码,请在我在下面提到的代码中使用的impl的帮助下制作dao .
web.xml
persistence.xml
dispatcher-servlet
java class to persist into one database
java class to persist in another database
customer.jsp
company.jsp
index.jsp
success.jsp
CompanyController
CustomerController
CompanyDetails Entity
CustomerDetails Entity
使用多个数据源或实现读写分离 . 你必须具备支持动态数据源选择的类
AbstractRoutingDataSource
的知识 .这是我的
datasource.yaml
,我想弄清楚如何解决这个案子 . 你可以参考这个项目spring-boot + quartz . 希望这会帮助你 .我想你会发现它很有用
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个配置类,分离模型/存储库包等以使配置变得容易 .
此外,在上面的示例中,它手动创建数据源 . 您可以使用带有@ConfigurationProperties批注的spring doc方法来避免这种情况 . 这是一个例子:
http://xantorohara.blogspot.com.tr/2013/11/spring-boot-jdbc-with-multiple.html
希望这些有帮助 .
谢谢大家的帮助,但看起来并不复杂; almost everything is handled internally by SpringBoot.
在我的情况下,我想使用Mysql和Mongodb,解决方案是在我的应用程序类上使用
EnableMongoRepositories
和EnableJpaRepositories
注释 .NB: 所有mysql实体都必须扩展
JpaRepository
,而mongo enities必须扩展MongoRepository
.数据源配置是直接的,如 Spring 季文档所示:
使用两个数据源需要自己的事务管理器 .
然后在@Transaction中相应地使用它
MySqlBDConfig.java
H2DBConfig.java
application.properties
Application.java
几天前我遇到同样的问题,我按照下面提到的链接,我能够克服这个问题
http://www.baeldung.com/spring-data-jpa-multiple-databases
一旦你开始使用jpa和一些驱动程序在你的类路径 spring 启动马上把它作为你的数据源(例如h2)用于使用defult数据源,因此你只需要定义
如果我们更进一步,你想使用两个我会建议使用两个数据源,如下所述:Spring Boot Configure and Use Two DataSources
Update 2018-01-07 with Spring Boot 1.5.8.RELEASE
如果您想知道如何配置它,如何使用它,以及如何控制事务 . 我可能有你的答案 .
您可以在https://www.surasint.com/spring-boot-with-multiple-databases-example/中看到可运行的示例和一些说明
我在这里复制了一些代码 .
首先,您必须像这样设置application.properties
然后将它们定义为提供者(@Bean),如下所示:
请注意,我有@Bean(name =“datasource1”)和@Bean(name =“datasource2”),那么当我们需要数据源为@Qualifier(“datasource1”)和@Qualifier(“datasource2”)时,你可以使用它,例如
如果您关心事务,则必须为它们定义DataSourceTransactionManager,如下所示:
然后就可以使用它了
要么
这应该足够了 . 请参阅上面链接中的示例和详细信息 .