提到hibernate,肯定少不了实体之间的几种映射关系。一般“出镜率”比较高的都会有一种规律,接下来就跟
大家分享一下hibernate实体映射的技巧。
实体映射三部曲
设计实体写关联关系注释,根据关联关系拷模板,填充模板。
1.设计实体写关联关系注释
格式: ?属性,本类与?的?关系
2.拷模板
多对一
<span style="font-family:SimSun;font-size:18px;"><many-to-one name="" class="" column=""></many-to-one></span>
一对多
<span style="font-family:SimSun;font-size:18px;"><set name="">
<key column=""/>
<one-to-many class=""/>
</set></span>
多对多
<span style="font-family:SimSun;font-size:18px;"><set name="" table="">
<key column=""/>
<many-to-many class="" column=""/>
</set>
</span>
3.填充模板 (将步骤一中的3个问号值填充到模版中)
Name:属性名,步骤一第一个?
class:关联的实体类型,步骤一第二个?
column:关联主外键。<many-to-one>映射一般写成属性名加Id后缀。<one-to-many>从<many-to-one>中将column的
值拷贝过来
下面结合一个实例来看一下具体应用。
需求提取:一个部门有一个上级,多个下级,一个部门内有多个员工,一个员工有多种角色,同时一个角色有多
个员工,(详细属性省略)。根据上述需求,我们设计出三个实体及三者之间的关联关系, 如下:
用户
<span style="font-family:SimSun;font-size:18px;">public class User {
private Long id; //用户id
private String loginName; // 登录名
private String password; // 密码
private String name; // 真实姓名
private String gender; // 性别
private String phoneNumber; // 电话号码
private String email; // 电子邮件
private String description; // 说明
//一个用户只属于一个部门
private Department department;
//一个用户有多个角色
private Set<Role> roles=new HashSet<Role>();
/*=========get、set方法==========*/
}</span>
部门
<span style="font-family:SimSun;font-size:18px;">public class Department {
private Long id;
private String name;
private String description;
//一个部门有多个用户
private Set<User> users=new HashSet<User>();
//自关联,一个部门只有一个上级部门
private Department parent;
//自关联,一个部门有多个下级部门
private Set<Department> children =new HashSet<Department>();
/*=========get、set方法==========*/
}</span>
角色
<span style="font-family:SimSun;font-size:18px;">public class Role {
//角色id
private Long id;
//角色名称
private String name;
//角色说明
private String description;
//一个角色有多个用户
private Set<User> users=new HashSet<User>();
/*=========get、set方法==========*/
}</span>
第二步,根据注释拷模板。
<span style="font-family:SimSun;font-size:18px;"><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.oa.domain">
<class name="Department" table="itcast_department">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<property name="description" />
<!-- users属性,本类与User的一对多关系 -->
<set name="">
<key column=""/>
<one-to-many class=""/>
</set>
<!-- parent属性,本类与Department(上级)的多对一关系 -->
<many-to-one name="" class="" column=""></many-to-one>
<!-- children属性,本类与Department(下级)的一对多关系 -->
<set name="">
<key column=""/>
<one-to-many class="" />
</set>
</class>
</hibernate-mapping></span>
<span style="font-family:SimSun;font-size:18px;"><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.oa.domain">
<class name="User" table="itcast_user">
<id name="id">
<generator class="native"/>
</id>
<property name="loginName" />
<property name="password" />
<property name="name" />
<property name="gender" />
<property name="phoneNumber" />
<property name="email" />
<property name="description" />
<!-- department属性,本类与Department的多对一关系 -->
<!-- roles属性,本类与Role的多对多关系 -->
<set name="" table="">
<key column=""/>
<many-to-many class="" column=""/>
</set>
</class>
</hibernate-mapping></span>
<span style="font-family:SimSun;font-size:18px;"><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.oa.domain">
<class name="Role" table="itcast_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<property name="description" />
<!-- users属性,本类与User的多对多关系 -->
<set name="" table="">
<key column=""/>
<many-to-many class="" column=""/>
</set>
</class>
</hibernate-mapping></span>
第三步,根据关联关系填充模板
<span style="font-family:SimSun;font-size:18px;"><hibernate-mapping package="cn.itcast.oa.domain">
<class name="Department" table="itcast_department">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<property name="description" />
<!-- users属性,本类与User的一对多关系 -->
<set name="users">
<key column="departmentId"/>
<one-to-many class="User"/>
</set>
<!-- parent属性,本类与Department(上级)的多对一关系 -->
<many-to-one name="parent" class="Department" column="parentId"></many-to-one>
<!-- children属性,本类与Department(下级)的一对多关系 -->
<set name="children">
<key column="parentId"/>
<one-to-many class="Department" />
</set>
</class>
</hibernate-mapping></span>
<span style="font-family:SimSun;font-size:18px;"><hibernate-mapping package="cn.itcast.oa.domain">
<class name="User" table="itcast_user">
<id name="id">
<generator class="native"/>
</id>
<property name="loginName" />
<property name="password" />
<property name="name" />
<property name="gender" />
<property name="phoneNumber" />
<property name="email" />
<property name="description" />
<!-- department属性,本类与Department的多对一关系 -->
<!-- roles属性,本类与Role的多对多关系 -->
<set name="roles" table="itcast_role_user">
<key column="userId"/>
<many-to-many class="Role" column="roleId"/>
</set>
</class>
</hibernate-mapping></span>
<span style="font-family:SimSun;font-size:18px;"><hibernate-mapping package="cn.itcast.oa.domain">
<class name="Role" table="itcast_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<property name="description" />
<!-- users属性,本类与User的多对多关系 -->
<set name="users" table="itcast_role_user">
<key column="roleId"/>
<many-to-many class="User" column="userId"/>
</set>
</class>
</hibernate-mapping></span>
其实多对多就是两个一对多,它的配置没什么新奇的。在多对多的关系设计中,一般都会使用一个中间表将他们
拆分成两个一对多。<set>标签中的"table"属性就是用于指定中间表的。中间表一般包含两个表的主键值,该表用于
存储两表之间的关系。由于被拆成了两个一对多,中间表是多方,它是使用外键关联的,<key>是用于指定外键的,
用于从中间表取出相应的数据。中间表每一行数据只包含了两个关系表的主键,要获取与自己关联的对象集合,还需
要取出由外键所获得的记录中的另一个主键值,由它到对应的表中取出数据,填充到集合中。<many-to-many>中
的"column"属性是用于指定按那一列的值获取对应的数据。