java - 在 Spring MVC 中将 View 模型映射到数据库模型时验证相关数据

标签 java spring-mvc oop mapping dozer

我正在开发一个 java spring mvc 应用程序,有一个关于将 View 模型对象映射到数据库模型对象的重要问题。我们的应用程序使用 dozer mapper为此目的。

假设我有一个Person 模型和BaseInformation 模型。 BaseInformation 模型适用于可在所有其他模型中使用的一般数据,例如性别、颜色、单位...

基础信息:

class BaseInformation{
   private Long id;
   private String category;
   private String title;
}

这可以有一个像这样的数据库表:

Id | Category | Title 
-------------------------
1  | "gender" | "male"
2  | "gender" | "female"
3  | "color"  | "red"
4  | "color"  | "green"
...

这是我的人物模型的一部分:

public class Person{
     ...
     private BaseInformation gender;
     ...
}

这是我的 RegisterPersonViewModel

的一部分
public class RegisterPersonViewModel{
    ...
    private Integer gender_id;
    ...
}

register person View 中,我有一个<select>BaseInfromation 中用 gender 类别填充。当用户提交该表单时,ajax 请求会像这样发送到 Controller 的方法:

@RequestMapping("/person/save", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody Person create(@Valid @RequestBody RegisterPersonViewModel viewModel) throws Exception {

    //Mapping viewModel to Model via dozer mapper
    //and passing generated model to service layer
}

现在,这是我的问题:

用户可以更改 value在 View 中手动设置性别组合框(例如设置颜色值而不是性别)并将无效的相关数据发送到 Controller 的方法。 Dozer mapper 将 viewModel 映射到模型,此无效数据通过数据访问层 并保存在数据库中。换句话说,无效数据可以在没有任何控制的情况下保存到数据库中。我想知道用最少的代码控制关系数据的最佳方法。

最佳答案

BaseInformation 类太笼统了:性别与颜色无关。你需要打破它。这是一个“一个真正的查找表”的案例,甚至在 Wikipedia 上提到过:

In the database world, developers are sometimes tempted to bypass the RDBMS, for example by storing everything in one big table with three columns labelled entity ID, key, and value.

...这对应于您的id、类别和标题。

While this entity-attribute-value model allows the developer to break out from the structure imposed by an SQL database, it loses out on all the benefits, [1] since all of the work that could be done efficiently by the RDBMS is forced onto the application instead. Queries become much more convoluted, [2] the indexes and query optimizer can no longer work effectively, and data validity constraints are not enforced.

粗体部分很好地描述了您遇到的问题。


您应该将不同的类别移动到它们自己的类和表中。对于性别,枚举就足够了:

public enum Gender {
    Female, Male, Unknown, Unspecified
}

然后像这样在 Person 类中使用它:

public class Person {
    ...
    private Gender gender;
    ...
}

如果您使用 Spring 数据绑定(bind)将输入数据转换为 Java 对象,则只能使用 Gender 枚举中指定的值,无需进一步检查。

对于颜色,如果不需要在运行时或类中更改颜色,您可以类似地使用枚举。

关于java - 在 Spring MVC 中将 View 模型映射到数据库模型时验证相关数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42553161/

相关文章:

c++ - 我应该怎么做才能让 WS_MAXIMIZE 工作?

c# - 如何获取基类型字段的值

java - 我们可以在不使用 Java 中的 return 的情况下为传入参数的对象赋值吗?

Spring:无法将模拟注入(inject)到使用 @Aspect 注释的类中

java - 如何利用 hibernate c3p0连接池?

spring-mvc - Spring-Integration-Splunk依赖问题

java - Spring @RequestMapping,404错误

java - 如何将随机生成的数字实现为setter或getter中的变量?

Java String 使用没有转义字符的引号

java - 用于程序更新的反射编程