在Spring MVC中将视图模型映射到数据库模型时验证相关数据

ham*_*med 11 java oop mapping spring-mvc dozer

我正在研究java spring mvc应用程序,并且有一个关于将视图模型对象映射到数据库模型对象的重要问题.我们的应用程序使用dozer映射器来实现此目的.

假设我有一个Person模型和BaseInformation模型.该BaseInformation模式是可以在所有其他机型上使用,例如一般数据性别,颜色,单位,....

BaseInformation:

class BaseInformation{
   private Long id;
   private String category;
   private String title;
}
Run Code Online (Sandbox Code Playgroud)

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

Id | Category | Title 
-------------------------
1  | "gender" | "male"
2  | "gender" | "female"
3  | "color"  | "red"
4  | "color"  | "green"
...
Run Code Online (Sandbox Code Playgroud)

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

public class Person{
     ...
     private BaseInformation gender;
     ...
}
Run Code Online (Sandbox Code Playgroud)

这是我的RegisterPersonViewModel的一部分

public class RegisterPersonViewModel{
    ...
    private Integer gender_id;
    ...
}
Run Code Online (Sandbox Code Playgroud)

注册个人观点,我有一个<select>从充满BaseInfromation性别类别.当用户提交该表单时,ajax请求会发送到控制器的方法,如下所示:

@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
}
Run Code Online (Sandbox Code Playgroud)

现在,这是我的问题:

用户可以value手动更改视图中的性别组合框(例如,设置颜色而不是性别),并将无效的相关数据发送到控制器的方法.Dozer映射器将viewModel映射到模型,这个无效数据通过数据访问层并持久存储在数据库中.换句话说,无效数据无需任何控制即可保存到数据库中.我想知道用最少的代码控制关系数据的最佳方法.

Bew*_*ein 6

BaseInformation类过于通用:性别与颜色无关.你需要分手.这是一个"One True Lookup Table"的案例,甚至在维基百科上也提到过:

在数据库领域,开发人员有时会试图绕过RDBMS,例如将所有内容存储在一个包含三个标记为实体ID,键和值的列的大表中.

...对应于您的ID,类别和标题.

虽然这个实体 - 属性 - 值模型允许开发人员从SQL数据库强加的结构中脱离出来,但它会失去所有的好处,[1]因为RDBMS可以有效完成的所有工作都被强加于而应用程序.查询变得更加复杂,[2]索引和查询优化器无法再有效地工作,并且不会强制执行数据有效性约束.

粗体部分描述了你很好的问题.


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

public enum Gender {
    Female, Male, Unknown, Unspecified
}
Run Code Online (Sandbox Code Playgroud)

并在Person类中使用它:

public class Person {
    ...
    private Gender gender;
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

对于颜色,如果在运行时不需要更改颜色,则可以类似地使用枚举,否则使用类.