使用 CF-ORM 的 ColdFusion 9 需要注意的事项
-
21-09-2019 - |
题
您在带有 CF-ORM (Hibernate) 的 ColdFusion 9 中观察到了哪些应该注意的事情?
解决方案
实体
init()
方法不得有必需的参数,否则EntityNew()
和其他 CF-ORM 操作将会中断。您可能想要使用工厂来创建实体,并在那里强制执行所需的参数。ORMReload()
和ormsettings.dbcreate = "drop create"
可能不会为您删除所有表格。 CF9 累积修补程序 1 稍微改进了这一点,但您可能想自己删除数据库中的表。type="date"
(默认使用ormtype="date"
),将只存储日期而不存储时间。如果您也想保留时间,请使用ormtype="timestamp"
type="string"
将默认为varchar(255)
type="numeric"
将默认为float
, , 不是int
. 。如果需要,请使用 ormtype="int"。如果
fieldtype="id"
并且生成器设置为某个生成器,ormtype 将默认为int
.type="string" length="10"
将使用varchar(10)
, , 不是char(10)
ormtype="char" length="10"
将使用char(1)
仍然。使用sqltype="char(10)"
如果你真的需要的话。type="boolean"
使用tinyint
默认情况下,使用sqltype="bit"
如果你需要。应该使用
inverse=true
在双向关系中,通常在“一对多”方面。做 不是 使用
inverse="true"
在单向关系中!这段感情可能根本就维持不下去了!如果使用 MS-SQL,则不能将超过 1 个实体的一对一属性设置为 Null,因为 Null 被视为索引中的唯一值。使列不为空的好主意。(或使用链接表)
EntityLoad("entity", 1, true)
有效,但是EntityLoadByPK("entity", 1)
更干净!EntityLoad()
,EntityLoadByPK()
, , 和ORMExecuteQuery
和unique=true
, , 将返回null
如果没有找到实体。使用isNull()
在使用返回值之前进行检查。ORMExecuteQuery
如果默认没有找到实体,将返回空数组。不要忘记使用
singularname
“一对多”/“多对多”中的属性以获得更好看的生成函数(例如addDog(Dog dog)
与addDogs(Dog dogs)
.)<cfdump>
将加载所有延迟加载属性。或者你可以尝试<cfdump var="#entityToQuery([entity])#">
或设置 top=1 以有效转储。存储在 Session 范围中的实体将与其 Hibernate 会话范围断开连接,并且不会加载延迟加载属性。要恢复休眠会话范围,请使用
entityLoadByExample()
或者entitySave(entity)
.cascade="all-delete-orphan"
通常对于“一对多”或“多对多”关系更有意义。Hibernate 设置 null 然后删除,因此请确保该列可以为 null。测试一下这是否是您想要的行为。放
required="true"
每当notnull="true"
, ,对于使用 CFCExplorer 浏览 CFC 的其他人来说更具可读性EntityNew('Y')
比效率稍高new com.X.Y
根据某些 Adobe 工程师的说法,该实体是否要在稍后保留。由于未修复的 Hibernate bug,与继承实体的关系有时可能会中断,请使用
linktable
作为解决方法。structKeyColumn
不能是目标实体的PK。双向多对多不能使用struct
当向结构添加新实体时,
structKeyColumn
当 CF 保留父实体时将被忽略。如果直接访问一对多/多对多数组或结构体,请在使用前确保相应的数组/结构体存在。生成的 addX()/hasX()/removeX() 可以随时安全使用。
在
postInsert()
, ,实体休眠会话不再可用,因此在 postInsert() 中设置属性将被静默忽略,或者将抛出 Session is Closed 异常。实体加载后
entityLoad()
或来自数据库的 HQL,更改将自动保留,即使EntitySave()
不被调用。CF-ORM 事务的实现方式是启动一个新会话并在完成后关闭。
事件内部(即preLoad() / postInsert()),分配给变量可能会抛出有关类型的 Java 异常。使用 JavaCast() 来解决该错误。
更新
- CF9.0.1+:使用
<cfquery dbtype="hql">
, 更容易做到cfqueryparam
, ,调试输出实际上显示了绑定值。
其他提示
添加建议:
- 关闭 ormsettings.flushAtRequestEnd = false 以便在请求结束时不进行自动刷新。相反,在所有写入事务(entitySave() 或编辑持久实体时)周围使用事务(从 CF9.01 开始,cftransaction 会刷新会话以完成事务)。
- 通过在HQL中使用贝的参数来防止SQL注入 - 未命名的“?”或命名为':'符号,以确保ORM与所讨论的字段绑定的类型(如Cfqueryparam一样)。防止SQL注入!
- CF9.0.1 允许 CFQUERY dbtype="hql" 内联写入和输出 HQL。使用 CFQUERYPARAM 内联绑定参数(相当于未命名?HQL 中的表示法)。
- 在 HQL 中使用 LEFT OUTER JOIN FETCH 来急切获取关系。
- 使用双向关系覆盖 CFC 上的添加/删除功能,以确保在任一方设置时均已设置。
- 设置 ormsettings.logsql=true 可在控制台中查看派生 SQL。调整 log4j Hibernate 设置以进一步调整 Hibernate 的日志设置。
- 加入 Google 群组 cf-orm-dev。那里有聪明人。
在与休眠摆弄记录也可以打开“保持联系”关闭你的数据源一起使用。
使用SQL Server 2005中,你可以再发动探查和观看查询来通。
由于保持连接是关闭休眠将被迫每次创造新准备的语句。
阅读制备语句可以是艰难的,但至少可以看到正在产生的原始查询。
如果您保持连接,这些准备好的语句创建一次,你只是看到类似
sp_execute 15, 'someparam'
在此是运行sp_prepexec物跑这是其中15来自。
EntityReload似乎忽视延迟加载像CFDUMP。
我使用它的一个EntitySave后抢在db任何拖欠列。我看到在SQL事件探查器(用于SQL Server中的跟踪工具)来很多通查询。
如果将其更改为EntityLoadByPK等则将装载的对象,也不会看到所有多余的关系查询这对我来说可能导致重大问题。