Hibernate中配置双向多对多关联

在项目中我们经常会用到一对多、一对一及多对多关联,下面我用角色和模块来举例说明多对多关联在Hibernate中的配置

第一步创建表,s_role(角色表)、s_module(模块表)、s_role_module(角色模块表)。一个角色可以有多个模块,一个模块可以被多个角色拥有,它们之间是多对多的关系,表结构如下(表中没有建立外键关联,此处的外键关联关系由Hibernate维护):

角色表

CREATE TABLE s_role
(
  id integer NOT NULL,
  "name" character varying(100) NOT NULL, -- 角色名称
  ctime timestamp without time zone NOT NULL, -- 创建时间
  sorts smallint NOT NULL, -- 排序
  CONSTRAINT s_role_id_pkey PRIMARY KEY (id) 
)

模块表

CREATE TABLE s_module
(
  id integer NOT NULL,
  "name" character varying(100), -- 模块名称
  url character varying(300) NOT NULL, -- 模块URL路径
  ctime timestamp without time zone NOT NULL, -- 创建时间
  pid integer, -- 父模块ID
  sorts smallint NOT NULL, -- 排序
  isleaf smallint NOT NULL, -- 是否为叶子节点
  CONSTRAINT s_module_id_pkey PRIMARY KEY (id)
)

角色 模块表(中间表保存角色ID和模块ID)

CREATE TABLE s_role_module
(
  mid integer NOT NULL, -- 模块ID
  rid integer NOT NULL, -- 角色ID
  CONSTRAINT s_role_module_mid_rid_pkey PRIMARY KEY (mid, rid)
)

二、用MyElipcse生成Po和hbm文件(只需生成角色和模块两个表的映射关系),然后修改PO和hbm文件

角色PO

public class SRole implements java.io.Serializable {

private Integer id;
private String name;
private Date ctime;
private Short sorts;

       //一个角色有多个模块
private Set<SModule> srmSet = new TreeSet<SModule>();

        //此处省略了get和set方法(代码太多)

}

一个角色可以拥有多个模块,我们在SRole(PO)中添加一个Set集合,集合中包含模块对象(SModule),然后配置hbm文件

SRole.hbm.xml中的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="cn.navidog.admin.pojo.SRole" table="s_role" schema="public">
        <comment>角色表</comment>
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="sequence" >
            <param name="sequence" >seq_role</param>
</generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="100" not-null="true" />
        </property>
        <property name="ctime" type="java.util.Date">
            <column name="ctime" length="8" not-null="true" />
        </property>
        <property name="sorts" type="java.lang.Short">
            <column name="sorts" not-null="true" />
        </property>
<!-- 角色和模块多对多关联 -->
<set name="srmSet" table="s_role_module" inverse="false" cascade="all">
<key>
<column name="rid">
<comment>角色ID</comment>
</column>
</key>

                        
<many-to-many class="cn.navidog.admin.pojo.SModule" column="mid"/>
</set>
    </class>
</hibernate-mapping>

在hbm文件中添加一个<set>,set中的name是指PO中的属性名称,table是指中间表(s_role_module)的名称,<key>中的Column是指中间表中的外键(rid,参照角色表中的ID),<many-to-many>中的class是指模块表对应PO对象,其中的column是指中间表中参照模块表主键的外键(即mid),到这里多对多的单向关联就配置好了,双向关联还需修改模块表对应的PO和hbm文件。

模块表PO

public class SModule implements java.io.Serializable,Comparable {
private Integer id;
private String name;
private String url;
private Date ctime;
private Integer pid;
private Short sorts;
private Short isleaf;

       //此处省略了get和set方法

        // 一个模块可以有被多个角色管理
private Set<SRole> srmSet = new TreeSet<SRole>();

}

模块表PO中需要添加一个Set集合,一个模块可被多个角色拥有(如上)

模块表的Hbm文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="cn.navidog.admin.pojo.SModule" table="s_module" schema="public">
        <comment>模块表</comment>
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="sequence" >
            <param name="sequence" >seq_module</param>
</generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="100" />
        </property>
        <property name="url" type="java.lang.String">
            <column name="url" length="300" not-null="true" />
        </property>
        <property name="ctime" type="java.util.Date">
            <column name="ctime" length="8" not-null="true" />
        </property>
        <property name="pid" type="java.lang.Integer">
            <column name="pid" />
        </property>
        <property name="sorts" type="java.lang.Short">
            <column name="sorts" not-null="true" />
        </property>
        <property name="isleaf" type="java.lang.Short">
            <column name="isleaf" not-null="true" />
        </property>
<!-- 模块角色双向多对多关联 -->
<set name="srmSet" table="s_role_module" cascade="all" inverse="false" lazy="true" >
<key >
<column name="mid" not-null="true" >
<comment >模块ID</comment>
</column>
</key>
<many-to-many class="cn.navidog.admin.pojo.SRole" column="rid" />
</set>
    </class>
</hibernate-mapping>
在hbm文件中我们需要添加一个<set>元素,set中的name是指模块表对应PO中的set集合属性的名称,table指定中间表的名称,<key>中的column是指中间表中以模块表中的主键ID为参照的外键(即mid),<many-to-many>中的class是指模块PO中包含的多个角色对象(SRole), column是指在中间表中以角色表中的主键ID为参照的外键(即rid),到此多对多双向关联的配置就完成了,有不对的地方还望大家指出。


你可能感兴趣的:(Hibernate,MyEclipse,Module,Integer,Class,character)