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+ 和可重现的案例来确保吗?