Hibernate多表关系配置——多对一关系映射

Posted zxd543

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate多表关系配置——多对一关系映射相关的知识,希望对你有一定的参考价值。

班级和学生两个实体类,关系如下:

多对一(many-to-one):多个学生属于一个班级

一对多(one-to-many):一个班级有多个学生

1、班级实体

技术分享
package demo.entity;

import java.util.HashSet;
import java.util.Set;

/**
 * 班级
 * @author Don
 * @date:日期:2017年4月10日 时间:下午4:51:56*
 * @version 1.0
 */
public class Cla {
    private int id;
    private String name;
    private String addr;
    private Set<Student> stus=new HashSet<Student>();
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddr() {
        return addr;
    }
    public void setAddr(String addr) {
        this.addr = addr;
    }
    public Set<Student> getStus() {
        return stus;
    }
    public void setStus(Set<Student> stus) {
        this.stus = stus;
    }
}
View Code

映射关系

<?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>
    <!-- name:实体, table:表名 -->
    <class name="demo.entity.Cla" table="m2o_cla">
        <!-- name:主键的名字,column:主键数据库表列,identity自增 -->
        <id name="Id">
            <!-- Hibernate使用generator类来生成主键 -->
            <generator class="identity" />
        </id>
        <!-- name:实体中的属性名,length:长度 ,column:表中的字段(实体属性和字段一致可省略),type:类型(可不写由hiberbate自动匹配) -->
        <property name="name"  />
        <property name="addr"/>
        
        <!-- inverse:这个属性(stus) 是否为关系的维护方,默认值为false
            如果inverse设置为true,表示将由对方维护两者之间的关联关系
         -->
        <!--cascade(级联)意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作
            all-代表在所有的情况下都执行级联操作
            none-在所有情况下都不执行级联操作
            save-update-在保存和更新的时候执行级联操作
            delete-在删除的时候执行级联操作
         -->
         <!--lazy:延迟加载,默认true,如学生实体不调用班级实体信息,可以不用加载  -->
        <set name="stus" inverse="false" cascade="all" lazy="true">
            <!-- 关系维护方的外键列 -->
            <key column="cid"></key>
            <one-to-many class="demo.entity.Student" />
        </set>
    </class>
</hibernate-mapping>

 2、学生实体

技术分享
package demo.entity;
/**
 * 学生信息
 * @author Don
 * @date:日期:2017年4月10日 时间:下午4:50:55*
 * @version 1.0
 */
public class Student {
    private int id;
    private String name;
    private int age;
    private Cla cla;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Cla getCla() {
        return cla;
    }
    public void setCla(Cla cla) {
        this.cla = cla;
    }
    
}
View Code

映射关系

<?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>
    <!-- name:实体, table:表名 -->
    <class name="demo.entity.Student" table="m2o_stu">
        <!-- name:主键的名字,column:主键数据库表列,identity自增 -->
        <id name="Id">
            <!-- Hibernate使用generator类来生成主键 -->
            <generator class="identity" />
        </id>
        <!-- name:实体中的属性名,length:长度 ,column:表中的字段(实体属性和字段一致可省略),type:类型(可不写由hiberbate自动匹配) -->
        <property name="name"  />
        <property name="age"/>
        
        <!-- 对应班级配置中的cid -->
        <many-to-one name="cla" column="cid" cascade="save-update"></many-to-one>
    </class>
</hibernate-mapping>

3、测试上述配置关系

获取Session会话公共方法

技术分享
package demo.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

public class HibernateUtil {

    public static Session getCurrentSession() {

        /*
         * 两种配置文件的加载方式,hibernate.properties只配置数据库的连接方式
         * 属性文件(hibernate.properties)调用代码:Configuration cfg = new
         * Configuration(); Xml文件(hibernate.cfg.xml) 调用代码:Configuration cfg =
         * new Configuration().configure();
         */

        // 加载Hibernate配置信息,默认读取src下的hibernate.cfg.xml
        Configuration cfg = new Configuration().configure();
        // 也可以指定hibernate.cfg.xml 的路径加载
        // Configuration cfg1 = new Configuration().configure(Path);

        /*
         * 应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。它在多个应用线程间进行共享。
         * 通常情况下,整个应用只有唯一的一个会话工厂,SessionFactory由Configuration对象创建,
         * 每个Hibernate配置文件,实际上是对SessionFactory的配置
         */
        // 试用配置信息构建sessionFactory
        SessionFactory factory = cfg.buildSessionFactory();
        
        Session session =factory.getCurrentSession();
        
        return session;
    }

}
View Code

3.1保存数据

技术分享
package demo.test;

import org.hibernate.classic.Session;

import demo.entity.Cla;
import demo.entity.Student;
import demo.util.HibernateUtil;

public class TestSave01 {

    public static void main(String[] args) {
        Cla c1 = new Cla();
        c1.setName("一班");
        c1.setAddr("101");
        
        Student stu1= new Student();
        stu1.setName("吕布");
        stu1.setAge(36);
        stu1.setCla(c1);
        
        Student stu2= new Student();
        stu2.setName("赵云");
        stu2.setCla(c1);
        
        //持久化
        Session session = HibernateUtil.getCurrentSession();
        session.beginTransaction();
        
        session.save(c1);
        
        //尽量保存真正的维护方对象,即一对多 由多的维护
        session.save(stu1);
        session.save(stu2);    

        session.getTransaction().commit();
    }

}
View Code

3.2查找数据

技术分享
package demo.test;

import org.hibernate.classic.Session;

import demo.entity.Cla;
import demo.entity.Student;
import demo.util.HibernateUtil;

public class TestFind {

    public static void main(String[] args) {

        // 持久化
        Session session = HibernateUtil.getCurrentSession();
        session.beginTransaction();
        
        Cla cla =(Cla) session.get(Cla.class, 1);
        System.out.println("班级名称:"+cla.getName());
        System.out.println("班级地址:"+cla.getAddr());
        System.out.println("班级人数:"+cla.getStus().size());
        
        for(Student stu:cla.getStus())
        {
            System.out.println(stu.getName()+":"+stu.getAge());
        }

        session.getTransaction().commit();
    }

}
View Code

3.3删除数据

技术分享
package demo.test;

import org.hibernate.classic.Session;

import demo.entity.Cla;
import demo.entity.Student;
import demo.util.HibernateUtil;

public class TestDelete {

    /**
     * @param args
     */
    public static void main(String[] args) {

        // 持久化
        Session session = HibernateUtil.getCurrentSession();
        session.beginTransaction();
        
        /*
         *级联删除需要先查询
         * */
        Cla cla = (Cla)session.get(Cla.class, 1);
        session.delete(cla);

        session.getTransaction().commit();
    }

}
View Code

以上是关于Hibernate多表关系配置——多对一关系映射的主要内容,如果未能解决你的问题,请参考以下文章

如何正确映射与@IdClass 的多对一关系?

Hibernate关联映射

Hibernate多表关系配置——多对多对关系映射

Hibernate中一对多和多对一关系

Hibernate 的七种映射关系

Hibernate ManyToOne Mappings 多对一关联映射