hibernate入门(七)关联关系讨论_多对一关系映射

1多对一关系映射

一个部门有可以有多个员工,而一个员工只属于一个部门。从员工角度看,很多员工会隶属一个部门。 现以实例说明,实例概要:一个部门类,只有id 和部门名称两个属性。有一个员工类,有id 和员工名称及部门对象三个属性。操作步骤如下:

>> 步骤一,建立Depatment.java 及实体配置文件:

package com.asm.hibernate.domain;

public class Department {

    private int id ;

    private String name ;

    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;

    }  

}

---- 同包下的实体配置文件: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 >

以上的操作,没的什么可多言的,和前面的配置是一样的形式。

>> 步骤二, 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;

    }

}

---- 同包下的实体配置文件: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 >
先来说这个类文件 ,它的一个重要属性就是 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();

       }

    }

}

说明:以前插入新的记录,都要传递一个实体对象,而这里没有这么做,原因是为了体现出一个插入记录的顺序问题,仔细观察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 ();

       }

    }

随后再在主方法中增加如下内容:便可以测试结果:

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();

       }

    }

main 方法中增加如下内容进行测试:

Employee emp = query2 (1);

System. out .println(emp.getDepart().getName());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值