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

在上篇博客我们讲了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文件



	
		hibernate
		a
		oracle.jdbc.driver.OracleDriver
		jdbc:oracle:thin:@localhost:1521:orcl
		
		org.hibernate.dialect.OracleDialect

		
		true
		
		true
		
		update
		
		thread

	


一对多的关联关系

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 students=new HashSet();

	public Classes() {

	}
	public Classes(String cname) {
		this.cname = cname;
	}
	public Classes(int cid, String cname, Set 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 getStudents() {
		return students;
	}
	public void setStudents(Set students) {
		this.students = students;
	}

	public String toString() {
		return "Classes [cid=" + cid + ", cname=" + cname + ", students="
				+ students + "]";
	}
}

2.根据实体类创建对应的hbm文件
Student.hbm.xml




    
        
            
            
            	seq_student_sId
            
        
        
            
        
    

Classes.hbm.xml




    
        
            
            
            	seq_classes_cid
            
        
        
            
        
        
        
        	
            
                
            
            
        
    


3.在cfg文件中加入映射路径



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方法的测试结果,其余方法小伙伴门可以自己尝试
Hibernate关联映射之一对多,多对一以及双向一对多_第1张图片
Hibernate关联映射之一对多,多对一以及双向一对多_第2张图片 Hibernate关联映射之一对多,多对一以及双向一对多_第3张图片

多对一的关联关系

在这里其实我们只需改变实体类中的属性以及对应的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




    
        
            
            
            	seq_student_sId
            
        
        
            
        
        
            
        
    

Classes.hbm.xml




    
        
            
            
            	seq_classes_cid
            
        
        
            
        
    


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方法
Hibernate关联映射之一对多,多对一以及双向一对多_第4张图片
Hibernate关联映射之一对多,多对一以及双向一对多_第5张图片           Hibernate关联映射之一对多,多对一以及双向一对多_第6张图片

双向的一对多

其实双向的一对多就是将上述两种方法结合,以便于之后的操作
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 students=new HashSet();

	//在此同样省略相应的方法
}

2.hbm文件
Student.hbm.xml




    
        
            
            
            	seq_student_sId
            
        
        
            
        
        
            
        
    

Classes.hbm.xml




    
        
            
            
            	seq_classes_cid
            
        
        
            
        
        
        	
            
                
            
            
        
    


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

	@Test
	public 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方法
Hibernate关联映射之一对多,多对一以及双向一对多_第7张图片
Hibernate关联映射之一对多,多对一以及双向一对多_第8张图片 Hibernate关联映射之一对多,多对一以及双向一对多_第9张图片

写到这里我突然想起一件事情,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();
		}
	}
}



你可能感兴趣的:(Hibernate)