NHibernate中ICompositeUserType和IUserType的区别
2023-04-18 15:15:33 时间
使用NHibernate实现ICompositeUserType后,可以在HQL中对组合对象的属性进行查询,例如下面
类图:
表结构:
xml配置:
使用NHibernate对BoxParamDao存取时,为BoxAttributeInfo类型实现一个ICompositeUserType接口(ThoughtSoft.CMS.Box.BoxParamCompositeType)就可以。在HQL中可以这样查询:
这里纠正一下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等其它一些特性又不支持,因此这是一个多余的设计,反而导致使用者对这个接口产生误解。
类图:
表结构:
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>
<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%");
.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等其它一些特性又不支持,因此这是一个多余的设计,反而导致使用者对这个接口产生误解。
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击