我想知道这个简单问题的答案。创建实体规则
当我创建一个实体对象,我想限制一个属性的设置(例如我不想让任何人设置一个整数值小于1的属性),我应该在这个属性的setter还是应该在处理这些对象的类中检查后者的限制?一般来说,我可以实现getter和setter,但是只要我的getter返回并设置set属性,我就可以实现吗?
我知道在java中有一些规则(代码约定),所以我不想破坏它们中的任何一个。
在此先感谢,希望我的问题对我可能犯的任何语法错误都足够清楚和抱歉:/。
我想知道这个简单问题的答案。创建实体规则
当我创建一个实体对象,我想限制一个属性的设置(例如我不想让任何人设置一个整数值小于1的属性),我应该在这个属性的setter还是应该在处理这些对象的类中检查后者的限制?一般来说,我可以实现getter和setter,但是只要我的getter返回并设置set属性,我就可以实现吗?
我知道在java中有一些规则(代码约定),所以我不想破坏它们中的任何一个。
在此先感谢,希望我的问题对我可能犯的任何语法错误都足够清楚和抱歉:/。
是的getters/setters对此很有用。
例如:
public void setAge(int age){
if(age < 0){
throw new IllegalArgumentException("Invalid age : " + age);
//or if you don't want to throw an exception you can handle it otherways too
}
}
您也可以使用Java-EE的Bean Validators此
public class Person{
@Min(value = 0)
@Max(value = 99)
private Integer age;
//some other code
}
这是获得者和制定者的目标。
如果我们不能在这些方法中添加一些行为,那么......为什么我们不使用公共属性?
我从你的问题的理解,它几乎涉及到封装OO原则。 你可以看看这篇文章:http://www.tutorialspoint.com/java/java_encapsulation.htm
我的首选方法是使用JSR 303(Bean验证API),以确保该类的属性是有效的。
在setter中执行验证是完全可以的,但这并不总是一种理想的方法。有可能会混淆不相关的多个上下文的需求。例如,您的某些属性决不能从用户界面设置,而应该在被保留之前由服务计算。在这种情况下,将这个逻辑放在setter中是不可取的,因为你需要知道setter被调用的上下文;您需要在UI层和持久层中应用不同的规则。 JSR 303允许您使用验证组来区分这些问题,以便您的UI验证组与您的持久性验证组不同。
在JPA 2.0中,当您使用的是由JSR 303的验证评估约束注释类,持久化提供商可以自动评估对PrePersist
,PreUpdate
和PreRemove
这些限制(通常没有这样做;见下文)的生命周期事件实体。要在您的JPA提供程序中执行实体验证,您必须在persistence.xml
文件中指定validation-mode
元素或javax.persistence.validation.mode
属性;值必须是AUTO
(默认值)或CALLBACK
(而不是NONE
)。
Bean验证提供程序的存在足以确保在JPA实体生命周期事件上进行验证,因为默认值为AUTO
。在Java EE 6应用程序服务器中,您可以默认获得此信息; Glassfish使用Hibernate Validator的JSR 303的RI实现,而且EclipseLink也可以很好地工作。
CALLBACK
模式将允许您覆盖触发生命周期事件时要应用的验证组。默认情况下,默认的Bean验证组(Default
)将针对更新和持久事件进行验证;删除事件不涉及任何验证。 CALLBACK
模式允许您使用属性javax.persistence.validation.group.pre-persist
,javax.persistence.validation.group.pre-update
和javax.persistence.validation.group.pre-remove
为这些事件指定不同的验证组。
请记住,虽然我上面发布的Bean Validation API文档链接来自Java EE 6 API文档,但可以在Java EE容器之外使用JSR 303验证。
顺便说一下,JSR 303的参考实现是Hibernate Validator框架。请参阅:http://www.hibernate.org/subprojects/validator.html – MicSim
吸气剂和吸附剂非常适合添加限制,就像Jigar Joshi在他的回答中所做的一样。这样,您可以立即获得反馈,并在引入问题时处理问题。
另一个解决方案是使用对象验证(类似于JSR-303实现),它允许您使用最小值和最大值对字段进行注释。像
@Min(value=1)
private int myvalue;
东西然后你就可以一气呵成验证整个对象并获取所有信息,如果您有其他的限制领域。这在任何地方显然都没有用,但如果它符合你的需要,它是一种选择。
最后,当你说“实体”时,我想到了存储在数据库中或与ORM工具相关的东西。如果是这样的话,你会想要小心你在吸气剂中的作用。例如,如果您在getter中执行延迟初始化,则某些ORM供应商会将实体标记为脏,并尝试将其刷新到数据库,可能会导致意外写入。
谢谢!您的帮助非常感谢,并且很高兴知道其他方法:) – VaclavDedik
欢迎您:) –