hibernate的映射关系之一对多

关系:事物之间相互作用、相互联系的状态。范围最大。

联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。

关联:表示对象之间的关系,既有数量性,又有方向性;动词:将对象之间通过某种方式联系起来。

映射:这里指java对象和数据库表的一种对应关系。动词:形成这种对应关系。

级联:有关系的双方中操作一方,另一方也将采取一些动作。

关联的联系种类

在不考虑关联的方向前提下,联系就是关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。

一对一联系(1:1):如用户和身份证、一夫一妻

一对多联系(1:n):如班级和学生

多对多联系(m:n):如学生和选课

关联的方向

关联关系的方向可分为单向关联和双向关联。

双向关联的方向其实就不重要了,因为通过任一一方都可以维护彼此的关系。也就是说:在双向关联中一对多和多对一都是一样的。

利用Java Project项目演示试用Hibernate技术添加数据到数据库


1 建立项目之后首先呢肯定是需要导入相关的JAR包的

2 然后是创建实体类

package cn.itcast.hiberate.sh.domain;

public class Student {
    private Long sid;
    private String sname;
    private String description;
    public Long getSid() {
        return sid;
    }
    public void setSid(Long sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", description="
                + description + "]";
    }

}
package cn.itcast.hiberate.sh.domain;

import java.util.Set;

public class Classes {
    private Long cid;
    private String cname;
    private String description;
    private Set<Student> students;
    public Long getCid() {
        return cid;
    }
    public void setCid(Long cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Set<Student> getStudents() {
        return students;
    }
    @Override
    public String toString() {
        return "Classes [cid=" + cid + ", cname=" + cname + ", description="
                + description + ", students=" + students + "]";
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }

}

Student映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name的值代表的是一个实体 -->
    <class name="cn.itcast.hiberate.sh.domain.Student">
        <!-- id用于指定主键  column,主键在数据库表列 ,  increment,主键自增 -->
        <!-- length,指定长度 type,类型,也可以不写 -->
        <id name="sid" length="5" type="java.lang.Long">
            <generator class="increment"></generator>
        </id>
        <!-- 表示表中普通的属性 -->
        <property name="sname" length="20" type="java.lang.String"></property>
        <property name="description" length="100" type="java.lang.String"></property>
    </class>
</hibernate-mapping>

Class映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name的值代表的是一个实体 -->
    <class name="cn.itcast.hiberate.sh.domain.Classes">
        <!-- id用于指定主键  column,主键在数据库表列 ,  increment,主键自增 -->
        <!-- length,指定长度 type,类型,也可以不写 -->
        <id name="cid" length="5" type="java.lang.Long">
            <generator class="increment"></generator>
        </id>
        <!-- 表示表中普通的属性 -->
        <property name="cname" length="20" type="java.lang.String"></property>
        <property name="description" length="100" type="java.lang.String"></property>
        <!-- set元素和实体类中的 private Set<Student> students; 相对应 -->
        <!--
            set元素对应类中的set集合
            通过set元素使classes表与student表建立关联
               key是通过外键的形式让两张表建立关联
               one-to-many是通过类的形式让两个类建立关联

            cascade 级联
               save-update
                   1、当 保存班级的时候,对学生进行怎么样的操作
                        如果学生对象在数据库中没有对应的值,这个时候会执行save操作
                        如果学生对象在数据库中有对应的值,这个时候会执行update操作
               delete
               all
            inverse  维护关系
               true      不维护关系
               false     维护关系
               default   false
         -->
        <set name="students" cascade="save-update">
            <!--
                key是用来描述外键
             -->
            <key column="cid"></key>
            <one-to-many class="cn.itcast.hiberate.sh.domain.Student"/>
        </set>
    </class>
</hibernate-mapping>

3 然后是配置文件 hibernate.cfg.xml

<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!--
        一个session-factory只能连接一个数据库
    -->
<session-factory>
    <!--
        数据库的用户名
    -->
    <property name="connection.username">root</property>
    <!--
        密码
    -->
    <property name="connection.password">root</property>
    <!--
        url
    -->
    <property name="connection.url">
        jdbc:mysql://localhost:3306/itcast_sh_hibernate
    </property>
    <!--
        作用:根据持久化类和映射文件生成表
        validate
        create-drop
        create
        update
    -->
    <property name="hbm2ddl.auto">update</property>
    <!--
        显示hibernate内部生成的sql语句
    -->
    <property name="show_sql">true</property>
    <mapping resource="cn/itcast/hiberate/sh/domain/Classes.hbm.xml" />
    <mapping resource="cn/itcast/hiberate/sh/domain/Student.hbm.xml" />

</session-factory>
</hibernate-configuration>

4 hibernate创建 sessionfactory 的工具类

package cn.itcast.hibernate.sh.utils;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Before;

public class HibernateUtils {
    public static SessionFactory sessionFactory;
    public static String url;
    // 需要在加载的时候就进行配置
    @Before
    public void init(){
        // 创建 Configuration 对象
        Configuration configuration = new Configuration();
        // 加载配置文件
        configuration.configure(url);
        sessionFactory = configuration.buildSessionFactory();
    }
}

5 测试类   需要注意的是,hibernate 可以创建相对应的表,但是 数据库需要自己先创建好

package cn.itcast.hibernate.sh.test;

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

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hiberate.sh.domain.Classes;
import cn.itcast.hiberate.sh.domain.Student;
import cn.itcast.hibernate.sh.utils.HibernateUtils;

public class TestOneToMany extends HibernateUtils{
    static{
        url="/hibernate.cfg.xml";
    }
    // 建表
    @Test
    public void  testCreateTable(){

    }
    // 创建一个班级
    /**
     * Hibernate: select max(cid) from Classes
       Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
     */
    @Test
    public void save_classes(){
        Session session = sessionFactory.openSession();
        // 除了查询之外的操作都需要使用事务
        Transaction transaction = session.beginTransaction();
        Classes classes = new Classes();
        classes.setCname("峡谷1");
        classes.setDescription("召唤师峡谷");
        session.save(classes);     // 将临时状态的对象转换成持久化状态
        transaction.commit();
        session.close();
    }
    // 创建一个学生
    /**
     * Hibernate: select max(sid) from Student
       Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
     */
    @Test
    public void save_student(){
        // session 的实质可以看为一个数据库连接
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("黑铁");
        student.setDescription("菜");
        session.save(student);
        transaction.commit();
        session.close();
    }
    // 创建一个班级的时候同事创建一个学生,级联同时维护关系所以student表的外键也有值了
    /**
     *  Hibernate: select max(cid) from Classes
        Hibernate: select max(sid) from Student
        Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
        Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
        Hibernate: update Student set cid=? where sid=?
     */
    @Test
    public void saveClasses_cacade_saveStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = new Classes();
        classes.setCname("峡谷2");
        classes.setDescription("召唤师峡谷2");
        Student student = new Student();
        student.setSname("白银呢");
        student.setDescription("还是菜");
        Set<Student> students = new HashSet<Student>();
        students.add(student);
        classes.setStudents(students);
        session.save(classes);
        transaction.commit();
        session.close();
    }
    // 存在一个班级,新建一个学生
    /**
     *  Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_,
     *  classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
        Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_,
        students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
        Hibernate: select max(sid) from Student
        Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
        Hibernate: update Student set cid=? where sid=?
     */
    @Test
    public void test_classes_saveStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes) session.get(Classes.class, 4L);
        Student student = new Student();
        student.setSname("白白");
        student.setDescription("有点菜");
        // classes 是持久化状态 可以直接添加
        classes.getStudents().add(student);
        session.save(classes);
        transaction.commit();
        session.close();
    }
    // 存在一个学生,新建一个班级
    /**
     *  Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_,
     *  student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
        Hibernate: select max(cid) from Classes
        Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
        Hibernate: update Student set cid=? where sid=?
     */
    @Test
    public void test_student_saveClasses(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = (Student) session.get(Student.class, 1L);
        Classes classes = new Classes();
        classes.setCname("峡谷3");
        classes.setDescription("召唤师峡谷3");
        Set<Student> students = new HashSet<Student>();
        students.add(student);
        classes.setStudents(students);
        // 临时状态的 classes 需要 save
        session.save(classes);
        transaction.commit();
        session.close();
    }
    // 存在一个 班级和学生 ,将其建立连接
    /**
     *  Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_,
     *  classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
        Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_,
        student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
        Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_,
         students0_.sname as sname1_0_, students0_.description as descript3_1_0_
         from Student students0_ where students0_.cid=?
        Hibernate: update Student set cid=? where sid=?

     */
    @Test
    public void updateClasses_cascade_updateStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes) session.get(Classes.class, 2L);
        Student student = (Student) session.get(Student.class, 5L);
        classes.getStudents().add(student);
        transaction.commit();
        session.close();
    }
    // 把一个学生从一个班级解除关系
    /**
     *  Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_,
     *  classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
        Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_,
        students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description
         as descript3_1_0_ from Student students0_ where students0_.cid=?
        Hibernate: update Student set cid=null where cid=? and sid=?
     */
    @Test
    public void test_release(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes) session.get(Classes.class, 2L);
        Set<Student> students = classes.getStudents();
        for(Student s : students){
            if(s.getSid() == 5){
                students.remove(s);
            }
        }
        // 解除了学生5的关系
        transaction.commit();
        session.close();
    }
    // 解除一个班级下面的一些学生的关系
    @Test
    public void test_releaseR(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes) session.get(Classes.class, 2L);
        Set<Student> students = classes.getStudents();
        for(Student s : students){

                students.remove(s);

        }
        // 解除了班级2下面的关系
        transaction.commit();
        session.close();
    }
    // 删除学生
    /**
     * Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_,
     * student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
       Hibernate: delete from Student where sid=?
     */
    @Test
    public void testDelete(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = (Student) session.get(Student.class, 5L);
        session.delete(student);
        transaction.commit();
        session.close();
    }
    // 删除班级
    /**
     *  Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
        Hibernate: update Student set cid=null where cid=?
        Hibernate: delete from Classes where cid=?
        删除班级的同时级联删除了 学生表中相应的外键
     */
    @Test
    public void test_deleteClasses(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes) session.get(Classes.class, 5L);
        session.delete(classes);
        transaction.commit();
        session.close();
    }
}

用于记忆整理,欢迎各位大神来指点

时间: 2024-11-03 01:40:00

hibernate的映射关系之一对多的相关文章

Hibernate基数映射关系

Hibernate基数映射关系 一.基数映射——一对一关系映射 每个账户对应一个地址的数据库关系为例: 1.SQL脚本:    -- 一对一(唯一外键)    drop table t_addr;    drop table t_act;    create table t_act(       id int primary key auto_increment,       actNo varchar(50) not null unique,       passwd varchar(50)

Hibernate映射关系之一对多

1.双边使用的比较多,所以这里用双边的一对多:一个商店包含多个优惠券,一个优惠券对应一个商店 Store.java(商店) @OneToMany(mappedBy="store",cascade = {CascadeType.REMOVE }) private Set<Coupon> coupons=new HashSet<Coupon>(); (1)mappedBy="store"是在Coupon类中的Store的变量名称 (2)Casca

Hibernate4.x之映射关系--单向一对多

在领域模型中,类与类之间最普遍的关系就是关联关系在UML中,关联是有方向的 以Customer和Order为例:一个用户能发出多个订单,而一个订单只能属于一个客户.从Order到Customer的关联是多对一关联:而从Customer到Order是一对多关联 单向n-1 单向n-1关联只需从n的一端可以访问到1的一端 域模型:从Order到Customer的多对一单向关联需要在Order类中定义一个Customer属性,而在Customer类中无需定义存放Order对象的集合属性 关系数据模型:

Hibernate关联映射关系

一.双向一对多关联映射关系:当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象(一对多双向关联和多对一双向关联是完全一样的) 1.1创建实体类(Emp(员工),Dept(部门)) /* * 员工实体类 */public class Emp { private Integer empId; //员工编号 private String empName; //员工姓名 private Dept dept; //所处部门 //get(),set()方法省略 } /* * 部

Hibernate One2Many映射关系

多对一映射与一对多映射: 使用部门和员工的关系来说明问题.一个部门可以有多个员工,但是一个员工只属于一个部门. 开发步骤: (1)JavaBean的设计,Dept(部门表) Employee(员工表) (2)映射关系 (3)测试 1.Dept和Employee Javabean Dept package cn.itcast.one2many; import java.util.HashSet; import java.util.Set; public class Dept { private i

hibernate annotation映射关系详解

在hibernate中处理关系映射的方法有两种.一种是使用传统的xml来处理它们的映射关系,另一种是基于annotation的注解方式.我个人非常喜欢使用annotation,觉得这种方式显得更加的简洁,大大减少工作量.在hibernate4中annotation包无需再引入,因为已经集成了annotation包. 在讲hibernate annotation之前,我们先回想一下.在数据库创建表的时候有几个关键点是必须的.表名.字段名.字段类型.约束条件.从这些点出发我们来看看一个hiberna

Hibernate many2many映射关系

多对多映射关系: 开发步骤: JavaBean 映射文件  测试 图片详解: 1.javaBean  Project.java package cn.itcast.many2many; import java.util.HashSet; import java.util.Set; public class Project { private int proj_id; @Override public String toString() { return "Project [proj_id=&qu

Hibernate对象映射关系:一对一

一:项目截图 二:业务代码 package com.cloud.domain; import java.util.Date; public class IdCard { private Integer id; private Date validateDte; private Person person; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Dat

Hibernate对象映射关系:多对一

一:项目截图 二:业务代码 package com.cloud.domain; import java.util.Set; public class Department implements java.io.Serializable{ /** * 实现java.io.Serializable 接口的类是可序列化的. * 没有实现此接口的类将不能使它们的任一状态被序列化或逆序列化. */ private static final long seriaVersionUID = 1L; privat