一口一口吃掉Hibernate(四)——多对一单向关联映射

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:       Hibernate对于数据库的操作,全部利用面向对象的思维来理解和实现的。一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它。

      Hibernate对于数据库的操作,全部利用面向对象的思维来理解和实现的。一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它。


      今天就来说说多对一的关联映射。


      数据库中有多对一的关系,Hibernate自然也有对象的多对一的关联关系。比如用户和用户组,一个用户只属于一个组,一个组有多名用户。我们就可以说用户和用户组的关系就是多对一的关系。用对象的uml图表示一下:



      在Hibernate中如何来实现呢?首先定义这两个实体类:

package com.bjpowernode.hibernate;

/**
 * 用户组
 * @author Longxuan
 *
 */
public class Group {

	private int id;
	private String name;
	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;
	}
}



package com.bjpowernode.hibernate;

/**
 * 用户类
 * @author Longxuan
 *
 */
public class User {
	
	private int  id;
	
	private String name;

	private Group group;
	
	public Group getGroup() {
		return group;
	}

	public void setGroup(Group group) {
		this.group = group;
	}

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

}


hibernate.cfg.xml配置文件:

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory name="foo">	
		
		<property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.show_sql">true</property><!-- 设置是否显示生成sql语句 -->
		<property name="hibernate.format_sql">false</property><!-- 设置是否格式化sql语句-->
		
		<mapping resource="com/bjpowernode/hibernate/Tables.hbm.xml" />
	</session-factory>
</hibernate-configuration>

hibernate.properties配置文件:

## MySQL

hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost:3306/hibernate_many2one
hibernate.connection.username root
hibernate.connection.password root

      这是最基础的准备工作,多对一映射在对数据进行更改时,会有一些限制。当没有该用户组时,添加用户,就会出错,当该用户组有用户时,删除该用户组也会报错。


      我们当然可以按一般的方法来做。添加的时候,先手动添加组,再添加用户。删除时,先删除所有的用户,再删除用户组。但是Hibernate为我们提供了一种便捷的方式——many-to-one。在映射文件hbm.xml中配置后,就可以不用再想那些限制了。Hibernate会自动添加上所引用的数据。


      给出映射文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	
	<class name="com.bjpowernode.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="name"></property>
		<many-to-one name="group" column="groupid" cascade="save-update"></many-to-one>
	</class>
		
	<class name="com.bjpowernode.hibernate.Group" table="t_group">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="name"></property>
	</class>
	
</hibernate-mapping>


       配置了many-to-one会自动在t_user表中创建外键groupid,与t_group的id映射。


    many-to-one标签用到了cascade,指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。其属性值如下: 

  • all:在所有的情况下都执行级联操作;
  • none:在所有情况下都不执行级联操作;
  • save-update:在保存和更新的时候执行级联操作;、
  • delete:在删除的时候执行级联操作。


    测试类Many2OneTest:

package com.bjpowernode.hibernate;

import junit.framework.TestCase;

import org.hibernate.Session;

public class Many2OneTest extends TestCase {

        /**
         * 测试添加用户
         */
        public void testSave3(){
		Session session = null;
		try{
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Group group = new Group();
			group.setName("提高班");
			
			User user1 = new User();
			user1.setName("张三");
			user1.setGroup(group);
			
			User user2 = new User();
			user2.setName("李四");
			user2.setGroup(group);
			
			//普通方法 :必须先保存group,再保存user
			//配置了many-to-one 则不用再手动save group了。
			//session.save(group);
			session.save(user1);
			session.save(user2);
			
			session.getTransaction().commit();
		}catch(Exception e){
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}
	
}

      结果图:



 执行测试前:  , 执行测试后:  


      用many-to-one进行配置后,hibernate会自动去添加外键,而我们做的任何操作都不需要去考虑它的结构,也不用手动去维护这个关系,关系由Hibernate自动维护。这就是Hibernate的魅力所在。





相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
9月前
|
SQL XML 存储
Hibernate框架【五】——基本映射——多对多映射
Hibernate框架【五】——基本映射——多对多映射
129 0
|
4月前
|
SQL 存储 Java
Hibernate - 继承关联关系映射
Hibernate - 继承关联关系映射
30 0
|
4月前
|
SQL XML Java
Hibernate - 单向多对一关联关系映射
Hibernate - 单向多对一关联关系映射
16 0
|
9月前
|
SQL XML Java
Hibernate框架【四】——基本映射——多对一和一对多映射
Hibernate框架【四】——基本映射——多对一和一对多映射
105 0
|
Java 数据库连接
mybatis-plus和hibernate 忽略映射字段
mybatis-plus和hibernate 忽略映射字段
249 1
|
SQL Java 数据库连接
《Hibernate上课笔记》-----class3----Hibernate的单实体映射
《Hibernate上课笔记》-----class3----Hibernate的单实体映射
94 0
|
XML Java 数据库连接
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
68 0
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
|
存储 SQL Java
hibernate学习笔记之二(映射关系与懒加载)
hibernate学习笔记之二(映射关系与懒加载)
hibernate学习笔记之二(映射关系与懒加载)
|
SQL 存储 数据可视化
Java Web之Hibernate的高级应用(数据库实体关联之间的映射规则、实体继承关系映射、Hibernate查询语言)
Java Web之Hibernate的高级应用(数据库实体关联之间的映射规则、实体继承关系映射、Hibernate查询语言)
154 0
Java Web之Hibernate的高级应用(数据库实体关联之间的映射规则、实体继承关系映射、Hibernate查询语言)
|
Oracle 关系型数据库 Java
hibernate注解 映射序列到Oracle
hibernate注解 映射序列到Oracle