关联是类(类的实例)之间的关系,表示有意义和值得关注的连接。

本系列将介绍Hibernate中主要的几种关联映射

Hibernate一对一主键单向关联
Hibernate一对一主键双向关联
Hibernate一对一外键单向关联
Hibernate一对一外键双向关联
Hibernate多对一单向关联
Hibernate多对一双向关联

Hibernate多对多关联

代码都写有注释,主要包括(核心配置文件,实体映射文件,实体类,测试类,数据库)主要操作有增删改查。

本篇主要介绍Hibernate多对一单向关联:

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>
      <!-- 配置数据库连接驱动类 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 配置数据库连接字符串 -->
        <property name="connection.url"><![CDATA[jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8]]></property>
        <!-- 配置数据库连接用户名 -->
        <property name="connection.username">root</property>
        <!-- 配置数据库连接密码 -->
        <property name="connection.password">123456</property>
        <!-- 配置数据库方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 配置数据库表生成策略 -->
        <!--<property name="hibernate.hbm2ddl.auto">update</property> -->
        <!-- 配置是否打印显示SQL语句 -->
        <property name="show_sql">true</property>
        <!-- 配置是否格式化显示SQL语句 -->
        <property name="format_sql">true</property>
        <!-- 配置hibernate是否自动提交事务 -->
        <!--<property name="hibernate.connection.autocommit">true</property> -->
        <!-- 配置实体类对应的映射文件 -->

        <!-- 多对一双向关联配置 -->
        <mapping resource="com/great/entity/Class.hbm.xml"></mapping>
        <mapping resource="com/great/entity/Student.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

Student.hbm.xml

<?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 package="com.great.entity">
    <!-- 配置实体类与数据库表的映射关系 -->
    <class name="Student" table="student">
        <!-- 配置主键映射关系 -->
        <id name="id" column="sId" type="int">
            <!-- 配置主键生成策略 -->
            <generator class="identity">
            </generator>
        </id>
        <!-- 配置属性和表字段映射关系 -->
        <property name="sName" column="sName" type="string"></property>
        <!-- 多对一关联关系配置 -->
        <!-- many-to-one标签声明多对一关联关系,name指定多方所维护的一方的实例名 -->
        <many-to-one name="classes" class="com.great.entity.Class"
            cascade="save-update">
            <!-- column标签指定关联外键,还是子表的外键列名 -->
            <column name="cId"></column>
        </many-to-one>
    </class>
</hibernate-mapping>

Class.hbm.xml

<?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 package="com.great.entity">
    <class name="Class" table="class">
        <!-- 配置主键映射关系 -->
        <id name="cId" column="cId" type="int">
            <!-- 配置主键生成策略 -->
            <generator class="identity">
            </generator>
        </id>
        <!-- 配置属性和表字段映射关系 -->
        <property name="cName" column="cName" type="string"></property>
        <!-- 一对多关联关系配置 -->
        <!-- inverse属性设置为true代表一的一方不在拥有关联关系的控制权,而把控制权交给多的一方 -->
        <!-- fetch属性用来指定子表数据的抓取策略,默认值为"select",代表对主表子表进行单独查询 ,对主表子表单独发select语句 -->
        <!-- fetch属性用来指定子表数据的抓取策略,设置为"join"时,代表对主表子表进行关联查询,对主表子表发出关联查询语句 -->
        <!-- lazy属性用来指定子表数据是否延迟加载,fetch="select"时起作用,fetch="join"时不起作用 -->
        <!-- fetch="select" lazy="true" -->
        <set name="students" cascade="all" inverse="true">
            <!-- key配置的是子表的外键列名 -->
            <key column="cId"></key>
            <!-- one-to-many标签声明关联关系是一对多,class指定多方的实体类类型 -->
            <one-to-many class="com.great.entity.Student" />
        </set>
    </class>
</hibernate-mapping>

Student.java

package com.great.entity;

import com.great.entity.Class;

public class Student {

    private int id;
    private String sName;
    // 多对一映射时,因为要维护一的一方的实例,所以外键不需要映射
    // private int cId;
    private Class classes;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getsName() {
        return sName;
    }

    public void setsName(String sName) {
        this.sName = sName;
    }

    public Class getClasses() {
        return classes;
    }

    public void setClasses(Class classes) {
        this.classes = classes;
    }

}

Class.java

package com.great.entity;

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

import com.great.entity.Student;

public class Class {
    // 班级id
    private int cId;
    // 班级名字
    private String cName;
    // 注意点:必须new一个Set的实现类的实例
    // 原因:子表不一定有主表的关联数据,所以可能取出空集合,引发空指针异常
    private Set<Student> students = new HashSet<Student>();

    public int getcId() {
        return cId;
    }

    public void setcId(int cId) {
        this.cId = cId;
    }

    public String getcName() {
        return cName;
    }

    public void setcName(String cName) {
        this.cName = cName;
    }

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "Class [cId=" + cId + ", cName=" + cName + ", students="
                + students + "]";
    }

}

TestManyToOneBoth.java

package com.great.test;

import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.great.entity.Class;
import com.great.entity.Student;

public class TestManyToOneBoth {
    static Session session;

    // 多对一双向关联
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // 加载hibernate主配置文件
        Configuration cfg = new Configuration().configure();
        // 构建session工厂
        SessionFactory sf = cfg.buildSessionFactory();
        // 打开session
        session = sf.openSession();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        // 关闭session,释放资源
        session.close();
    }

    // select1, 通过class查询到student
    @Test
    public void testManyToOneBothSelect1() {
        Class c = (Class) session.get(Class.class, 5);
        System.out.println("班级为:" + c.getcName());
        System.out.println("cId:" + c.getcId());
        Set<Student> students = c.getStudents();
        Iterator<Student> it = students.iterator();
        while (it.hasNext()) {
            Student student = (Student) it.next();
            System.out.println("学生姓名:" + student.getsName());
        }
    }

    // select2, 通过student查询到class
    @Test
    public void testManyToOneBothSelect2() {
        Student s = (Student) session.get(Student.class, 3);
        System.out.println("学生名字为:" + s.getsName());
        System.out.println("班级为:" + s.getClasses().getcName());
    }

    // insert1,通过class保存数据,一条insert class.两条insert student
    @Test
    public void testManyToOneBothSave1() {

        Transaction ts = session.beginTransaction();
        Class c = new Class();
        c.setcName("通信2班");
        Student s1 = new Student();
        Student s2 = new Student();
        s1.setsName("学员1");
        s2.setsName("学员2");
        c.getStudents().add(s1);// 必须加
        c.getStudents().add(s2);// 必须加
        s1.setClasses(c);
        s2.setClasses(c);
        session.save(c);
        ts.commit();
    }

    // insert2,通过student保存数据,一条insert class.两条insert student
    @Test
    public void testManyToOneBothSave2() {
        Transaction ts = session.beginTransaction();
        Class c = new Class();
        c.setcName("硬件3班");
        Student s1 = new Student();
        Student s2 = new Student();
        s1.setsName("学员3");
        s2.setsName("学员4");
        c.getStudents().add(s1);// 可加可不加
        c.getStudents().add(s2);// 可加可不加
        s1.setClasses(c);
        s2.setClasses(c);
        session.save(s1);
        session.save(s2);
        ts.commit();
    }

    // delete1数据,仅仅删除student,cascade="save-update"[因为是多对一] 发出一条select ,一条delete
    @Test
    public void testManyToOneDelete1() {
        Transaction ts = session.beginTransaction();
        Student student = (Student) session.get(Student.class, 17);
        session.delete(student);
        ts.commit();
    }

    /*
     * delete2数据,通过删除class,把与class以及class相关的student全部删除,先删student,再删class,发出两条select
     * ,两条delete,在class配置文件中配置cascade="all"
     */
    @Test
    public void testManyToOneDelete2() {
        Transaction ts = session.beginTransaction();
        Class classes = (Class) session.get(Class.class, 2);
        session.delete(classes);
        ts.commit();
    }

    // 更新数据1,通过student进行更新
    @Test
    public void testManyToOneUpdate1() {
        Transaction ts = session.beginTransaction();
        Student student = (Student) session.get(Student.class, 2);
        student.setsName("小哥");
        student.getClasses().setcName("设计二班");
        session.saveOrUpdate(student);
        ts.commit();
    }

    // 更新数据2,通过class进行更新
    @Test
    public void testOneToOneUpdate2() {
        Transaction ts = session.beginTransaction();
        Class classes = (Class) session.get(Class.class, 11);
        classes.setcName("工业设计五班");
        Set<Student> students = classes.getStudents();
        Iterator<Student> it = students.iterator();
        while (it.hasNext()) {
            Student student = (Student) it.next();
            System.out.println("学生姓名:" + student.getsName());
            if ("吴邪".equals(student.getsName())) {
                student.setsName("吴小邪");
            }
        }
        ts.commit();
    }
}

数据库:

student表

三个字段 sId sName cId(外键)

class表

两个字段  cId cName

注意:在student表的cId上建立外键关系。

hibernate多对一双向关联的更多相关文章

  1. Java进阶知识12 Hibernate多对多双向关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.应用场景(Student-Teacher):当学生知道有哪些老师教,老师也知道自己教哪些学生时,可用双向关联 1.2.创建Teacher类和Student类 ...

  2. Hibernate多对多双向关联的配置

    Hibernate的双向多对多关联有两种配置方法:那我们就来看看两种方案是如何配置的.  一.创建以各自类为类型的集合来关联 1.首先我们要在两个实体类(雇员<Emploee>.工程< ...

  3. Hibernate多对多双向关联

    以Student和Course为例,一个学生可以选多门课程,一门课程也可以被多个学生选取: 持久化类Student: package bean; import java.util.Set; publi ...

  4. Hibernate多对多双向关联需要注意的问题(实例说话)

    以Student和Course为例,一个学生可以选多门课程,一门课程也可以被多个学生选取: 持久化类Student: package bean; import java.util.Set; publi ...

  5. hibernate 多对多双向关联

    package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax.persistenc ...

  6. Java进阶知识10 Hibernate一对多_多对一双向关联(Annotation+XML实现)

    本文知识点(目录): 1.Annotation 注解版(只是测试建表)    2.XML版 的实现(只是测试建表)    3.附录(Annotation 注解版CRUD操作)[注解版有个问题:插入值时 ...

  7. hibernate多对一单向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  8. Java进阶知识11 Hibernate多对多单向关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.应用场景(Student-Teacher):当学生知道有哪些老师教,但是老师不知道自己教哪些学生时,可用单向关联 1.2.创建Teacher类和Student ...

  9. Java进阶知识08 Hibernate多对一单向关联(Annotation+XML实现)

    1.Annotation 注解版 1.1.在多的一方加外键 1.2.创建Customer类和Order类 package com.shore.model; import javax.persisten ...

随机推荐

  1. Hibernatel框架关联映射

    Hibernatel框架关联映射 Hibernate程序执行流程: 1.集合映射 需求:网络购物时,用户购买商品,填写地址 每个用户会有不确定的地址数目,或者只有一个或者有很多.这个时候不能把每条地址 ...

  2. SQLSERVER走起 APP隆重推出

    SQLSERVER走起 APP隆重推出 为方便大家查看本微信公众以前推送的文章,QQ群里面的某位SQLSERVER重度爱好者开发了<SQLSERVER走起>的APP 以供大家一起交流 网页 ...

  3. 有朋友问了数据库ID不连续,怎么获取上一篇和下一篇的文章?(不是所有情况都适用)

    呃 (⊙o⊙)…,逆天好久没写SQL了,EF用的时间长了,SQL都不怎么熟悉了......[SQL水平比较菜,大牛勿喷] 方法很多种,说个最常见的处理 因为id是自增长的,所以一般情况下下一篇文章的I ...

  4. 开始学nodejs——net模块

    net模块的组成部分 详见 http://nodejs.cn/api/net.html 下面整理出了整个net模块的知识结构,和各个事件.方法.属性的用法 net.Server类 net.Socket ...

  5. .NET应用和AEAI CAS集成详解

    1 概述 数通畅联某综合SOA集成项目的统一身份认证工作,需要第三方系统配合进行单点登录的配置改造,在项目中有需要进行单点登录配置的.NET应用系统,本文专门记录.NET应用和AEAI CAS的集成过 ...

  6. 【转】外部应用和drools-wb6.1集成解决方案

    一.手把手教你集成外部应用和drools workbench6.1 1.         首先按照官方文档安装workbench ,我用的是最完整版的jbpm6-console的平台系统,里面既包含j ...

  7. 一些关于Linux入侵应急响应的碎碎念

    近半年做了很多应急响应项目,针对黑客入侵.但疲于没有时间来总结一些常用的东西,寄希望用这篇博文分享一些安全工程师在处理应急响应时常见的套路,因为方面众多可能有些杂碎. 个人认为入侵响应的核心无外乎四个 ...

  8. Android——eclipse下运行android项目报错 Conversion to Dalvik format failed with error 1解决

    在eclipse中导入android项目,项目正常没有任何错误,但是运行时候会报错,(clean什么的都没用了.....)如图: 百度大神大多说是jdk的问题,解决: 右键项目-Properties如 ...

  9. Linux下用netstat查看网络状态、端口状态(转)

    转:http://blog.csdn.net/guodongdongnumber1/article/details/11383019 在linux一般使用netstat 来查看系统端口使用情况步.  ...

  10. 理解JavaScript中的“this”

    对于javascript的初学者来说,一般对“this”关键字都感到非常迷惑.本文的目的旨在让你全面的了解“this”,理解在每一个情景下如何使用“this”,希望通过本文,可以帮助同学们不在害怕“t ...