英文:
Is it possible to use MongoDb and PostgreSql for same model in Spring boot?
问题
我已经构建了一个用户管理服务,其中我正在使用MongoDb(使用Spring Data)。我有两个模型:User(用户)和Role(角色)。
User模型:
package com.userservice.usermanagement.models;
import java.util.HashSet;
import java.util.Set;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "user_data")
public class User {
@Id
private String id;
private String username;
private String email;
private String password;
private String customername;
private String customerid;
private String description;
public String getCustomerid() {
return customerid;
}
public void setCustomerid(String customerid) {
this.customerid = customerid;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCustomername() {
return customername;
}
public void setCustomername(String customername) {
this.customername = customername;
}
@DBRef
private Set<Role> roles = new HashSet<>();
public User() {
}
public User(String username, String email, String customername, String customerid, String description, String password) {
this.username = username;
this.email = email;
this.customername = customername;
this.customerid = customerid;
this.description = description;
this.password = password;
}
// Getters and setters...
}
Role模型:
package com.userservice.usermanagement.models;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "roles")
public class Role {
@Id
private String id;
private URole name;
public Role() {
}
public Role(URole name) {
this.name = name;
}
// Getters and setters...
}
Role枚举类:
package com.userservice.usermanagement.models;
public enum URole {
ROLE_USER,
ROLE_ADMIN
}
在User模型中,我使用了@DBRef
注解来引用角色集合。我的问题是,我希望在同一应用程序中为这些模型同时提供使用PostgreSql和MongoDb的选项。我已经针对MongoDb实现了这一点,但我不确定如何在同一应用程序中为PostgreSql实现这一点作为选项。我认为一种方法是为User和Role定义接口,然后构建两个不同的类分别用于User_mongo模型和User_postgre实体(角色也是同样的方式)。我陷入了困境,并且我尝试过进行一些研究,但大多数情况下我找到的教程都是针对同一类型的不同数据库(都是PostgreSql数据库)。对于我来说,任何方向都将不胜感激。附注:我刚接触Spring Boot和Java。
我现在的AddUser控制器,目前使用了Mongorepository:
@PostMapping("/adduser")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
// Controller创建新用户基于所有用户实体
// ...(控制器的其余代码)...
}
注意:上述内容是对您提供的代码的翻译,不包含问题的回答。如有任何进一步的翻译需求,请随时告知。
英文:
I have built a User management service in which I'm using MongoDb (spring data). I have two models User and Role.
package com.userservice.usermanagement.models;
import java.util.HashSet;
import java.util.Set;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "user_data")
public class User {
/**
* User model
*/
@Id
private String id;
private String username;
private String email;
private String password;
private String customername;
private String customerid;
private String description;
public String getCustomerid() {
return customerid;
}
public void setCustomerid(String customerid) {
this.customerid = customerid;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCustomername() {
return customername;
}
public void setCustomername(String customername) {
this.customername = customername;
}
@DBRef
private Set<Role> roles = new HashSet<>();
public User() {
}
public User(String username, String email, String customername,String customerid,String description, String password) {
this.username = username;
this.email = email;
this.customername = customername;
this.customerid = customerid;
this.description = description;
this.password = password;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Role model -
package com.userservice.usermanagement.models;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "roles")
public class Role {
/**
* Model for role with all the attributes
*/
@Id
private String id;
private URole name;
public Role() {
}
public Role(URole name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public URole getName() {
return name;
}
public void setName(URole name) {
this.name = name;
}
}
and Role enumerator-
package com.userservice.usermanagement.models;
public enum URole {
ROLE_USER,
ROLE_ADMIN
}
In User there is a role attribute which I have @Dbref to role collection. My problem is that I want to have a option of using PostgreSql and MongoDb in the same application for these Models. I have implemented this for MongoDb but I'm not sure how to go about doing this for postgreSql in the same application as an option. One way I think is to have a interface User and role and build two different classes for User_mongo model and User_postgre entity(same way for role). I'm stuck here, and I tried to do certain research but most of the time I find tutorials that have separate databases of same type(Both PostgreSql databases). Any direction is highly appreciated. PS I'm new to spring boot and Java.
My AddUser Controller that Uses Mongorepository as of now
@PostMapping("/adduser")
// @PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
/*
* This controller Creates new user based on all the entities for the user
*
*/
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Username is already taken!"));
}
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse("Error: Email is already in use!"));
}
// Create new user's account
User user = new User(signUpRequest.getUsername(),
signUpRequest.getEmail(),
signUpRequest.getCustomername(),
signUpRequest.getCustomerid(),
signUpRequest.getDescription(),
encoder.encode(signUpRequest.getPassword()));
Set<String> strRoles = signUpRequest.getRoles();
Set<Role> roles = new HashSet<>();
if (strRoles == null) {
Role userRole = roleRepository.findByName(URole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(userRole);
} else {
strRoles.forEach(role -> {
switch (role) {
case "admin":
Role adminRole = roleRepository.findByName(URole.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(adminRole);
break;
default:
Role userRole = roleRepository.findByName(URole.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
roles.add(userRole);
}
});
}
user.setRoles(roles);
userRepository.save(user);
return ResponseEntity.ok(new MessageResponse("User Added successfully!"));
}
```
</details>
# 答案1
**得分**: 4
我会在这里对两个配置(一个用于Mongo,一个用于PostgreSQL)使用 @ConditionalOnProperty 注解,并在运行时添加 enabled 配置属性(对于要加载它的配置)。
以下是一个简化的示例:
```java
public static void main(String[] args) {
SpringApplication application = new SpringApplication(DemoApplication.class);
Properties properties = new Properties();
properties.put("databaseFoo.enabled", "true");
application.setDefaultProperties(properties);
application.run(args);
}
然后,在需要在运行时是 databaseFoo 的配置中,你可以将 bean 注解如下:
@ConditionalOnProperty(
value="databaseFoo.enabled",
havingValue = "true")
public class DatabaseFooConfig {
另一个 bean 可以具有以下条件属性:
@ConditionalOnProperty(
value="databaseBar.enabled",
havingValue = "false",
matchIfMissing = true)
public class DataBaseBarConfig {
英文:
I would use the @ConditonalOnProperty annotation here on two configs(one for Mongo and one for PostgerSql), and add the enabled config-property at runtime(For the config you want it's beens to load)
Here is a simplified example.
public static void main(String[] args) {
SpringApplication application = new SpringApplication(DemoApplication.class);
Properties properties = new Properties();
properties.put("databaseFoo.enabled", "true");
application.setDefaultProperties(properties);
application.run(args);
}
then on the config needed when run time is databaseFoo you can annotate the bean as such
@ConditionalOnProperty(
value="databaseFoo.enabled",
havingValue = "true")
public class DatabaseFooConfig {
Then the other bean could have the following conditional properties
@ConditionalOnProperty(
value="databaseBar.nabled",
havingValue = "false",
matchIfMissing= true)
public class DataBaseBarConfig {
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论