hibernate学习笔记(三)

本文深入探讨了ORM中一对多、多对一及多对多关系的实现方式,包括关系表达、代码实现、级联操作及关系维护优化等内容,旨在帮助开发者更好地理解和应用ORM技术。

目录

 

一、一对多和多对一

1.1 关系表达

1.2 级联操作

1.3 关系维护优化

二、多对多关系

2.1 关系表达

2.2 代码实现

三、总结


一、一对多和多对一

1.1 关系表达

1.1.1 表中关系的表达

 

1.1.2  实体中的表达

1.1.3 orm中配置的表达

Customer.hbm.xml中的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.bean">
	<class name="Customer" table="customer">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name"></property>
		<property name="age" column="age"></property>
		
		<set name="linkMen">
			<key column="cid"></key>
			<one-to-many class="LinkMan"/>
		</set>

	</class>
</hibernate-mapping>

Customer实体的配置

package cn.itcast.bean;

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

public class Customer {

	public int id;
	public String name;
	public int age;
	
	private Set<LinkMan> linkMen = new HashSet<LinkMan>();
	
	public Set<LinkMan> getLinkMen() {
		return linkMen;
	}
	public void setLinkMen(Set<LinkMan> linkMen) {
		this.linkMen = linkMen;
	}

	
}

一对多的关系中,实体中需要配置一个集合来映射多的一方,由于记录的不重复,所以用set集合,hbm.xml中用<set>节点来配置


name:属性中的名字
column:外键列名
class:对应的实体的类名
<set name="linkMen">
	<key column="cid"></key>
	<one-to-many class="LinkMan"/>
</set>

LinkMan.hbm.xml中的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.bean">
	<class name="LinkMan" table="linkMan">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name"></property>
		
		<many-to-one name="customer" class="Customer" column="cid"></many-to-one>
		
	</class>
</hibernate-mapping>

LinkMan实体的配置

package cn.itcast.bean;

public class LinkMan {

	private int id;
	private String name;
	
	private Customer customer;
	
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
}

其中多对一的属性用 <many-to-one>节点来配置

name:属性的名字
class:实体的类名
column:外键列名
<many-to-one name="customer" class="Customer" column="cid"></many-to-one>

1.1.4 代码维护关系

package cn.itcast.one2many;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.bean.Customer;
import cn.itcast.bean.LinkMan;
import cn.itcast.util.HibernateUtils;

public class Demo {

	@Test
	public void testOne2Many() {

		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		//两个实体对象
		Customer c1 = new Customer();
		c1.setName("百度");
		
		LinkMan lm1 = new LinkMan();
		lm1.setName("李彦宏");
		
		LinkMan lm2 = new LinkMan();
		lm2.setName("王玉龙");
		
		//互相维护关系
		lm1.setCustomer(c1);
		lm2.setCustomer(c1);
		c1.getLinkMen().add(lm1);
		c1.getLinkMen().add(lm2);
		
		//保存 持久化
		session.save(c1);
		session.save(lm1);
		session.save(lm2);
		
		tx.commit();
		session.close();
	}
}

输出的sql语句

1.2 级联操作

1.2.1 级联保存更新

可以看到,在上述的插入客户和联系人的过程中,每增加一个联系人就得调用session.save(lm)一下,当我们有更多的联系人的时候就得保存不止一次,为了能让hibernate自动的帮我们级联的保存更新联系人,我们可以设置我们的级联操作

                                       
cascade:级联操作                                 
	save-update:级联保存更新                       
	delete:级联删除                              
	all:save-update+delete                   
                                       
<set name="linkMen" cascade="save-update">   
	<key column="cid"></key>                 
	<one-to-many class="LinkMan"/>           
</set>                                       

设置之后我们就可以省去下面的几行代码:

@Test                                                   
public void testOne2Many() {                            
                                                        
	Session session = HibernateUtils.openSession();     
	Transaction tx = session.beginTransaction();        
	                                                    
	//两个实体对象                                            
	Customer c1 = new Customer();                       
	c1.setName("百度");                                   
	                                                    
	LinkMan lm1 = new LinkMan();                        
	lm1.setName("李彦宏");                                 
	                                                    
	LinkMan lm2 = new LinkMan();                        
	lm2.setName("王玉龙");                                 
	                                                    
	//互相维护关系                                            
	lm1.setCustomer(c1);                                
	lm2.setCustomer(c1);                                
	c1.getLinkMen().add(lm1);                           
	c1.getLinkMen().add(lm2);                           
	                                                    
	//保存 持久化                                            
	session.save(c1);                                   
//	session.save(lm1);                                  
//	session.save(lm2);                                  
	                                                    
	tx.commit();                                        
	session.close();                                    
}                                                       

1.2.2 级联删除

<set name="linkMen" cascade="delete">   
	<key column="cid"></key>                 
	<one-to-many class="LinkMan"/>           
</set>  

当cascade的值为save-update时,我们进行删除

@Test                                                   
public void testOne2ManyDelete() {                      
	                                                    
	Session session = HibernateUtils.openSession();     
	Transaction tx = session.beginTransaction();        
	                                                    
	Customer c = session.get(Customer.class, 1);        
	                                                    
	session.delete(c);                                  
	                                                    
	tx.commit();                                        
	session.close();                                    
}                                                       

实际上数据库并没有删除linkman的数据,只是把外键cid设置为null

当cascade的值为delete时,我们进行删除,所有相关的数据都会删除了

 

1.3 关系维护优化

可以看出,最后两条更新语句有点多余,按说插入语句完成后,cid是已经生成了,不需要最后两条sql语句来维护关系了。

出现这个问题的原因就是我们的两个实体都相互维护了关系,其实只要一方维护关系就行了,hibernate就能自动识别了,所以我们需要做一下优化。让其中一方放弃维护关系

                                                                                        
inverse:(是否反转)配置关系是否维护,true:customer不维护关系;false(默认值):customer 维护关系                                                                                                                            
inverse属性是来做性能优化的,使得一方放弃维护关系,会减少sql语句的生成                                                        
原则:无论如何放弃,必须有一方来维护关系。                                                                           
一对多关系中,一的一方放弃,多的一方不放弃,也必须一的一方放弃                                                                 
                                                                                                                                                                                   
<set name="linkMen" inverse="true" cascade="save-update">                                       
	<key column="cid"></key>                                                                    
	<one-to-many class="LinkMan"/>                                                              
</set>                                                                                          

代码修改

public void testOne2Many() {                                    
                                                                
	Session session = HibernateUtils.openSession();             
	Transaction tx = session.beginTransaction();                
	                                                            
	//两个实体对象                                                    
	Customer c1 = new Customer();                               
	c1.setName("百度");                                           
	                                                            
	LinkMan lm1 = new LinkMan();                                
	lm1.setName("李彦宏");                                         
	                                                            
	LinkMan lm2 = new LinkMan();                                
	lm2.setName("王玉龙");                                         
	                                                            
	//互相维护关系                                                    
	lm1.setCustomer(c1);                                        
	lm2.setCustomer(c1);                                        
	//客户放弃维护关系(也就是一的一方放弃维护关系)                                   
	//c1.getLinkMen().add(lm1);                                 
	//c1.getLinkMen().add(lm2);                                 
	                                                            
	//保存 持久化                                                    
	session.save(c1);                                           
	session.save(lm1);                                          
	session.save(lm2);                                          
	                                                            
	tx.commit();                                                
	session.close();                                            
}                                                               

但是session得保存每个lm使得持久化,输出入下

但是有点扯淡啊,还得调用save。

二、多对多关系

2.1 关系表达

2.1.1 表中关系

2.1.2 实体中的表达

2.1.3 orm元数据中的表达

由于多对多的关系需要一个中间表来维护,所以我们配置的时候要引入一张中间表。

                                                           
name:集合属性名                                                  
table:配置的中间表名                                               
key                                                         
 |-column:外键列名,别人引用我的外键列名                                  
class:我与那个类是多对多关系                                           
column:外键,我引用别人的外键                                          
                                                         
<set name="users" table="user_role" cascade="save-update">      
	<key column="role_id"></key>                                
	<many-to-many class="User" column="user_id"></many-to-many> 
</set>                                                          

2.2 代码实现

2.2.1 实体

package cn.itcast.bean;

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

public class User {
	
	private int user_id;
	private String user_name;
	private Set<Role> roles = new HashSet<Role>();
	public Set<Role> getRoles() {
		return roles;
	}
	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}
	public int getUser_id() {
		return user_id;
	}
	public void setUser_id(int user_id) {
		this.user_id = user_id;
	}
	public String getUser_name() {
		return user_name;
	}
	public void setUser_name(String user_name) {
		this.user_name = user_name;
	}

	
}

public class Role {
	private int role_id;
	private String role_name;
	private Set<User> users =new HashSet<User>();
	
	
	public Set<User> getUsers() {
		return users;
	}
	public void setUsers(Set<User> users) {
		this.users = users;
	}
	public int getRole_id() {
		return role_id;
	}
	public void setRole_id(int role_id) {
		this.role_id = role_id;
	}
	public String getRole_name() {
		return role_name;
	}
	public void setRole_name(String role_name) {
		this.role_name = role_name;
	}
	
}

2.2.2 hbm.xml中的配置

User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.bean">

	<class name="User" table="user">

		<id name="user_id" column="user_id">
			<generator class="native"></generator>
		</id>
		
		<property name="user_name" column="user_name"></property>
	
		<!--
			name:集合属性名
			table:配置的中间表名
			key
			  |-column:外键列名,别人引用我的外键列名
			class:我与那个类是多对多关系
			column:外键,我引用别人的外键
		  -->
		<set name="roles" table="user_role" cascade="save-update">
			<key column="user_id"></key>
			<many-to-many class="Role" column="role_id"></many-to-many> 
		</set>
	</class>
</hibernate-mapping>

Role.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.bean">

	<class name="Role" table="role">

		<id name="role_id" column="role_id">
			<generator class="native"></generator>
		</id>
		
		<property name="role_name" column="role_name"></property>
	
		<!--
			name:集合属性名
			table:配置的中间表名
			key
			  |-column:外键列名,别人引用我的外键列名
			class:我与那个类是多对多关系
			column:外键,我引用别人的外键
		  -->
		<set name="users" table="user_role" cascade="save-update">
			<key column="role_id"></key>
			<many-to-many class="User" column="user_id"></many-to-many> 
		</set>
	</class>
</hibernate-mapping>

2.2.3 代码

@Test                                                
public void testMany2Many() {                        
                                                     
	Session session = HibernateUtils.openSession();  
	Transaction tx = session.beginTransaction();     
	                                                 
	User u1 = new User();                            
	u1.setUser_name("李四");                           
	User u2 = new User();                            
	u2.setUser_name("张三");                           
                                                     
	Role r1 = new Role();                            
	r1.setRole_name("管理员");                          
	Role r2 = new Role();                            
	r2.setRole_name("财务");                           
	                                                 
	u1.getRoles().add(r1);                           
	u1.getRoles().add(r2);                           
	                                                 
	u2.getRoles().add(r1);                           
	u2.getRoles().add(r2);                           
	                                                 
	session.save(u1);                                
	session.save(u2);                                
	session.save(r1);                                
	session.save(r2);                                
	                                                 
	tx.commit();                                     
	session.close();                                 
}                                                    

本测试使用了User的级联更新属性

输出如下

三、总结

这次我们主要学习了一对多,多对多关系的实现,hibernate的初衷是从代码开始,让开发者不再关注数据库,直接写逻辑,这和EF的codefirst是一样的道理。

 

标题基于SpringBoot的马术俱乐部管理系统设计与实现AI更换标题第1章引言介绍马术俱乐部管理系统的研究背景、意义、国内外研究现状、论文方法及创新点。1.1研究背景与意义阐述马术俱乐部管理系统对提升俱乐部管理效率的重要性。1.2国内外研究现状分析国内外马术俱乐部管理系统的发展现状及存在的问题。1.3研究方法以及创新点概述本文采用的研究方法,包括SpringBoot框架的应用,以及系统的创新点。第2章相关理论总结和评述与马术俱乐部管理系统相关的现有理论。2.1SpringBoot框架理论介绍SpringBoot框架的基本原理、特点及其在Web开发中的应用。2.2数据库设计理论阐述数据库设计的基本原则、方法以及在管理系统中的应用。2.3马术俱乐部管理理论概述马术俱乐部管理的基本理论,包括会员管理、课程安排等。第3章系统设计详细描述马术俱乐部管理系统的设计方案,包括架构设计、功能模块设计等。3.1系统架构设计给出系统的整体架构,包括前端、后端和数据库的交互方式。3.2功能模块设计详细介绍系统的各个功能模块,如会员管理、课程管理、预约管理等。3.3数据库设计阐述数据库的设计方案,包括表结构、字段设计以及数据关系。第4章系统实现介绍马术俱乐部管理系统的实现过程,包括开发环境、编码实现等。4.1开发环境搭建介绍系统开发所需的环境,包括操作系统、开发工具等。4.2编码实现详细介绍系统各个功能模块的编码实现过程。4.3系统测试与调试阐述系统的测试方法、测试用例以及调试过程。第5章系统应用与分析呈现马术俱乐部管理系统的应用效果,并进行性能分析。5.1系统应用情况介绍系统在马术俱乐部中的实际应用情况。5.2系统性能分析从响应时间、并发处理能力等方面对系统性能进行分析。5.3用户反馈与改进收集用户反馈,提出系统改进建议。第6章结论与展望总结马术俱乐部管理系统的设计与实现成果,并展望未来的研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值