Richie

Sometimes at night when I look up at the stars, and see the whole sky just laid out there, don't you think I ain't remembering it all. I still got dreams like anybody else, and ever so often, I am thinking about how things might of been. And then, all of a sudden, I'm forty, fifty, sixty years old, you know?

NHibernate中ICompositeUserType和IUserType的区别

使用NHibernate实现ICompositeUserType后,可以在HQL中对组合对象的属性进行查询,例如下面
类图:
   
表结构:

xml配置:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="ThoughtSoft.CMS.Box" assembly="thoughtsoft.cms">
    
<class name="BoxParamDao" table="Cms_Box_Param">
        
<id name="BoxParamId" >
            
<column name="BOX_PARAM_ID" sql-type="nvarchar2" length="36" not-null="true"/>
            
<generator class="assigned" />
        
</id>
        
<property name="BoxId" >
            
<column name="BOX_ID" sql-type="number(8,0)" not-null="true"/>
        
</property>
        
<property name="AttributeInfo" type="ThoughtSoft.CMS.Box.BoxParamCompositeType, thoughtsoft.cms">
            
<column name="BOX_PARAM_TYPE" sql-type="nvarchar2" length="20" not-null="true"/>
            
<column name="BOX_PARAM_NAME" sql-type="nvarchar2" length="20" not-null="true"/>
            
<column name="BOX_PARAM_DESC" sql-type="nvarchar2" length="50" not-null="false"/>
            
<column name="BOX_PARAM_LEN" sql-type="nvarchar2" length="50" not-null="false"/>
        
</property>
        
<property name="Value" >
            
<column name="BOX_PARAM_VALUE" sql-type="nvarchar2" length="2000" not-null="false"/>
        
</property>
    
</class>
</hibernate-mapping>

使用NHibernate对BoxParamDao存取时,为BoxAttributeInfo类型实现一个ICompositeUserType接口(ThoughtSoft.CMS.Box.BoxParamCompositeType)就可以。在HQL中可以这样查询:
IQuery query=session.CreateQuery("from BoxParamDao t where t.BoxId=? and t.AttributeInfo.Name like ?")
    .SetInt32(
0104)
    .SetString(
1"Title%");

这里纠正一下NHibernate考察系列 04 枚举 自定义类型 组件类型3. 自定义类型、自定义映射类型IUserType中的一个错误。那一段示例将一个DateTime类型的属性存储到数据库的两个CHAR类型字段(CREATE_DATE、CREATE_TIME)中,而对这个属性实现了IUserType,因此在NHibernate考察系列 05 Critetia, HQL, Native SQL, Named Query这一篇的2. HQL部分,想在HQL中对这个属性进行查询时,没有办法进行。
上面这种做法是错误的。这种情况下这个DateTime属性完全是一个组合(Composite)对象,应当定义一个组合类(Composite Class),在存储映射时实现ICompositeUserType接口。

这样对ICompositeUserType和IUserType接口的职责就明确了:ICompositeUserType完全用于组合类型的映射;IUserType用于特殊属性的自定义映射。
虽然也可以使用IUserType接口实现单个属性映射到多个数据库字段,但这种情况下对于NHibernate来说,它只是一个简单类型的属性,而不是组合对象,你无法在HQL、Criteria中对这个属性进行条件查询。

其实从ICompositeUserType和IUserType接口本身也可以看出这个差别:ICompositeUserType要求实现public IType[] PropertyTypes()方法,返回组合对象的属性列表;并且要实现public object GetPropertyValue(object component, int property)、public void SetPropertyValue(object component, int property, object value),因为组合对象会具有多个属性。而IUserType只有一个public SqlType[] SqlTypes(),其实这个接口方法应该改为public SqlType SqlType()更合适,因为一个属性映射到多个字段,而又不是组合关系,这种使用方式很尴尬或者太特殊,并且一旦这样使用,HQL等其它一些特性又不支持,因此这是一个多余的设计,反而导致使用者对这个接口产生误解。

posted on 2007-08-03 22:23  riccc  阅读(3490)  评论(1编辑  收藏  举报

导航