Hibernate关联映射之一对多,多对一以及双向一对多

来源:互联网 发布:淘宝客服要开通管理 编辑:程序博客网 时间:2024/05/20 06:30

在上篇博客我们讲了hibernate对单表的操作,本篇博客就来讲讲对多表的关联映射操作。首先我们拿来做例子的表为班级表1---n学生表,在这次的测试主键我用的是序列,创建代码如下:

--班级表drop table classes;create table classes(       cid int primary key,       cname varchar2(50));drop sequence seq_classes_cid;create sequence seq_classes_cid       START WITH 1000    -- 从1000开始计数        INCREMENT BY 1     -- 每次加1个--学生表drop table student;create table student(       sid int primary key,       sname varchar2(50),       cid int constraint FK_student_cid references classes(cid));drop sequence seq_student_sId;create sequence seq_student_sId       START WITH 1000    -- 从1000开始计数        INCREMENT BY 1     -- 每次加1个


对于使用hibernate我们都需要配置cfg文件,所以在此贴出我的cfg文件
<?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.username">hibernate</property><property name="connection.password">a</property><property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property><property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property><!-- 方言 --><property name="dialect">org.hibernate.dialect.OracleDialect</property><!-- 是否在运行的时候显示sql语句 --><property name="show_sql">true</property><!-- 显示的sql语句是否进行排版 --><property name="format_sql">true</property><!-- 表结构生成策略 --><property name="hbm2ddl.auto">update</property><!-- getCurrentSession所需的参数(本地事务) --><property name="hibernate.current_session_context_class">thread</property></session-factory></hibernate-configuration>

一对多的关联关系

1.首先我们需要编写学生和班级的实体类
package com.yc.entity;import java.io.Serializable;public class Student implements Serializable{private static final long serialVersionUID = 3914237588346266940L;private int sid;private String sname;public Student() {}public Student(String sname) {this.sname = sname;}public Student(int sid, String sname) {this.sid = sid;this.sname = sname;}public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public String toString() {return "Student [sid=" + sid + ", sname=" + sname + "]";}}
package com.yc.entity;import java.io.Serializable;import java.util.HashSet;import java.util.Set;public class Classes implements Serializable {private static final long serialVersionUID = 948637569053708320L;private int cid;private String cname;//在一方定义一个多方的集合 一对多private Set<Student> students=new HashSet<Student>();public Classes() {}public Classes(String cname) {this.cname = cname;}public Classes(int cid, String cname, Set<Student> students) {this.cid = cid;this.cname = cname;this.students = students;}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;}public String toString() {return "Classes [cid=" + cid + ", cname=" + cname + ", students="+ students + "]";}}

2.根据实体类创建对应的hbm文件
Student.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"><!-- Generated 2016-8-12 19:33:30 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="com.yc.entity.Student" table="STUDENT">        <id name="sid" type="int">            <column name="SID" />            <generator class="sequence" >            <param name="sequence">seq_student_sId</param>            </generator>        </id>        <property name="sname" type="java.lang.String">            <column name="SNAME" />        </property>    </class></hibernate-mapping>
Classes.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"><!-- Generated 2016-8-12 19:33:30 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="com.yc.entity.Classes" table="CLASSES">        <id name="cid" type="int">            <column name="CID" />            <generator class="sequence" >            <param name="sequence">seq_classes_cid</param>            </generator>        </id>        <property name="cname" type="java.lang.String">            <column name="CNAME" />        </property>        <!-- 配置单向的一对多关联关系 -->        <set name="students" table="STUDENT" inverse="false" lazy="true">        <!-- 指定关联的外键列 -->            <key>                <column name="CID" />            </key>            <one-to-many class="com.yc.entity.Student" />        </set>    </class></hibernate-mapping>

3.在cfg文件中加入映射路径
<!-- 测试一对多 --><mapping resource="Classes.hbm.xml" /><mapping resource="Student.hbm.xml" />

4.编写测试类测试
package com.yc.test;import java.util.Collections;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;import com.yc.entity.Classes;import com.yc.entity.Student;import com.yc.utils.HibernateUtil;public class MyTest {@Test//插入数据的测试public void testAdd() {Classes c=new Classes("龙宫");Student s1=new Student("龙太子");Student s2=new Student("玄彩娥");//如果希望在学生表中添加对应的班级编号,需要在班级中添加学生,建立关联关系Collections.addAll(c.getStudents(), s1,s2);Session session=HibernateUtil.getSession();Transaction transaction=session.beginTransaction();session.save(c);session.save(s1);session.save(s2);transaction.commit();HibernateUtil.closeSession(session);}@Test//查询班级中包含的学生public void testFind() {Session session=HibernateUtil.getSession();Classes c=(Classes) session.get(Classes.class, 1000);//建立关联关系后,可以方便的从一个对象导航到另一个对象System.out.println(c);}@Test//修改学生信息public void testUpdate() {Classes c=new Classes("普陀山");Session session=HibernateUtil.getSession();Transaction transaction=session.beginTransaction();Student s=(Student) session.get(Student.class, 1001);c.getStudents().add(s);session.save(c);transaction.commit();HibernateUtil.closeSession(session);}@Test//删除public void testDelete() {Session session=HibernateUtil.getSession();Transaction transaction=session.beginTransaction();Student s=(Student) session.get(Student.class, 1000);session.delete(s);transaction.commit();HibernateUtil.closeSession(session);}}

5.测试结果,在这里我只贴出testAdd方法的测试结果,其余方法小伙伴门可以自己尝试


多对一的关联关系

在这里其实我们只需改变实体类中的属性以及对应的hbm文件即可,其实多对一更加符合我们的数据库表的设计
1.实体类
package com.yc.entity;public class Student {private int sid;private String sname;private Classes cid; //多对一//在此就不贴出对应的set,get方法以及构造函数,toString方法}
package com.yc.entity;public class Classes {private int cid;private String cname;//在此就不贴出对应的set,get方法以及构造函数,toString方法}

2.hbm文件
Student.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"><!-- Generated 2016-8-12 20:59:00 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="com.yc.entity.Student" table="STUDENT">        <id name="sid" type="int">            <column name="SID" />            <generator class="sequence" >            <param name="sequence">seq_student_sId</param>            </generator>        </id>        <property name="sname" type="java.lang.String">            <column name="SNAME" />        </property>        <many-to-one name="cid" class="com.yc.entity.Classes" fetch="join">            <column name="CID" />        </many-to-one>    </class></hibernate-mapping>
Classes.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"><!-- Generated 2016-8-12 20:59:00 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="com.yc.entity.Classes" table="CLASSES">        <id name="cid" type="int">            <column name="CID" />            <generator class="sequence" >            <param name="sequence">seq_classes_cid</param>            </generator>        </id>        <property name="cname" type="java.lang.String">            <column name="CNAME" />        </property>    </class></hibernate-mapping>

3.编写测试类运行
package com.yc.test;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;import com.yc.entity.Classes;import com.yc.entity.Student;import com.yc.utils.HibernateUtil;//测试多对一public class MyTest2 {@Test//测试多对一public void testSave(){Classes ct=new Classes();ct.setCname("阴曹地府");Student st1=new Student();st1.setSname("杀破狼");Student st2=new Student();st2.setSname("骨精灵");//设置关联关系st1.setCid(ct);st2.setCid(ct);Session session=HibernateUtil.getSession();Transaction tx=session.beginTransaction();session.save(ct);session.save(st1);session.save(st2);tx.commit();HibernateUtil.closeSession(session);}@Test//测试多对一public void testFind(){Session session=HibernateUtil.getSession();Student s=(Student) session.get(Student.class,1002);System.out.println(s);HibernateUtil.closeSession(session);}}

4.测试运行,同样在这里我只测试testSave方法

          

双向的一对多

其实双向的一对多就是将上述两种方法结合,以便于之后的操作
1.实体类
package com.yc.test3;import java.io.Serializable;public class Student3 implements Serializable{private static final long serialVersionUID = 4829740592306007293L;private int sid;private String sname;private Classes3 cid;//在此同样省略相应的方法}
package com.yc.entity;import java.io.Serializable;import java.util.HashSet;import java.util.Set;public class Classes implements Serializable {private static final long serialVersionUID = 948637569053708320L;private int cid;private String cname;//在一方定义一个多方的集合private Set<Student> students=new HashSet<Student>();//在此同样省略相应的方法}

2.hbm文件
Student.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"><!-- Generated 2016-8-13 10:41:54 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="com.yc.entity.Student" table="STUDENT">        <id name="sid" type="int">            <column name="SID" />            <generator class="sequence" >            <param name="sequence">seq_student_sId</param>            </generator>        </id>        <property name="sname" type="java.lang.String">            <column name="SNAME" />        </property>        <many-to-one name="cid" class="com.yc.entity.Classes" fetch="join">            <column name="CID" />        </many-to-one>    </class></hibernate-mapping>
Classes.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"><!-- Generated 2016-8-13 10:41:54 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="com.yc.entity.Classes" table="CLASSES">        <id name="cid" type="int">            <column name="CID" />            <generator class="sequence" >            <param name="sequence">seq_classes_cid</param>            </generator>        </id>        <property name="cname" type="java.lang.String">            <column name="CNAME" />        </property>        <set name="students" table="STUDENT" inverse="false" lazy="true" >        <!-- 指定关联的外键列 -->            <key>                <column name="CID" />            </key>            <one-to-many class="com.yc.entity.Student" />        </set>    </class></hibernate-mapping>

3.测试类
package com.yc.test;import java.util.Collections;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;import com.yc.entity.Classes;import com.yc.entity.Student;import com.yc.utils.HibernateUtil;//测试双向一对多public class MyTest3 {@Test//测试多对一public void testSave(){Classes c=new Classes("大唐官府");Student s1=new Student("剑侠客");Student s2=new Student("飞燕女");//设置关联关系Collections.addAll(c.getStudents(), s1,s2);s1.setCid(c);s2.setCid(c);Session session=HibernateUtil.getSession();Transaction tx=session.beginTransaction();session.save(c);session.save(s1);session.save(s2);tx.commit();HibernateUtil.closeSession(session);}@Testpublic void testFind(){Session session=HibernateUtil.getSession();Classes c=(Classes) session.get(Classes.class, 1002);Student s=(Student) session.get(Student.class, 1003);System.out.println(c);System.out.println(s);HibernateUtil.closeSession(session);}@Test//查询学生所在的班级的信息public void testFingStudentClass(){Session session=HibernateUtil.getSession();Student s=(Student) session.get(Student.class, 1003);System.out.println(s.getCid());HibernateUtil.closeSession(session);}}

4.测试运行,一样这里只测试testSave方法

写到这里我突然想起一件事情,HibernateUtil的代码忘记贴了,下面是我的代码
package com.yc.utils;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;public class HibernateUtil {private static SessionFactory sessionFactory;private static Session session;static{// 创建配置对象Configuration config = new Configuration().configure();// 创建服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();// 创建会话工厂对象sessionFactory = config.buildSessionFactory(serviceRegistry);}public static Session getSession(){//创建会话对象session = sessionFactory.openSession();return session;}public static void closeSession(Session session){if(session!=null){//关闭会话session.close();}}}



0 0
原创粉丝点击