hibernate3第四章之一对多cascade、fetch

都是级联,cascade只作用于(save\update\delete)、fetch只作用于(query);

一、一对多  save一的一方

1.cascade为级联,值有以下几种,一般都是用ALL

  • CascadeType.PERSIST: 如果一个实体是受管状态, 或者当persist()函数被调用时, 触发级联创建(create)操作
  • CascadeType.MERGE: 如果一个实体是受管状态, 或者当merge()函数被调用时, 触发级联合并(merge)操作
  • CascadeType.REMOVE: 当delete()函数被调用时, 触发级联删除(remove)操作
  • CascadeType.REFRESH: 当refresh()函数被调用时, 触发级联更新(refresh)操作
  • CascadeType.ALL: 以上全部
2.下面代码运行后,会先存入一个teacher,然后再存入2个Student (以下将teacher简写为t,Student简写为s)
   可以看到我只是save(t)了,为什么会存入2个student呢?因为以下2点
(1)cascade设置为all,表示使用所有方法都会级联操作
(2)在t里面设置好2个s的对应关系
  否则缺一点则会只存入一个teacher,student不会存入,但是程序不会报错。

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher")
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	@Test
	public void testSaveTeacher(){
		Session session=sf.getCurrentSession();
		Student s=new Student();
		s.setName("a");
		s.setAge(25);
		Student s1=new Student();
		s1.setName("s1");
		s1.setAge(26);
		Teacher t=new Teacher();
		t.setBirthDate(new Date());
		t.setName("wy");
		t.setTitle("中级");
		t.getStudent().add(s1);
		t.getStudent().add(s);
		s.setTeacher(t);
		s1.setTeacher(t);
		
		session.beginTransaction();
		session.save(t);
		session.getTransaction().commit();
	}
	
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}

二、一对多  存入多的一方

1.下面代码运行后,会先存入一个teacher,然后再存入1个Student (以下将teacher简写为t,Student简写为s)

   可以看到我只是save(s)了,为什么会存入1个teacher呢?因为以下2点
(1)cascade设置为all 
  否则缺一点则会报错(org.hibernate.TransientObjectException: object references an unsaved transient instance - save the t   意思大概是外键关联的是一个未持 久化的瞬时状态对象,通俗的讲就是一的一方还没有存进去多的一方外键字段为空)。
(2)在s里面设置好t的对应关系
否则只会存入一个s,不会报错,关联字段为空;
 

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher")
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	@Test
	public void testSaveStudent(){
		Session session=sf.getCurrentSession();
		Student s=new Student();
		s.setName("a");
		s.setAge(25);
		Teacher t=new Teacher();
		t.setBirthDate(new Date());
		t.setName("wy");
		t.setTitle("中级");
		s.setTeacher(t);
		session.beginTransaction();
		session.save(s);
		session.getTransaction().commit();
	}
	
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}
三、一对多  查询一的一方

1.fetch:关联关系获取(hibernate默认挺人性化,在一对多中,一的一方默认为lazy懒加载,多的一方默认为eager积极的主动的加载),fetch参数可以设置为FetchType.LAZY 或者 FetchType.EAGEREAGER通过outer join select直接获取关联的对象, 而LAZY(默认值)在第一次访问关联对象的时候才会触发相应的select操作. EJBQL提供了fetch关键字,该关键字可以在进行特殊查询的时候覆盖默认值. 这对于提高性能来说非常有效,应该根据实际的用例来判断是否选择fetch关键字.

2.load和get的区别最大的就是:Load生成的是一个代理,用到对象的时候才去数据库查找,用不到就不查数据库节约内存,get则是直接查找对象放到内存里。如果session关闭了再去拿没有取出来的对象的数据,则两种都会报错,因为session关闭以后就断开了与数据库的链接。 

3.下面如果不设置fetch参数为eager的话,load的话产生一个代理,get则首先只会查询一这一方,当遇到要用多一方数据的时候会再次查询数据库将多的一方取出来。(看似和load差不多)

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL},fetch=FetchType.EAGER)
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}
   
	@Test
	public void testLoadTeacher(){
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Teacher t=(Teacher)session.load(Teacher.class, 1);//只是做了代理,用到才会发SQL
		for(Student s:t.getStudent()){
			System.out.println(s.getName());
		}
		session.getTransaction().commit();

	}
	@Test
	public void testGetTeacher(){
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Teacher t=(Teacher)session.get(Teacher.class, 1);//直接发SQL
		session.getTransaction().commit();
		for(Student s:t.getStudent()){
			System.out.println(s.getName());
		}
	}
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}


四、一对多 查询多的一方

1.多的一方默认fetch为eager,所以会直接取出一的一方数据

2.如果一的一方也设置fetch为eager的话,则会因为去一条多的一方数据,而连带着将所有与一的一方(这一条一的一方数据与你要取的那条多的一方数据有关联)关联的多的一方数据全部取出,因为你要取一条多的一方数据,因为eager的关系会取出一的一方数据,又因为一的一方eager的关系,继续又取出了多的一方所有关联数据。所以在开发过程中一般都会将fetch设置为lazy,慎重使用eager

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL})
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	@Test
	public void testLoadStudent(){
		//fetch控制查询懒加载  cascade控制增删改
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Student s=(Student)session.load(Student.class, 2);//只是做了代理,用到才会发SQL
<pre name="code" class="java">		System.out.println(s.getName());
session.getTransaction().commit();}@Testpublic void testGetStudent(){Session session=sf.getCurrentSession();session.beginTransaction();Student s=(Student)session.get(Student.class, 2);//直接发SQL
		System.out.println(s.getTeacher().getName());
session.getTransaction().commit();}@Testpublic void testSchemaExport(){new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);}@AfterClasspublic static void afterClass(){sf.close();}}

 

五、一对多 更新多的一方 (由于annotation没有设置XML中dynamic-update="true"的标签,所有所有更新都是更新所有字段,在某些字段比较大的时候这样更新是很不合理的,所以:1.改用XML配置(XML不方便,所以不用这种方式)2.在某属性上使用 @Column(updatable=false)使得某属性不参与更新(这样想更新这个字段也不行了,所以不采用这个方式)3.使用HQL语句,灵活方便可以采用这种方法,其实就是和写SQL语句差不多,HQL语句是面向对象的操作语句;以上可以看出annotation也不是万能的,希望以后版本可以解决这个问题,但是update()还是要学的)

1.多的一方默认设置fetch为eager,取得s数据的时候会直接把t的也取出来,然后更改了s和t的信息,然后如果多的一方的cascade设置为all,则会连带着把t的也更新了,如果没有设置all,用update方法更新则不会更新t的信息;需要注意的是cascade的其他值设定:如果设置为persist,则只在用persist()方法的时候发生级联操作,其他merge、remove、refresh等方法一样。  

2.联想到:如果一的一方fetch也设置为eager的话,则会连着把多的一方所有数据取出,这样虽然是不应该的,但是这样的话就可以更改与之关联的所有s的数据了。

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL})
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	//在不同session里更新其实差不多
	@Test
	public void testUpdateStudent(){
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Student s=(Student)session.get(Student.class, 2); //首先直接取出student数据
		session.getTransaction().commit(); //关闭session
		s.setName("aaa1");//更改s的name
		s.getTeacher().setName("cc");//更改一的一方的name
		Session session1=sf.getCurrentSession();//另开一个session
		session1.beginTransaction();
		session1.update(s);//更新数据
		session1.getTransaction().commit();  
	}
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}

六、一对多 更新一的一方

1.一的一方没有设置fetch的值为eager,默认是不取得s的数据的,但是在session关闭之前使用了与之相关的s的数据,所以会像load似的再次查询数据将s的数据都拿出   来,更改了t的Name,更改了所有s的name。

由于一的一方设置了cascade的值为ALL,则更新t的时候会将所有的s也一起更新,更新s的形式是每一条s一个更新语句,如果有1000个s则发出1000条sql语句

如果一的一方没有设置cascade的值,在session关闭之前更新t,也会将所有的s也一起更新;但是在session关闭之后由另外一个session去更新的话则只会更新t, 不会更新s;

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL})
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	
	@Test
	public void testUpdateTeacher(){
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Teacher t=(Teacher)session.get(Teacher.class, 2); 
		t.setName("zs");
		for(Student s:t.getStudent()){
			s.setName(s.getName()+"s");
		};
		session.getTransaction().commit();  
	}
	
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}

七、一对多  删除多的一方

1.由于多的一方设置cascade等于all,所以在删除s的时候会删除一的一方的t,而在一的一方t中又设置了cascade等于all,所以删除t又会将与之关联的所有s给删除,这种     结果不是我们所想要的,所以要打破这种关联关系,可以在删除之前将s的teacher属性设置为null,这样s就找不到t,也就删不了;还有一种删除就是使用HQL语句;

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL})
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	
	@Test
	public void testDeleteStudent(){
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Student s=(Student)session.load(Student.class, 11);
		s.setTeacher(null);
		session.delete(s);
		session.getTransaction().commit();  
	}
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}


八、一对多  删除一的一方

1.删除一的一方很简单,就像树枝似的,树干砍了,树枝自然没了,删除t则会将与之关联的s都删除了

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

import javax.annotation.Generated;
import javax.persistence.*;

@Entity
public class Teacher {
	private int id;
	private String name;
	private String title;
	private Date birthDate;
	private Set<Student> student=new HashSet<Student>();
	
	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL})
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	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 String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
}

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Fetch;
@Entity
public class Student {
	private int id;
	private String name;
	private int age; 
	private Teacher teacher;
	@ManyToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="teacherid")
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Id
	@GeneratedValue
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateORMTest {
	private static SessionFactory sf=null;
	@BeforeClass
	public static void beforeClass(){
		sf=new AnnotationConfiguration().configure().buildSessionFactory();
	}

	@Test
	public void testDeleteTeacher(){
		Session session=sf.getCurrentSession();
		session.beginTransaction();
		Teacher t=(Teacher)session.load(Teacher.class, 11);
		session.delete(t);
		session.getTransaction().commit();  
	}
	@Test
	public void testSchemaExport(){
		new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
	}
	@AfterClass
	public static void afterClass(){
		sf.close();
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值