我想知道這個簡單問題的答案。創建實體規則
當我創建一個實體對象,我想限制一個屬性的設置(例如我不想讓任何人設置一個整數值小於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
歡迎您:) –