这种关系在CF9的ORM中是否可行?怎么样?

时间:2012-01-31 21:38:58

标签: hibernate orm coldfusion coldfusion-9

首先,表结构的相关位:

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'
                }
            }
        }
    }
}

基于contact表与两个表的关系,看起来它在definitiondata之间创建了间接关系。可以想象,增加联系人和自定义字段的数量只会使问题呈指数级变差。

这种关系是否可以使用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;
}

Definition.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;

}

1 个答案:

答案 0 :(得分: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);