现在的位置: 首页 > 综合 > 正文

在hibernate中 以Collection 替换Map结构

2018年02月11日 ⁄ 综合 ⁄ 共 1757字 ⁄ 字号 评论关闭

最近一个老项目,模型结构是这样的

QualifiedEntity


mapping 文件

<class name="QualifiedRole">

.....

<map name="qualifiedEventRole" cascade="all"
table="VERIFIED_ROLES_MAP">
<key column="QUALIFIED_ROLE_ID" not-null="false" />
<map-key-many-to-many column="EVENT_ID" class="VerifiedEvent" />
<many-to-many column="ROLE_ID" class="Role" />
</map>

</class>

这样映射出来,会产生中间表,关联QualifiedRole主键及Role主键。并且QualifiedRole主键和VerifiedEvent的EVENT_ID作为联合主键。

现在需求变了,VerifiedEvent的id 可以关联多个role, 而不再是以前的1对1关系。所以看起来,应该对这样的模型进行映射

Map<VerifiedEvent, List<<Role>>, 不过查询了hibernate文档之后,不能直接对这样的结构进行映射。而采取把Map里面的 value:List<Role>放到一个新的wrapper类,再进行映射,如下:

<class name="QualifiedRole">

.....

<map name="qualifiedEventRole" cascade="all"
table="VERIFIED_ROLES_MAP">
<key column="QUALIFIED_ROLE_ID" not-null="false" />
<map-key-many-to-many column="EVENT_ID" class="VerifiedEvent" />
<many-to-many column="WRAPPER_ROLE_ID" class="WrapperRole" />
</map>

</class>

<class name="WrapperRole">

<id>**** </id>

<list>

<key column="WRAPPER_ROLE_ID" />
<list-index column="LIST_INDEX" />
<one-to-many class="Role" />

</list>

</class>

虽然这样能解决问题,但是在一个运行很久的系统来说,这样会造成数据表的变化,那么以前大量的老数据如何迁移?

基于以上考虑,决定使用一个新类: QualifiedEventRole,并利用它关联以前的Key和Value 对象,至于mapping,以映射Set的方式,即可重用以前的表结构。模型变化如下:

<class name="QualifiedRole">

.....

<set name="qualifiedEventRole" table="VERIFIED_ROLES_MAP">
            <key column="QUALIFIED_ROLE_ID" not-null="false" />
            <composite-element class="VerifiedApplicationRole">
                <many-to-one name="verificationEvent" class="VerifiedEvent" column="EVENT_ID"/>
                <many-to-one name="role" class="Role" column="ROLE_ID"/>
            </composite-element>

</set>

</class>

总结:以这种方式实现重构,表结构无任何变化,还是和以前一样,3张表:QualifiedRole, VerifiedEvent, Role以及一个中间表VERIFIED_ROLES_MAP,但以前的Key: VerifiedEvent对象,满足了需求,实现了对多个Role的依赖,不再有唯一约束。

在老数据很大,关系较负责的情况下,要考虑数据迁移的难度。能不变表结构实现重构,这样的方式,只需要修改domain模型相关代码,升级相对简单。

抱歉!评论已关闭.