Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 332|回复: 0

[Java框架学习]Hibernate学习:多对一

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-3 00:00:07 | 显示全部楼层 |阅读模式
    关联关系讨论 1.多对一关系映射:    一个部门有可以有多个员工,而一个员工只属于一个部门。从员工角度看,很多员工会隶属一个部门。 现以实例说明,实例概要:一个部门类,只有id和部门名称两个属性。有一个员工类,有id和员工名称及部门对象三个属性。操作步骤如下: >>步骤一,建立Depatment.java及实体配置文件: package com.asm.hibernate.domain;
    public class Department {
         private int id ;
         private String name;
         public int getId() { return id;
    }

       
      
       
       
         
       

         
       
      

    同包下的实体配置文件:Depart.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.asm.hibernate.domain">
            <class name="Department">
                    <id name="id">
                            <generator class="native" />
                    </id>
                    <property name="name"></property>
            </class>
    </hibernate-mapping>
                      [/code] 以上的操作,没的什么可多言的,和前面的配置是一样的形式。 >>步骤二,Employee.java内容如下及实体配置文件   package com.asm.hibernate.domain;
    public class Employee {
            private int id;
            private String name;
            private Department depart;
            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 Department getDepart() {
                    return depart;
            }
            public void setDepart(Department depart) {
                    this.depart = depart;
            }
    }
                      [/code] 同包下的实体配置文件:Employee.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.asm.hibernate.domain">

            <class name="Employee">
                    <id name="id">
                            <generator class="native" />
                    </id>
                    <property name="name"></property>
                    <many-to-one name="depart" column="depart_id" />
            </class>
    </hibernate-mapping>[/code] 先来说这个类文件,它的一个重要属性就是Department对象,这就是它所关联的一个外键,这里我们只必须记住一点,每个实体类对应于一张表,如果一张表想关联另一张表,则只需要在这张表所对应的实体类中引入它想关联表的实体类对象。再进行简单的配置即可。再来看配置文件,这里主要看这个
    <many-to-one name="depart" column="depart_id"></many-to-one>
    元素,它的name属性仍然是实体类中的属性。column为对应表的外键。可以留意下数据库表中的相关表。
      >>步骤三:
    修改主配置文件,增加以下内容以便找到相应的实体配置文件。 <mapping resource="com/dep/emp/Employee.hbm.xml"/>??  <mapping resource="com/dep/emp/Depart.hbm.xml"/>
      >>步骤四,编写测试类。类中省略导入包的内容。 package com.asm.hibernate.test;
    public class ManyToOneTest {
            public static void main(String[] args) {
                    add();
            }
            static void add() {
                    Session s = null;
                    Transaction tx = null;
                    try {
                            Department depart = new Department();
                            depart.setName("departName");
                            Employee emp = new Employee();
                            emp.setName("empName");
                            emp.setDepart(depart);

                            s = HibernateUtil.getSession();
                            tx = s.beginTransaction();

                            s.save(depart);
                            s.save(emp);
                    // 交换以上两句的位置,看Hibernate执行的sql语句。会再增加一条更新操作。
                            tx.commit();
                    } finally {
                            if (s != null)
                                    s.close();
                    }
            }
    }
                      [/code] 说明:
    以前插入新的记录,都要传递一个实体对象,而这里没有这么做,原因是为了体现出一个插入记录的顺序问题,仔细观察add()方法,发现先保存的是Department对象,再保存的是Employee对象,原因是什么?这里略作说明,我们知道此项目设计的是让Employee表来关联Department表,而要想关联此表,必须保证此表已进行存储,这里暂时这样理解,也可以试试颠倒save方法的顺序,或是不保存depart来看看效果,这样也许有助理解。
      简要说明,以上提到的尝试性操作:颠倒顺序,可以通过,只是增加了一条更新操作;不保存dep则不能通过,原因是此实体对象没有保存;再测试,如果注释掉“depart.setDname("deptName");”后面按正常顺序执行,发现是能正确执行的。只是在数据库的employee表中depart_id字段为null,如果我们在前面设置<many-to-one name="depart" column="depart_id">中增加:not-null="true"这个属性,再来执行将会报“不能为空的错误”。通过增加这个属性,可以让我们更好理解如何建立两个对象的关联。
      >>步骤五,再探查询方法。接上面,在测试类中增加一个查询方法,内容如下: static Employee query(int empId) {
                    Session s = null;
                    try {
                            s = HibernateUtil.getSession();
                            Employee emp = (Employee) s.get(Employee.class, empId);
                            System.out.println("Department Name:" + emp.getDepart().getName());
                            return emp;
                    } finally {
                            if (s != null)
                                    s.close();
                    }
            }
    [/code] 随后再在主方法中增加如下内容:便可以测试结果: query(1); 对结果的说明分析:如果在以往的JDBC操作中,我们想得到这个部门的信息,需要查两次才能得到,这里的 Hibernate就实现了这一优化,如果我们开启了控制台的数据库显示功能(主配置文件中开启,前面已提到),便可以查看下数据库的执行操作,并切实感受到这里实际执行了两步查询操作,在以后的操作中,建议开启此属性,以便切实体会数据库操作。
      >>步骤六,增加一个新的查询方法query2,内容如下,注意和query区别: static Employee query2(int empId) {
                    Session s = null;
                    try {
                            s = HibernateUtil.getSession();
                            Employee emp = (Employee) s.get(Employee.class, empId);
                            Hibernate.initialize(emp.getDepart());
                            //上一句作用后面会作说明,这里略作了解
                            return emp;
                    } finally {
                            if (s != null)
                                    s.close();
                    }
            }
                      [/code] 在main方法中增加如下内容进行测试:   Employee emp = query2(1);

    System.out.println(emp.getDepart().getName());
                     
    [/code]  

      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/3/000007421.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 16:31 , Processed in 0.296079 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表