我是相当新的春季启动,我想为我的项目创建一个多数据源。 这是我目前的情况。我有两个包的实体多个数据库。让我们说
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
我到处搜索,还没找到解决办法。知道为什么会出现这种异常吗?这是实现多个数据源来实现我上面的案例的最佳方式吗?如果需要,我愿意进行全面重构。
谢谢