Hibernate07_映射关系-MangToOne

来源:互联网 发布:直通车重要数据 编辑:程序博客网 时间:2024/06/04 00:25

一、基本属性映射

实体类Book

package com.chb.model;public class Book {    private String id;    private String name;    private double price;    //书的页数    private int bookPage;    public Book() {}    public Book(String id, String name, double price, int bookPage) {        super();        this.id = id;        this.name = name;        this.price = price;        this.bookPage = bookPage;    }    public void setBookPage(int bookPage) {        this.bookPage = bookPage;    }    public long getBookPage() {        return bookPage;    }    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 double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }   }

Book.hbm.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping        SYSTEM        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" ><!-- 映射对应的package --><hibernate-mapping package="com.chb.model">    <!-- 实体类Book与数据库中表Book_info对应 -->    <class name="Book" table="book_table">        <id name="id" column="book_id">            <!-- 会自动生成一个字符串, 主键必须为String类型  -->            <generator class="uuid"></generator>        </id>        <property name="name" column="book_name"></property>        <property name="price" column="book_price"></property>        <!-- 指定数据类型 -->        <properties name="bookPage" column="book_page" type="int"></properties>    </class></hibernate-mapping>

测试类

package com.chb.model;import org.hibernate.Session;import com.chb.hbUtils.HibernateUtils;public class Test {    @org.junit.Test    public void test01() {        Session session = null;        //获取session        session = HibernateUtils.getSession();        //开启事务        session.beginTransaction();        Book book = new Book();        book.setName("西游记");        book.setPrice(23.0);        book.setBookPage(542);        //保存对象        session.save(book);        //提交事务        session.getTransaction().commit();    }}

可以看到表结构的变化,

这里写图片描述

正常情况下, 不会使用hibernate生成表,表的结构都会按照事先的设计结构,提前创建, 然后创建对象(book), 当数据表发生变化,才会使用hibernate表中自动生成。

我们通过来进行属性的映射。

二、关系映射,在我们实际应用中最重要的是关系映射

2.1、ManyToOne 在多的一方,进行管理

案例Student—-Classroom

2.1.1 实体类Classroom

package com.chb.model;public class Classroom {    private int id ;    //系名    private String name;    //年纪    private int grade;    public Classroom() {}    public Classroom(int id, String name, int grade) {        super();        this.id = id;        this.name = name;        this.grade = grade;    }    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 getGrade() {        return grade;    }    public void setGrade(int grade) {        this.grade = grade;    }}

对应的映射文件ClassRoom.hbm.xml

因为是manyToOne, 在多的一方管理对应关系。所以Classroom.hbm.xml只需定义Classroom的属性映射。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping        SYSTEM        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" ><!-- 映射对应的package --><hibernate-mapping package="com.chb.model">    <!-- 实体类Classroom与数据库中表t_classroom对应 -->    <class name="Classroom" table="t_classroom">        <id name="id" column="classroom_id">            <!-- 主键自增  -->            <generator class="native"></generator>        </id>        <property name="name" column="classroom_name"></property>        <!-- type指定数据类型 -->        <property name="grade" column="classroom_grade" type="int"></property>    </class></hibernate-mapping>

2.1.2 实体类Student, 多的一方

在多的一方(Student)添加“一”(Classroom)作为属性

package com.chb.model;public class Student {    private int id;    private String name;    private String no;    //在多的一方添加“一”作为属性    private Classroom classroom;    public Student() {}    public Student(int id, String name, String no) {        super();        this.id = id;        this.name = name;        this.no = no;    }    public void setClassroom(Classroom classroom) {        this.classroom = classroom;    }    public Classroom getClassroom() {        return classroom;    }    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 getNo() {        return no;    }    public void setNo(String no) {        this.no = no;    }}

Student的映射文件中管理关系

在many-to-one标签中定义在多的一方管理关系 name为Student中定义的classroom对象, column 为外键

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping        SYSTEM        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" ><!-- 映射对应的package --><hibernate-mapping package="com.chb.model">    <!-- 实体类Student与数据库中表t_student对应 -->    <class name="Student" table="t_student">        <id name="id" column="student_id">            <!-- 主键自增  -->            <generator class="native"></generator>        </id>        <property name="name" column="student_name"></property>        <property name="no" column="student_no"></property>        <!-- 在多的一方管理关系  name为Student中定义的classroom对象, column 为外键-->        <many-to-one name="classroom" column="cid">        </many-to-one>    </class></hibernate-mapping>

hibernate.cfg.xml中引入映射文件。

<!-- ~ Hibernate, Relational Persistence for Idiomatic Java ~ ~ License:     GNU Lesser General Public License (LGPL), version 2.1 or later. ~ See the     lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. --><!DOCTYPE hibernate-configuration PUBLIC        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory>        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>        <property name="connection.url">jdbc:mysql://localhost:3307/hibernate</property>        <property name="connection.username">root</property>        <property name="connection.password">root</property>        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>        <property name="show_sql">true</property>        <property name="format_sql">true</property>        <!-- 第一次加载 hibernate 时根据实体类自动建立表结构,以后自动更新表结构 -->        <property name="hibernate.hbm2ddl.auto">update</property>        <!-- 映射文件 -->        <mapping resource="com/chb/model/Student.hbm.xml" />        <mapping resource="com/chb/model/Classroom.hbm.xml" />    </session-factory></hibernate-configuration>

2.2测试

2.2.1 添加测试

首先添加“一”的一方(Classroom对象)

package com.chb.model;import org.hibernate.Session;import com.chb.hbUtils.HibernateUtils;public class Test {    @org.junit.Test    public void test01() {        Session session = null;        //获取session        session = HibernateUtils.getSession();        //开启事务        session.beginTransaction();        Classroom classroom = new Classroom();        classroom.setName("计算机系");        classroom.setGrade(1);        Student stu1 =new Student();        stu1.setName("猴子");        stu1.setNo("5401");        Student stu2 =new Student();        stu2.setName("肥猪");        stu2.setNo("5402");        stu1.setClassroom(classroom);        stu2.setClassroom(classroom);        //保存对象        session.save(classroom);        session.save(stu1);        session.save(stu2);        //提交事务        session.getTransaction().commit();    }}

2.2.2测试load

这里写图片描述

3、设置自动关联cascade

3.1、默认不适用级联, Student.hbm.xml

这里写图片描述

3.1.2、添加测试, 注意: Classroom对象没有save, 还是瞬时对象。

这里写图片描述

3.1.3、测试结果报错

由于我们的Classroom对象是一个瞬时对象, 数据库中是没有的, 当插入Student时,要关联外键, 发现没有classroom对象, 所以无法添加。

这里写图片描述

3.2、设置级联:在多的一方设置cascade关联,修改Student.hbm.xml

这里写图片描述

3.2.1、再次执行添加, 会成功, 因为, cascade会自动的创建一个关联对象。

3.3、执行删除操作, 又会报错

因为, 我们在删除Student(7)的时候,它会自动关联Classroom(3), 尝试删除Classroom(3), 但是Student(8)也关联Classroom(3), 这时候删除操作就不会成功。

这里写图片描述

3.4最佳实践

这里写图片描述

原创粉丝点击