WebObjects/EOF/建模/布林值
在 WO 中有很多方法可以對布林值進行建模。
我喜歡這種方法,因為它不需要任何特定的程式碼,並且在資料庫中非常易讀。
注意,這僅在 WO 5.2 中有效,在 WO 5.0 到 WO 5.1.4 中已失效。
以下是我的做法:我將該列定義為長度為 5 的字元可變型別,以便我可以儲存“true”或“false”。在 EOModeler 中,我將內部資料型別定義為自定義型別,類定義為 java.lang.Boolean,工廠方法定義為 valueOf,轉換方法定義為 toString,初始化引數定義為 NSString。即使這會在資料庫中浪費一些空間,但這仍然很有效。
為了方便使用,您應該將其定義為原型。
注意 - 這在“Practical WebObjects”一書中也進行了討論;在第 42 頁。
另一種實現方法是在 EOModeler 中將您的屬性定義為 Number,並將其值型別設定為“c”。這將導致 JDBC 介面卡在 ResultSet 上使用 getBoolean() / setBoolean() 方法,因此您可以使用您想要的任何資料型別,只要 JDBC 驅動程式支援即可。
如果您想編寫自定義訪問器方法,可以使用 Boolean 型別,EO 將自動進行型別轉換 - 因此這將起作用。
public Boolean getAttribute() { return storedValueForKey("attribute"); }
public void setAttribute(Boolean input) { takeStoredValueForKey(input, "attribute"); }
有趣的是,在 WO 5.2 中,_無論_您在 EOModeler 中如何設定“值型別”,EOF 有時會自動將任何數字資料庫列轉換為布林值。如果您有一個名為“someAttribute”的屬性,並且實體的類定義了一個類似於“public Boolean someAttribute()”的方法,那麼 storedValueForKey("someAttribute") 將自動返回一個布林值(無論您是否喜歡!)。如果簽名是小寫的 boolean,這也是正確的。可能還有其他情況是正確的 - 它完全沒有文件記錄,我只是透過實驗才發現的。
用於將數字資料轉換為布林值的演算法似乎是 - 如果數字為 1,則返回 Boolean(true),否則(包括 null)返回 Boolean(false)。null 在這種情況下永遠不會被 storedValueForKey("someAttribute") 返回,即使資料庫中存在 null。同樣,EOModel 中的“值型別”似乎無關緊要。
我注意到與 Jonathan 觀察到的情況完全相同。但是,這個“功能”引入了一個問題 - 來自資料庫的儲存快照包含值“1”(我想轉換是在這一點之後發生的),無論何時我對資料庫儲存更改,EOF 都認為該屬性已從“1”更改為“true”,並且它將此寫入資料庫,即使這並不一定合適。
問題比這更嚴重。除了 Jesse 指出的問題之外,這個“功能”還會導致 EOF 出現一些嚴重問題,這可能與 Jesse 談論的內容有關。特別是,在某些情況下,EOF 會認為一個屬性_沒有_改變,即使它已經改變了,並且即使它應該寫入資料庫,它也不會寫入任何內容。存在一個“自動轉換屬性”似乎會觸發這個問題,但 EOF 會感到困惑的已更改屬性可能出現在其他屬性甚至關係中!我無法真正解釋這一點;我甚至無法解釋它在什麼情況下發生。但是我遇到過一種情況,其中一對一關係的目標已更改,但 EOF 在 saveChanges() 時沒有寫入更改。但是,刪除“自動布林轉換”屬性,對程式進行其他更改,使問題消失了。[WO 5.2]
我建議_避免_自動布林轉換。它會導致各種各樣的問題。[我向蘋果公司提交了一個請求,要求提供一種關閉這種自動布林轉換的方法,但工程師們拒絕了。我提交了自己的錯誤報告。Jesse,你應該提交一個關於你特別注意到的問題的報告。]
有關此錯誤的更多說明,請參見:Weird52EOFBug 我知道此錯誤影響 5.2.1;我相信它在 5.2.2 中還沒有得到修復。(寫於 2004 年 3 月 13 日)
在 5.2.3 的版本說明中注意到了這一點 http://docs.info.apple.com/article.html?artnum=107873 --- 當目標實體具有布林屬性時,一對一關係不會正確更新。
蘋果參考 3108071
問題:儲存更改時,具有布林屬性的目標實體不會正確提交到資料庫,因為快照處於無效狀態。
解決方案:為了解決這個問題,使用 Number 值類和“c”值型別定義的布林屬性的行為現在將返回一個布林值,而不是一個整數值。
我的“零努力”方法如下:在 EOModeler 中,我有一個名為“enabled”的屬性。
Name = 'enabled' Value Class (Java) = 'Boolean' External Type = 'BOOL' (in MySQL it maps to tinyint(1)) Value Type 'c'
EOModeler 會抱怨它需要為此屬性指定“valueFactoryMethodName”和“adaptorValueConversionMethodName”,但似乎您可以忽略它。
當我生成 Java 程式碼時,我會得到。
public Boolean enabled(){ return (Boolean)storedValueForKey("enabled"); }
public void setEnabled(Boolean v){ takeStoredValueForKey(v, "enabled"); }
我的初始測試看起來很有希望,但你們可以嘗試使用 5.2.3+ 和可重現的案例來確保嗎?