Hibernate单向一对多对象关系模型映射

这篇博客介绍了Hibernate ORM中单向的One-to-Many关系映射,包括数据库模型、Java模型和配置方法。通过示例展示了如何进行班级与学生的关系建立、添加、修改、查询和删除操作,并探讨了级联操作在删除时的策略。

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

1 hibernate 的对象关系映射

Orm:

      类-----表

      属性------字段

      对象------记录

表:在数据库中存在主外键的关系,反向工厂类是由表生成,在由表生成类的时候,类和类之间存在者某个关系。将数据库的主外键关系,在java类型进行体现和维护(建立数据之间的关系和断开关系)。

2 单向的one-to-many

家庭和成员(家庭和成员之间的关系,是由家庭进行体现,成员不体现)

父亲和子女

班级和学生

……

2.1 单向one-to-many数据库的模型

在数据库中两张表,产生主外键关系。

描述班级和学生的关系

2.2单向one-to-many  java中的模型体现

通过java中的pojo进行表之间关系的体现。

在班级中定义班级下的学生的集合。

2.3单向one-to-many的配置

Classes.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="org.guangsoft.pojo">
    <!-- 类 到 表 -->
    <class name="Classes" table="t_classes">
        <id name="cid" column="cid" type="java.lang.Integer">
            <generator class="native"></generator>
        </id>
        <!-- 其他简单属性 -->
        <property name="cname" column="cname" type="java.lang.String"></property>
        <!-- 进行单向one-to-many的映射配置 -->
        <set name="stus" table="t_student">
            <key column="cid"></key>
            <!-- one:表示的Classes班级 many:表示的Student学生 calss属性:表示set集合中元素的类型。 x-to-y:当前标签在谁的配置文件中,x就代表谁。y就表示对方。 
                <element column="cls" type="java.lang.String"></element> -->
            <one-to-many class="Student" />
        </set>
    </class>
</hibernate-mapping>

Student.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="org.guangsoft.pojo">
    <!-- 类 到 表 -->
    <class name="Student" table="t_student">
        <id name="sno" column="sno" type="java.lang.Integer">
            <generator class="native"></generator>
        </id>
        <!-- 其他简单属性 -->
        <property name="sname" column="sname" type="java.lang.String"></property>
    </class>
</hibernate-mapping>

2.4进行CRUD操作

2.4.1添加班级信息

班级为one的一方,在数据库中为主表。

/***
 * 添加班级信息
 * ***/
@Test
public void testSaveClasses(){
    //1获得会话session
    Session session=sf.openSession();
    //2开启事务
    Transaction tr=session.beginTransaction();
    //3进行增加操作
    Classes  cls = new Classes();
    //cls对象封装数据
    cls.setCname("java逆袭班");
    session.save(cls);
    //提交事务
    tr.commit();
    //释放资源
    session.close();
}

2.4.2添加新班级和学生

在保存班级信息的时候,由于给班级对象,分配了学生信息,这时候会自动建立该班级和集合中学生的关系

/***
 * 添加班级的同时添加学生信息
 * set标签的cascade属性:对象的级联操作,对某个对象进行crud操作的是,
 *                    同时操作该对象,关联的对象
 * all:包含所有
 *  save-update:级联保存和更新,在one-to-many中,实际中通常设置为通过many去保存one
 *  delete:级联删除
 *  none:不级联(默认)
 * ****/
@Test
public void testSaveClasses2(){
    //1获得会话session
    Session session=sf.openSession();
    //2开启事务
    Transaction tr=session.beginTransaction();
    //3进行增加操作
    Classes  cls = new Classes();
    //cls对象封装数据
    cls.setCname("java爆发班");
    /**
     * 给班级分配学生信息
     * ***/
    Student s1 = new Student();
    s1.setSname("朱元璋");
    Student s2 = new Student();
    s2.setSname("刘邦");
    //将s1,s2分配给cls(建立班级和学生的关系)
    cls.getStus().add(s1);
    cls.getStus().add(s2);
    session.save(cls);
    //提交事务
    tr.commit();
    //释放资源
    session.close();
}

2.4.3 修改班级信息

/***更新班级信息
 *级联更新:更新了班级下的学生的信息
 * ***/
@Test
public void testUpdate(){
    //1获得会话session
    Session session=sf.openSession();
    //2开启事务
    Transaction tr=session.beginTransaction();
    //3进行增加操作
    Classes  cls =  (Classes) session.get(Classes.class, 3);
    cls.setCname("javaee班");
    //获得该班级学生
    Iterator<Student> its=cls.getStus().iterator();
    while(its.hasNext()){
        //获得某个学生信息
        Student s=its.next();
        s.setSname(s.getSname()+"名字");
    }
    session.update(cls);
    //提交事务
    tr.commit();
    //释放资源
    session.close();
}

2.4.4查询班级信息

同时关联加载  该班级下的所有学生。

/**
    查询班级信息,
    hibernate:在对象关联加载的时候,默认为延迟加载。
              延迟加载:在加载A对象的时候,不会立即查询与A对象的其他对象
              只有在访问A对象关联的其他对象的时候,(..)在进行数据库的查询
           默认延迟加载:提供数据库的加载速度 
 * ***/
@Test
public void testSelectClasses(){
    //1获得会话session
    Session session=sf.openSession();
    //查询所有的班级
    List<Classes> clist=session.createCriteria(Classes.class).list();
    //遍历集合
    for(Classes c :clist){
        System.out.println(c.getCname());
        //访问班级下的学生信息
        Set<Student>  stus = c.getStus();
        //获得stus集合的迭代器
        Iterator<Student>  it = stus.iterator();
        while(it.hasNext()){
            //获得一个学生信息
            Student s=it.next();
            System.out.println("\t\t"+s.getSname()+"\t\t"+c.getCname());
        }
    }
    //释放资源
    session.close();
}

2.4.5删除班级信息

需要删除主表中的数据,子表中关联的记录怎么处理:

      断开主外键,删除主表中的数据,子表中的数据继续存在

      主表,子表中的数据一起删除

/***
    删除班级信息
    1 删除主表中数据的默认情况,断开主外键关系,删除主表中数据
    2cascade级联删除
        cascade="all"  "delete"
        主表,子表一起删除
        delete-orphan:当通过控制方解除被控制的对象的时候。会自动将解除关系的对象进行删除
        对HashSet集合的使用:注意重写两个方法hashCode  和     equals()
 * ***/
@Test
public void testDeleteClasses2(){
    //1获得会话session
    Session session=sf.openSession();
    //2开启事务
    Transaction tr=session.beginTransaction();
    //3进行增加操作
    Classes  cls =  (Classes) session.get(Classes.class, 6);
    //获得该班级的所有学生
    Set<Student> stus=cls.getStus();
    Student s = new Student();
    s.setSno(6);
    //删除集合中的某个学生(解除班级和学生的关系)
    stus.remove(s);
    //提交事务
    tr.commit();
    //释放资源
    session.close();
}
/***给已有的班级,添加学生****/

2.4.5 出现问题

外键不允许为空造成:

 

使用hashSet集合注意:

      hashCode方法

      equals()方法

总结:cascade级联操作

      All(save-update,delete) :级联保存,更新,删除

      save-update:设置为one-to-many,将many的一方设置为save-update

      delete:设置one-to-many,将one的一方设置为delete或者all

      none:默认的删除是将主外键关系断开,(员工---工资)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值