hibernate关联映射(二)

本文详细介绍了在Hibernate框架中实现一对一映射关系的两种方式:主键关联和唯一外键关联,并通过实际代码示例展示了如何在Student和StudentInfo类之间建立一对一关系。同时,还介绍了如何通过一对多映射实现特殊的一对一映射关系,以及多对多映射的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在现实生活中,一对一的映射关系不是很多,相对于多对多,一对多比较简单,比如:学生和学生信息就是一个一对一的关系。
在hibernate中有两种方式可以实现一对一的映射关系:
1.主键关联:即让两个对象拥有相同的主键值,以表明他们之间的一一对应关系,数据库表不会有额外的字段来维护他们之间的关系,仅通过表的主键来关联。
2.唯一外键关联:外键关联原本是用于一对多的映射,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系。

主键关联实现一对一

先来看下Student和StudentInfo这两个类:
StudentInfo.java

package x.y.z;

public class StudentInfo {
    private  int infoId;
    private String realName;
    private String qq;

    //基本信息
    private Student base;

    public int getInfoId() {
        return infoId;
    }

    public void setInfoId(int infoId) {
        this.infoId = infoId;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public String getQq() {
        return qq;
    }

    public void setQq(String qq) {
        this.qq = qq;
    }

    public Student getBase() {
        return base;
    }

    public void setBase(Student base) {
        this.base = base;
    }

    public StudentInfo(){}

    public StudentInfo(int infoId,String realName,String qq){
        this.infoId = infoId;
        this.realName = realName;
        this.qq = qq; 
    }

}

Student.java

package x.y.z;

public class Student {
    private int stuid;
    private String stuname;

    //详细信息
    private StudentInfo info;

    public Student(){}

    public Student(int stuid,String stuname){
        this.stuid = stuid;
        this.stuname = stuname;
    }

    public int getStuid() {
        return stuid;
    }

    public void setStuid(int stuid) {
        this.stuid = stuid;
    }

    public String getStuname() {
        return stuname;
    }

    public void setStuname(String stuname) {
        this.stuname = stuname;
    }

    public StudentInfo getInfo() {
        return info;
    }

    public void setInfo(StudentInfo info) {
        this.info = info;
    }

}

可以看到在Student和StudentInfo这两个类当中,都有对方的引用。
StudentInfo.hbm.xml

<hibernate-mapping>
    <class name="x.y.z.StudentInfo">
        <id name="infoId">
            <generator class="foreign">
                <param name="property">base</param><!-- 把Student的主键 当做StudentInfo的外键 -->
            </generator>
        </id>
        <property name="realName"></property>
        <property name="qq"></property>

        <one-to-one name="base" constrained="true" />
    </class>
</hibernate-mapping>

Student.hbm.xml

<hibernate-mapping>
    <class name="x.y.z.Student">
        <id name="stuid">
            <generator class="native"/>
        </id>
        <property name="stuname"></property>

        <one-to-one name="info"/>       <!-- Student.java实体类的第八行info -->
    </class>
   </hibernate-mapping>

根据映射文件可以看出:studentInfo的主键依赖于student的主键,这就保证了一对一的映射。
下面实现一对一的插入操作:

Session session = new Configuration().configure().buildSessionFactory().openSession();
session.beginTransaction();
Student s1 = new Student(0,"张三");
Student s2 = new Student(0,"李四");

StudentInfo info1 = new StudentInfo(100,"张大三","1234567");
StudentInfo info2 = new StudentInfo(200,"李小四","7654321");
//由约束方StudentInfo维护关系
info1.setBase(s1);
info2.setBase(s2);

session.save(s1);
session.save(s2);

session.save(info1);
session.save(info2);

session.getTransaction().commit();
session.close();

唯一外键关联实现一对一映射

可以通过一对多实现特殊的一对一,当多方只有一个的时候,就是标准的一对一实现。
Student.hbm.xml

<hibernate-mapping>
    <class name="x.y.z.Student">
        <id name="stuid">
            <generator class="native"/>
        </id>
        <property name="stuname"></property>

        <one-to-one name="info"/>       
    </class>
</hibernate-mapping>

StudentInfo.hbm.xml

 <hibernate-mapping>
       <class name="x.y.z.StudentInfo">
            <id name="infoId">
                <generator class="assigned"/>
            </id>
            <property name="realName"></property>
            <property name="qq"></property>

            <many-to-one name="base" unique="true" column="s_id"/>      <!-- 有约束方维护关系 -->
            <!-- 特殊的many-to-one,一对一(把以前的多个合并成一个) -->
        </class>
 </hibernate-mapping>

hibernate多对多实现

在hibernate中多对多的实现都是通过一个中间表来将其转换成两个一对多的。这里我以Market和Product来做例子,比如:一个超市可以出售多种商品,一个商品也可以在多个超市里边出售。先来看下这两个实体类:
Market.java

public class Maket {

    private int mid;
    private String mname;
    private String maddr;   
    Set<Product> prods = new HashSet<Product>();    
    public Maket() {
        super();
    }   
    public Maket(int mid, String mname, String maddr) {
        super();
        this.mid = mid;
        this.mname = mname;
        this.maddr = maddr;
    }
    public int getMid() {
        return mid;
    }
    public void setMid(int mid) {
        this.mid = mid;
    }
    public String getMname() {
        return mname;
    }
    public void setMname(String mname) {
        this.mname = mname;
    }
    public String getMaddr() {
        return maddr;
    }
    public void setMaddr(String maddr) {
        this.maddr = maddr;
    }
    public Set<Product> getProds() {
        return prods;
    }
    public void setProds(Set<Product> prods) {
        this.prods = prods;
    }   
}

Product.java

public class Product {

    private int pid;
    private String pname;
    private double price;
    Set<Maket> tomakets = new HashSet<Maket>();
    public Product() {
        super();
    }
    public Product(int pid, String pname, double price) {
        super();
        this.pid = pid;
        this.pname = pname;
        this.price = price;
    }
    public int getPid() {
        return pid;
    }
    public void setPid(int pid) {
        this.pid = pid;
    }
    public String getPname() {
        return pname;
    }
    public void setPname(String pname) {
        this.pname = pname;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public Set<Maket> getTomakets() {
        return tomakets;
    }
    public void setTomakets(Set<Maket> tomakets) {
        this.tomakets = tomakets;
    }   
}

可以看到在Market和Product中都有各自引用。
product.hbm.xml

<hibernate-mapping>
    <class name="a.b.c.Product">
        <id name="pid">
            <generator class="native"/>
        </id>
        <property name="pname"/>
        <property name="price"/>

        <set name="tomakets" table="prod_mkt" inverse="true" cascade="all">
            <key column="p_id"/>
            <many-to-many class="a.b.c.Maket" column="m_id"/>
        </set>
    </class>
</hibernate-mapping>    

说明一下:”prod_mkt”是生成的中间表的名称,inverse=”true”表示有对方来维护关系,”p_id”表示该类所对应的生成的中间表的外键。。
Maket.hbm.xml

<hibernate-mapping>
    <class name="a.b.c.Maket">
        <id name="mid">
            <generator class="native"/>
        </id>

        <property name="mname"/>
        <property name="maddr"/>

        <set name="prods" table="prod_mkt" cascade="all">
            <key column="m_id"/>
            <many-to-many class="a.b.c.Product" column="p_id"/>
        </set>

    </class>
</hibernate-mapping>    

好了,关于hibernate的映射的配置就学习到这里了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值