Hibernate<四> Hibernate关联映射

Hibernate映射关系概述:

        Hibernate关联映射分为:

        ①、多对一。②、一对多。③、一对一。④、多对多。⑤、组件映射。⑥、集合映射。

        在Uml语言中关联是有方向的,以客户Customer和订单Order的关系为例,一个客户能发出多个订单,而一个订单只能属于一个客户。从Order到Customer的关联是多对一,这意味着每个Order对象都会引用一个Customer对象,因此在Order类中应该定义一个Customer类型的属性,来引用关联的Customer对象。从Customer到Order是一对多关联,这意味着每个Customer对象会引用一组Order对象,因此在Customer类中应该定义一个集合类型的属性,来引用所有关联的Order对象。如果仅有从Order到Customer的关联,或者仅有从Customer到Order的关联,就称为单向关联。如果同时包含两种关联,就称为双向关联。

       在关系数据库中,只存在外键参照关系,而且总是由many方参照one方,因为这样才能消除数据冗余,因此实际上关系数据库只支持多对一或一对一的单向关联。

 

一、多对一的单向关联关系:<many-to-one>        

 1、    在Order类中定义一个customer属性,而在Customer类中无需定义用于存放Order对象的集合属性。我们在Order类中可以定义customer_id属性,但是没有多大意义,不方便。所以我们在Order类中定义的customer属性时Customer类型的,和Orders表的外键customer_id对应,所以下面的映射方式是错误的:

<property name="customer" column="customer_id" />   这种映射方式是错误的。

   在上面的配置代码中,customer属性是Customer类型,而Orders表的外键customer_id是整数类型,显然类型不匹配,因此不能使用<property>元素来映射customer属性,而要使用<many-to-one>元素

<many-to-one name="customer" column="customer_id" class="Com.edu.bean.Customer" nut-null="true"/>

   name:设置持久化类的属性名。

  column:设定和持久化类的属性对应的表的外键。

  class:设定持久化类的属性的类型。

  not-null:如果为true,表示customer属性不允许为null,该属性的默认值为false。

Order类和Customer类分别如下:

public class Customer{
    private String cid;
    private String cname;
    public Customer(){}   //持久化类必须提供默认的构造函数
    public Customer(String cid,String cname){
     this.cid=cid;
    this.cname=cname;

    } 
    public String getCid() {
      return cid;
     }
     public void setCid(String cid) {
      this.cid = cid;
     }
     public String getCname() {
      return cname;
     }
     public void setCname(String cname) {
      this.cname = cname;
     }
}

   Customer.hbm.xml文件:

<hibernate-mapping package="com.edu.bean">
 <class name="Customer" table="sys_customer">
  <id name="cid" column="cid">
   <generator class="assigned"></generator>
  </id>
  <property name="cname" column="cname" ></property> 
 </class>
</hibernate-mapping>

Order类:

package com.edu.bean;
public class Order {
 private String oid;
 private String oname;
 private Customer customer;
 public Order(){}
 public String getOid() {
  return oid;
 }
 public void setOid(String oid) {
  this.oid = oid;
 }
 public String getOname() {
  return oname;
 }
 public void setOname(String oname) {
  this.oname = oname;
 }
 public Customer getCustomer() {
  return customer;
 }
 public void setCustomer(Customer customer) {
  this.customer = customer;
 }
 
}

 Order.hbm.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.edu.bean">
 <class name="Order" table="sys_order">
  <id name="oid" column="oid">
   <generator class="assigned"></generator>
  </id>
  <property name="oname" column="oname" ></property>
  <many-to-one name="customer" column="customerId" class="Customer"></many-to-one> 
 </class>
</hibernate-mapping>

二、一对多的单向关联关系:<one-to-many>

1、我们现在的业务需求经常要获得某个customer对象的所有order,所以为了方便起见我们采用Hibernate的多对已关联关系,在Customer类中,定义Set<order>order集合。

现在Customer类修改如下:

public class Customer{
    private String cid;
    private String cname;
    private Set<Order> orders;
     public Set<Order> getOrders() {
      return orders;
     }
     public void setOrders(Set<Order> orders) {
      this.orders= orders;
     }
    public Customer(){}   //持久化类必须提供默认的构造函数
    public Customer(String cid,String cname){
     this.cid=cid;
    this.cname=cname;

    } 
    public String getCid() {
      return cid;
     }
     public void setCid(String cid) {
      this.cid = cid;
     }
     public String getCname() {
      return cname;
     }
     public void setCname(String cname) {
      this.cname = cname;
     }
}

Customer.hbm.xml文件修改如下:

<hibernate-mapping package="com.edu.bean">
 <class name="Customer" table="sys_customer">
  <id name="cid" column="cid">
   <generator class="assigned"></generator>
  </id>
  <property name="cname" column="cname" ></property> 
 </class>
 <set name="orders">
     <key column="customerId"/>
     <one-to-many class="Order">
     </one-to-many>
 </set>
</hibernate-mapping>

三、一对一关联关系

Hibernate的一对第一关联关系有两种实现方式:共享主键方式和唯一外键方式。在这种一对一关联关系中对象分为主对象和从对象。

1、基于主键的一对一关联关系:

例如Person人只有一个身份证Idcard,Person和IdCard是一对一的关系:

Person类:

 package com.edu.bean;
public class Person {
 private String id;
 private String name;
 private IdCard idcard;
 
 public Person(){}
 public Person(String id,String name,IdCard idcard){
  this.id=id;
  this.name=name;
  this.idcard=idcard;
 }
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public IdCard getIdcard() {
  return idcard;
 }
 public void setIdcard(IdCard idcard) {
  this.idcard = idcard;
 }
 
}

Person.hbm.xml文件

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE hibernate-mapping PUBLIC 
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 <hibernate-mapping package="com.edu.bean">
  <class name="Person" table="sys_person">
   <id name="id" column="id">
    <generator class="assigned"></generator>
   </id>
   <property name="name" column="name" ></property>
   <one-to-one name="idcard"></one-to-one>
  </class>
 </hibernate-mapping>

IdCar类:

package com.edu.bean;
public class IdCard {
 private String id;
 private String username;
 private Person person;
 public Person getPerson() {
  return person;
 }
 public void setPerson(Person person) {
  this.person = person;
 }
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
}

IdCard.hbm.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.edu.bean">
 <class name="IdCard" table="sys_idcard">
  <id name="id" column="id">
   <generator class="foreign">
    <param name="property">person</param>
   </generator>
  </id>
  <property name="username" column="username" ></property>
  <one-to-one name="person" class="Person" constrained="true"></one-to-one>
 </class>
</hibernate-mapping>

   这里使用Hibernate的constrained属性,这个属性只能在<one-to-one>的映射中使用,如果constrained=true,则表明该类对应的表和被关联的对象所对应的数据库之间,通过一个外键引用对主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序。例如在save的时候,如果constrained=true,则会先增加关联表,然后增加本表,删除的时候相反。

2、基于外键的一对一关联关系:

Person类及Person.hbm.xml文件没有任何变化:

IdCard类:

package com.edu.bean;
public class IdCard {
 private String id;
 private String username;
 private Person person;
 public Person getPerson() {
  return person;
 }
 public void setPerson(Person person) {
  this.person = person;
 }
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
}

IdCard.hbm.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.edu.bean">
 <class name="IdCard" table="sys_idcard">
  <id name="id" column="id">
   <generator class="assigned">
   </generator>
  </id>
  <property name="username" column="username" ></property>
  <many-to-one name="person" column="p_id" class="Person" unique="true"></many-to-one>
  <!-- <one-to-one name="person" class="Person" constrained="true"></one-to-one> -->
 </class>
</hibernate-mapping>

四、多对多关联关系:

    在关系型数据库中实体多对多时,我们一般创建中间关联表,而Hibernate同样也会为我们创建中间关联表,将多对多拆分为2个一对多。

    例如经典的用户角色问题:

    用户User类:

 package com.edu.bean;
import java.util.Set;
public class User {
 private String uid;
 private String uname;
 private String password;
 private Set<Role> roles;
 public User(){}
 public User(String uid,String uname,String password){
  this.uid=uid;
  this.uname=uname;
  this.password=password;
 }
 public String getUid() {
  return uid;
 }
 public void setUid(String uid) {
  this.uid = uid;
 }
 public String getUname() {
  return uname;
 }
 public void setUname(String uname) {
  this.uname = uname;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 public Set<Role> getRoles() {
  return roles;
 }
 public void setRoles(Set<Role> roles) {
  this.roles = roles;
 }
}

    User.hbm.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.edu.bean">
 <class name="User" table="sys_user">
  <id name="uid" column="uid">
   <generator class="assigned"></generator>
  </id>
  <property name="uname" column="uname" ></property>
  <property name="password" column="password"></property>
  <set name="roles" table="user_role">
   <key column="uid"></key>
   <many-to-many class="Role" column="rid"></many-to-many>
  </set>
 </class>
</hibernate-mapping>

    角色类Role:

package com.edu.bean;
import java.util.Set;
public class Role {
 private String rid;
 private String rname;
 private Integer ordernum;
 private String description;
 private Set users;
 
 public Role(){}
 public Role(String rid,String rname,Integer ordernum,String description){
  this.rid=rid;
  this.rname=rname;
  this.ordernum=ordernum;
  this.description=description;
 }
 public String getRid() {
  return rid;
 }
 public void setRid(String rid) {
  this.rid = rid;
 }
 public String getRname() {
  return rname;
 }
 public void setRname(String rname) {
  this.rname = rname;
 }
 public Integer getOrdernum() {
  return ordernum;
 }
 public void setOrdernum(Integer ordernum) {
  this.ordernum = ordernum;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public Set getUsers() {
  return users;
 }
 public void setUsers(Set users) {
  this.users = users;
 }
}

    Role.hbm.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.edu.bean">
 <class name="Role" table="sys_role">
  <id name="rid" column="rid">
   <generator class="assigned"></generator>
  </id>
  <property name="rname" column="rname" ></property>
  <property name="ordernum" column="ordernum"></property>
  <property name="description" column="description"></property>
  <set name="users" table="user_role">
   <key column="rid"></key>
   <many-to-many class="User" column="uid"></many-to-many>
  </set>
 </class>
</hibernate-mapping>

转载于:https://my.oschina.net/wangning0535/blog/488706

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值