【问题标题】:Is this relationship possible in CF9's ORM? How?这种关系在CF9的ORM中是可能的吗?如何?
【发布时间】:2012-02-23 15:10:16
【问题描述】:

一、表结构的相关位:

contact
    -contactID
    -email

data
    -value
    -contactID
    -definitionID

definition
    -definitionID
    -name

contact 表中的每条记录代表一个联系人及其电子邮件地址。

definition 表中的每条记录代表自定义数据字段的定义。例如,definition 中可能有五条记录 - 组织、邮政编码、评论、地址、电话。除了字段的名称,它还定义了有关字段的相关元数据。

data 表中的每条记录都包含与联系人相关的自定义数据字段的值。它的定义取自definition 表。

为了进一步说明,如果我想生成一个联系人表格以及他们的自定义字段数据,它可能如下所示:

| E-Mail            | Organization | Zip Code | Comments                         | Address       | Phone    |
-------------------------------------------------------------------------------------------------------------
| sean@example.com  | ACME         | 12345    | Cool guy!                        | 123 Test St   | 555-5555 |
| sean2@example.com | SomeCo.      | 54321    | Doesn't know anything about ORM! | 321 Test Blvd | 444-4444 |

这个系统的好处是它可以根据我的需要向外扩展,并且易于定制。缺点是我不知道如何定义关系:)

我尝试将contact:data 定义为1:M 并将definition:data 定义为1:M,但结果似乎有点奇怪:使用两个联系人和一个定义,为每个联系人添加一行数据,然后调用entityLoad( 'Contact' ) 会产生有趣的关系。它看起来像这样(只是要使用一些伪结构符号,因为它很容易输入并且我希望阅读):

{
    contact: {
        email: 'sean@example.com',
        data: {
            value: 'ACME',
            definition: {
                name: 'Organization',
                data: {
                    value: 'SomeCo.',
                    contact: {
                        email: 'sean2@example.com'
                }
            }
        }
    }
}

看起来它正在基于data 表与两个表的关系在contactdefinition 之间创建间接关系。正如您可以想象的那样,增加联系人和自定义字段的数量只会使问题成倍地恶化。

这种类型的关系是否可以使用 CF9 的 ORM?我怎样才能完成它?

提前致谢!

编辑:忘记指定 - 如果重要的话,我正在使用 MySQL。

编辑 2:CFC 定义如下:

Contact.cfc

/**
 * @persistent true
 */
component name='Contact' {

    /**
     * @type numeric
     * @sqltype int(11)
     * @generator increment
     * @fieldtype id
     */
    property contactID;

    /**
     * @type string
     * @sqltype varchar(50)
     */
    property email;

    /**
     * @type array
     * @fieldtype one-to-many
     * @cfc Data
     * @fkcolumn dataID
     */
    property data;
}

定义.cfc

/**
 * @persistent true
 */
component name='Definition' {

    /**
     * @type numeric
     * @sqltype int(11)
     * @generator increment
     * @fieldtype id
     */
    property definitionID;

    /**
     * @type string
     * @sqltype varchar(50)
     */
    property name;

    /**
     * @type array
     * @fieldtype one-to-many
     * @cfc Data
     * @fkcolumn dataID
     */
    property data;

}

Data.cfc

    /**
 * @persistent true
 */
component {

    /**
     * @type numeric
     * @sqltype int(11)
     * @generator increment
     * @fieldtype id
     */
    property dataID;

    /**
     * @type string
     * @sqltype varchar(50)
     */
    property value;

    /**
     * @fieldtype many-to-one
     * @fkcolumn contactID
     * @cfc Contact
     * @inverse true
     */
    property contact;

    /**
     * @fieldtype many-to-one
     * @fkcolumn definitionID
     * @cfc Definition
     * @inverse true
     */
    property definition;

}

【问题讨论】:

  • 我相信您希望在联系人和定义之间实现多对多关系,并将数据作为您的“LinkTable”:help.adobe.com/en_US/ColdFusion/9.0/Developing/…
  • 再想一想,如果您将“数据”中的“值”字段用作多对多中的链接表,我不确定您将如何访问它。或许正确的做法是先定义联系人和数据之间的一对多关系,然后再定义数据和定义之间的多对一关系。
  • @Danimal37 感谢您的 cmets!如我的问题所述,我将definition:datacontact:data 都定义为一对多,并收到了上面的结果:)
  • 自从我使用 CF 的 ORM 以来已经有一段时间了,但似乎你可以颠倒你的关系,以便将 definition:data 而不是 1:M,你可以将其反转为 data:definitionM:1。换句话说,使用data 内部而不是definition 内部的关系来定义您的属性。当然,我在这里做出假设,因为我实际上还没有看到您的 ORM CFC 定义。
  • @Danimal37 没错,您可以使用@inverse trueinverse='true' 反转关系。我确实尝试过这样做,但没有更好的结果。对于缺少 CFC 定义,我深表歉意 - 我面前没有代码,但我会在今晚下班回家时更新问题。

标签: hibernate orm coldfusion coldfusion-9


【解决方案1】:

我相信您希望 Data.cfc 处理关系,具有

Data --m2o--> Contact
Data --m2o--> Definition

为了方便

Contact --o2m--> Data (inverse=true)

CFC

// Contact.cfc
component persistent="true" {
  property name="contactID" fieldtype="id" generator="native";
  property name="email";
  property name="data" cfc="Data" fieldtype="one-to-many" inverse="true" lazy="true";
}

// Definition.cfc
component persistent="true" {
  property name="definitionID" fieldtype="id" generator="native";
  property name="name";
}

// Data.cfc
component persistent='true'{
  property name="dataID" fieldtype="id" generator="native";
  property name="value";
  property name="contact" cfc="Contact" fieldtype="many-to-one" fkcolumn="contactID";
  property name="definition" cfc="Definition" fieldtype="many-to-one" fkcolumn="definitionID";
}

index.cfm

<cfscript>
ormReload();
transaction {
    con = new Contact();
    con.setEmail("chris@domain.com");
    entitySave(con);

    def1 = new Definition();
    def1.setName("twitter");
    entitySave(def1);

    def2 = new Definition();
    def2.setName("interests");
    entitySave(def2);

    data1 = new Data();
    data1.setValue("d1rtym0nk3y");
    data1.setDefinition(def1);
    data1.setContact(con);
    entitySave(data1);

    data2 = new Data();
    data2.setValue("ColdFusion");
    data2.setDefinition(def2);
    data2.setContact(con);
    entitySave(data2);

    // this is important, you must set both sides of the relationship or "bad things" happen
    // i'd recommend overriding contact.addData()/data.setContact to ensure both sides get set
    con.addData(data1);
    con.addData(data2);
}
writeDump(con);
</cfscript>

要以合理的方式检索联系人的数据属性,您可以这样做

myData = ormExecuteQuery("
    select new map(
        data.value as value,
        def.name as name
    )
    from Data data
    join data.definition def
    where data.contact.contactID = :id

", {id=con.getContactID()});

writeDump(myData);

【讨论】:

  • 搞定了,谢谢! :) 我的印象是必须从双方来定义关系,这可能是我在这种情况下的失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多