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(
0 104 )
    .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等其它一些特性又不支持,因此这是一个多余的设计,反而导致使用者对这个接口产生误解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值