一、问题
项目中有两张数据库表:权限新增(对应java类:AmRoleAddApply。用于存放新增的权限的信息)和权限移除(对应java类:AmRoleChangeApply。用于存放更改的权限的信息),这两张表的结构有些字段一样。由于需求变化,先要将两张表的列表内容在一个视图中显示(所要显示的列字段名和意义相同),并能根据搜索条件进行查询。(注:由于代码关联较多,在此就不罗列代码实例,只用文字描述实现过程和思想)
从一个表中查询众所周知,可是如何从两个表中查询并且方法简单不影响效率呢?
二、求解过程
网上搜了一下确定可以用hibernate试图映射实现。可是hibernate视图映射时啥玩意儿呢?又带着疑问上网搜了一下。可是网上说的hibernate视图有两种情况:
一、数据库已经建立视图,hibernate只是把视图当作普通的表来映射。
二、数据库没有视图,用hibernate自己做视图映射
以上两种情况有一个共同点,就是都需要一个对应的java实体类和hbm映射文件。这个实体类是从原有的两个实体类进行子查询,从而得出对应的视图。
这第一种情况当然容易理解了,这时映射视图和映射表的方式基本一样。第二种正是我所想要的。然而如何实现呢?
网上查了一下,不查不知道,一查才发现这个hibernate视图映射时需要配置联合主键,而联合主键有两种确定方式:一种是基于实体类的复合主键,另一种是通过定义主键类来实现。
第一种顾名思义当然是使用原有的实体类的属性类构成我们的视图实体类了。而第二种就稍微麻烦些,它是将属性抽取出来独立成为一个实体类。也就是说采用这种方式从头到尾你得写两个实体类和对应的映射文件。到这里基本思路终于有了。
三、解决问题
从简单实用的角度来考虑(当然也没发现哪篇文章上说明这些实现方式的性能上的差别,所以性能上就不考虑了),我选择了“hibernate自己做视图映射+基于实体类的复合主键”方式来实现。最终的hbm映射文件如下:
<hibernate-mapping>
<class name="com.landray.kmss.cmobile.uiam.model.AmRoleApply">
<meta attribute="sync-DAO">false</meta>
<!-- 子查询视图,列别名对应视图中的字段-->
<subselect>
<![CDATA[
select addapp.FD_ID fd_id,addapp.FD_APPLICANT_ID fd_applicant_id,addapp.DOC_STATUS doc_status, addapp.FD_SECRETARY_ID fd_secretary_id,addapp.FD_CREATE_TIME fd_create_time, '0' as fd_apply_type from AM_ROLE_ADD_APPLY addapp union select removeapp.FD_ID fd_id,removeapp.FD_APPLICANT_ID fd_applicant_id,removeapp.DOC_STATUS doc_status,removeapp.FD_SECRETARY_ID fd_secretary_id,removeapp.FD_CREATE_TIME fd_create_time,'1' as fd_apply_type from AM_ROLE_CHANGE_APPLY removeapp ]]>
</subselect>
<!-- 定义这个实体用到的表为同步,确保自动刷新,查询不会返回过期数据 -->
<synchronize table="AM_ROLE_ADD_APPLY" />
<synchronize table="AM_ROLE_CHANGE_APPLY" />
<!-- 联合主键-->
<composite-id>
<key-property
name="fdId"
column="FD_ID"
type="java.lang.String"
length="36">
</key-property>
<key-property
name="fdApplyType"
column="fd_apply_type"
type="java.lang.Long"
length="1" />
</composite-id>
<property
name="docStatus"
column="doc_status"
type="java.lang.String"
length="2" />
<property
name="fdCreateTime"
column="fd_create_time"
type="java.util.Date"
length="6" />
<many-to-one
name="fdSecretary"
column="fd_secretary_id"
class="com.landray.kmss.cmobile.uiam.model.AmDeptSecretary">
</many-to-one>
<many-to-one
name="fdApplicant"
column="fd_applicant_id"
class="com.landray.kmss.sys.organization.model.SysOrgElement">
</many-to-one>
</class>
</hibernate-mapping>
这里有一点是需要注意的,就是联合主键中的字段在表中每一条记录必须有该值,不然会出现问题。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lujun262589342/archive/2010/01/05/5135161.aspx