Hibernate知识点概况(二)

一、多对一映射与一对多映射
学生和班级关系举例:
1.学生实体类,存在班级属性

package hibernate1;


public class Student {
	private int id;
	private String name;
	private String phone;
	private String QQ;
	private Class classid;
	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 getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getQQ() {
		return QQ;
	}
	public void setQQ(String qQ) {
		QQ = qQ;
	}
	public Class getClassid() {
		return classid;
	}
	public void setClassid(Class classid) {
		this.classid = classid;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", phone=" + phone
				+ ", QQ=" + QQ + ", classid=" + classid + "]";
	}
	
}
2.学生类映射
<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  
<hibernate-mapping package="hibernate1" auto-import="true">  
	 <!--主键映射,id自增长类型-->    
    <class name="Student" table="Student">     
        <id name="id" column="id">  
             <generator class="native"/>   
        </id>  
	 <!--普通字段映射-->     
        <property name="name" column="name" type="java.lang.String" length="20"></property>  
        <property name="phone" type="java.lang.String"></property>  
        <property name="QQ" type="java.lang.String"></property>  
        <!--many-to-one映射,name是学生实体中的班级属性名,column为数据库对应字段名,class代表对应的类,即班级类-->  
        <many-to-one name="classid" column="class_id" class="Class"></many-to-one>     	
    </class>  
</hibernate-mapping>  
3.班级实体类,存在List的学生属性
package hibernate1;


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


public class Class {
	private int id;
	private String name;
	private Set<Student> students=new HashSet<Student>();
	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;
	}
	
	@Override
	public String toString() {
		return "Class [id=" + id + ", name=" + name + ", banzhang=" 
				+ ", students=" + students + "]";
	}
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
	
}
4.班级类映射
<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  


<hibernate-mapping package="hibernate1" auto-import="true">   
    <class name="Class" table="Class">  
        <id name="id" column="id">  
             <generator class="native"/>   
        </id>  
        <property name="name" column="name" type="java.lang.String" length="20"></property>        
 	<!--set映射,name是班级实体中的学生属性名,key代表外键,与many-to-one映射的column必须相同--> 
 <set name="students" table="Student"> <key column="class_id"></key> <one-to-many class="Student"/></set> </class> </hibernate-mapping>
5.hibernate.cfg.xml主配置中去除加载实体类的映射配置
6.测试类(推荐多的一方进行操作,即学生)

package hibernate1;


import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;


public class test {
	private static SessionFactory sf;
	static{
		sf=new Configuration().configure()
				.addClass(Class.class).addClass(Student.class).
				buildSessionFactory();	
	}
	
	@Test
	public void save2() {	
		Session session = sf.openSession();
		session.beginTransaction();
			
		// 部门对象
		Class c = new Class();
		c.setName("综合部");
		// 员工对象
		Student s = new Student();
		s.setName("张三");
		s.setPhone("110");
		s.setQQ("120");


		// 关系
		s.setClassid(c);	
		// 保存
		session.save(c); // 先保存一的方法
		session.save(s);// 再保存多的一方,关系回自动维护(映射配置完)
			
		session.getTransaction().commit();
		session.close();


	}
}
7.总结:
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!        
配置一对多与多对一,这种叫“双向关联”;只配置一对多,叫“单项一对多”;只配置多对一,叫“单项多对一”。
注意: 配置了哪一方,哪一方才有维护关联关系的权限!

二、Inverse属性
Inverse属性,是在维护关联关系的时候起作用的。
表示控制权是否转移。(在一的一方起作用)
Inverse , 控制反转。
Inverse = false  不反转,当前方有控制权;True  控制反转; 当前方没有控制权
维护关联关系中,:
         1.保存数据关系中,是否设置inverse属性有影响:
         如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工,数据会保存,但关联关系不会维护。即外键字段为NULL
         2.获取数据关系中,是否设置inverse属性无影响。
         3.解除关联关系中,是否设置inverse属性有影响:
         inverse=false,可以解除关联;inverse=true,当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
         4.删除数据对关联关系中,是否设置inverse属性有影响:
         inverse=false,有控制权, 可以删除。先清空外键引用,再删除数据。
         inverse=true,  没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束!  如果删除的记录没有被引用,可以直接删除。

三、cascade属性
cascade 表示级联操作  【可以设置到一的一方或多的一方】
         none         不级联操作, 默认值
         save-update     级联保存或更新
         delete                级联删除
         save-update,delete    级联保存、更新、删除
         all                 同上。级联保存、更新、删除
使用说明:在多对一映射与一对多映射例子中

// 保存
session.save(c); // 先保存一的方法
session.save(s);// 再保存多的一方,关系回自动维护(映射配置完)
可以修改为:
// 保存
session.save(c); // 先保存一的方法
//session.save(s);// 再保存多的一方,关系回自动维护(映射配置完)
然后在班级映射中增加级联操作属性,产生的效果是一样的
<set name="students" table="Student" cascade="save-update,delete">   
	<key column="class_id"></key>
	<one-to-many class="Student"/>
</set>

四、多对多映射

学生和社团关系举例

1.学生实体类,存在社团属性

package hibernate2;

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

public class Student {
	private int id;
	private String name;
	private Set<Shetuan> shetuans=new HashSet<Shetuan>();
	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 Set<Shetuan> getShetuans() {
		return shetuans;
	}
	public void setShetuans(Set<Shetuan> shetuans) {
		this.shetuans = shetuans;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", shetuans="
				+ shetuans + "]";
	}
}
2.学生映射

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
<hibernate-mapping package="hibernate2" auto-import="true">   
    <class name="Student" table="Student">  
        <id name="id" column="id">  
             <generator class="native"/>   
        </id>  
      
        <property name="name" column="name" type="java.lang.String" length="20"></property>  
        
        <set name="shetuans" table="duiying">   
		 	 <key column="student_id"></key>
		 	 <many-to-many column="shetuan_id" class="Shetuan"></many-to-many>
	    </set>     
    </class>   
</hibernate-mapping>   
3.社团实体类

package hibernate2;

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

public class Shetuan {
	private int id;
	private String name;
	private Set<Student> students=new HashSet<Student>();
	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 Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
	@Override
	public String toString() {
		return "Shetuan [id=" + id + ", name=" + name + ", students="
				+ students + "]";
	}
}
4.社团实体类映射
<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  

<hibernate-mapping package="hibernate2" auto-import="true">   
    <class name="Shetuan" table="Shetuan">  
        <id name="id" column="id">  
             <generator class="native"/>   
        </id>  
      
        <property name="name" column="name" type="java.lang.String" length="20"></property>  
        
        <set name="students" table="duiying">   
		 	 <key column="shetuan_id"></key>
		 	 <many-to-many column="student_id" class="Student"></many-to-many>
	</set>  
    </class>    
</hibernate-mapping>  
5.测试类

package hibernate2;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class test {
	private static SessionFactory sf;
	static{
		sf=new Configuration().configure()
				.addClass(Shetuan.class).addClass(Student.class).
				buildSessionFactory();
		
	}

	
		@Test
		public void save() {
			
			Session session = sf.openSession();
			session.beginTransaction();
			
			// 部门对象
			Shetuan c1 = new Shetuan();
			c1.setName("青年志愿者协会");
			Shetuan c2 = new Shetuan();
			c2.setName("爱心社");
			Shetuan c3 = new Shetuan();
			c3.setName("俱乐部");
		
			// 员工对象
			Student s1 = new Student();
			s1.setName("张三");
			Student s2 = new Student();
			s2.setName("李四");
			Student s3 = new Student();
			s3.setName("王五");
			
			// 关系
			c1.getStudents().add(s1);
			c1.getStudents().add(s3);
			c2.getStudents().add(s1);
			c3.getStudents().add(s2);
			// 保存
			session.save(c1); 
			session.save(c2);
			session.save(c3);
			
			session.save(s1); 
			session.save(s2);
			session.save(s3);
			
			session.getTransaction().commit();
			session.close();

	}
}
6.hibernate.cfg.xml配置相同,不再给出

7.常见问题:

7.1测试类要加载实体类

7.2实体类中的Set或List要跟映射配置相一致
7.3hibernate.cfg.xml配置中自动建表的值

五、多对多维护管理关系(inverse属性)

1) 保存数据有影响

       inverse=false ,有控制权,可以维护关联关系;保存数据的时候会把对象关系插入中间表;

       inverse=true,  没有控制权,不会往中间表插入数据。

2) 获取数据无影响

3) 解除关系有影响

       inverse=false ,有控制权,解除关系就是删除中间表的数据。

       inverse=true, 没有控制权,不能解除关系。

4) 删除数据有影响

       inverse=false, 有控制权。先删除中间表数据,再删除自身。

       inverse=true, 没有控制权。如果删除的数据有被引用,会报错!否则,才可以删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值