`
ctojxzsycztao
  • 浏览: 78684 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hibernate one-to-one 与 many-to-one 有关级联操作和Session中添加返回对象 --CTO

阅读更多

很多朋友在使用Hibernate添加有关关联对象的时候都喜欢使用一个对象对应一个save方法的方式来进行保存,但是这家种方法可以说非常的低智,优其是我们使用了Hibernate,学习过Hibernate的朋友们应该都知道,Hibernate的实现方式其实就是对JDBC的一个轻量级的封装,但是它里面提供了自已的一种数据库查询规范HQL,通过编写HQL使用得工程师

们不须要对SQL语句非常的了解,只需要了解对象之间的关联就可以,这样就可以很容易的实现面向对象的方式来编写HQL语句进行查询,Hibernate最终还是会将其转换为SQL语句并执行,Hibernate提供了很多非常实用的特性和方法,使用得我们在开发效率上可以提高几十倍的速度,但对于初学者而言这并不是一件好事,话题好象有些讲偏了题目了,不过在这里我只是做了一个简单的介绍,接下来我们还是回到题目上,使用Hibernate在保存对象与关联对象的时候使用多个save方法,这不是一件好事,只是体现了Hibernate的个基础特性,我们都知道Hibernate提供了一个非常好的功能,那就是级联,通过使用配置,我们可以体现事物的原子性,有一句非常好的话来描述级联,主增从增,主改从改,主删从删,也就是说主表的更改会同时更改子表,而你并不须要特意针对子表来做另外的一些工作,我们针对的只有子表,不过有一些朋友还是对这个不太了解,也有朋友曾经问过我好几次,这也就是我今天要写这个文章的原因,下面我就用一个小例子来讲解并实现这种方式,我将用MyEclipse IDE来实现:该项目的业务很简单,就是用来描述一个用户所对应的身份证号和所对应的职位,用户与他的身份证为一对一的关联,与职位为一对多的关系,我的实现是在添加用户信息和身份证号与及职位的时候使用级联来操作,只使用一个save方法,在添加完后在同一个session下返回刚添加的数据给用户,首先需要准备好Hibernate相关的依赖JAR包和一个MySql5驱动JAR,我在MyEclipse中新建一个Java工程,将相关的JAR包通过引用添加到该工程中去,主个时候需要抒写一个配置,该配置用来定义数据连接池和需要Hibernate来接管的持久化对象,

文件内容如下:

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
	<property name="hibernate.connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="hibernate.connection.url">
		jdbc:mysql://localhost/test
	</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password">root</property>
	<property name="dialect">
		org.hibernate.dialect.MySQLDialect
	</property>
	<!--此处可使用delete 或 update 根据情况而定-->
	<property name="hibernate.hbm2ddl.auto">create</property>
	<property name="hibernate.show_sql">false</property>
	<property name="hibernate.format_sql">true</property>
	<mapping resource="com/lianghe/hibernate/domain/IdCard.hbm.xml" />
	<mapping resource="com/lianghe/hibernate/domain/User.hbm.xml" />
	<mapping resource="com/lianghe/hibernate/domain/Department.hbm.xml" />
</session-factory>
</hibernate-cofiguration>

 接下来需要定义实体BEAN与及相关映射文件源码

User.java

package com.lianghe.hibernate.domain;

import java.util.Date;
public class User {

	private Integer id;
	private String name;
	private Date birthday;
	/* 用户职位 */
	private Department department;
	/* 用户身份证关联号 */
	private IdCard idCard;
	// get set ......
}

 

Idcard.java

package com.lianghe.hibernate.domain;

public class IdCard {
	private Integer id;
	private String name;
	private User user;
	// get set .......
}

 

 

Department.java

package com.lianghe.hibernate.domain;

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

public class Department {
	private Integer id;
	private String name;
	private String desc;
	private Set<User> users = new HashSet<User>(0);
	// get set ........
}

 

 

User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lianghe.hibernate.domain">
	<class name="User" table="user">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name" />
		<property name="birthday" column="birthday" />
		<many-to-one name="department" column="department_id" cascade="all"/>
		<one-to-one name="idCard" class="IdCard" property-ref="user" cascade="all"/>
	</class>
</hibernate-mapping>

 

 

IdCard.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lianghe.hibernate.domain">
	<class name="IdCard" table="id_card">
		<id name="id" column="id" type="java.lang.Integer">
			<generator class="foreign">
				<param name="property">user</param>
			</generator>
		</id>
		<property name="name" column="i_name" />
		<one-to-one name="user" class="User" constrained="true"></one-to-one>
	</class>
</hibernate-mapping>

 

 

Department.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lianghe.hibernate.domain">
	<class name="Department" table="department">
		<id name="id" column="id">
			<generator class="native" />
		</id>
		<property name="name" column="name" />
		<property name="desc" column="desc" />
		<set name="users" inverse="false" lazy="true">
			<key column="department_id"></key>
			<one-to-many class="User" />
		</set>
	</class>
</hibernate-mapping>

 

 

上面也就是我将要实现的这个小例程所需要的进行处理的对象和相关映射文件的描述,到了这个时候接下我我们想要怎样就怎样了,可以进行任何的CRUD操作
接下来我就编写一个测试对象来对上面持久对象进行CRUD的操作

HibernateTest.java

package com.test;

import java.util.Date;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.lianghe.hibernate.domain.Department;
import com.lianghe.hibernate.domain.IdCard;
import com.lianghe.hibernate.domain.User;

public class HibernateTest{

	private static Configuration config;

	private static SessionFactory sessionFactory;

	private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

	static {
		config = new Configuration().configure();
		sessionFactory = config.buildSessionFactory();
	}

	/**
	 * 该方法用于获取 session,并将session存放到当前线程副本,用于在全局使用
	 * 
	 * @return
	 */
	public static Session getSession() {
		Session session = (Session) threadLocal.get();
		if (session != null && !session.isOpen()) {
			return session;
		}
		session = sessionFactory.openSession();
		threadLocal.set(session);
		return session;
	}

	/**
	 * 关闭 session
	 */
	public static void closeSession() {
		Session session = (Session) threadLocal.get();
		if (session != null && !session.isOpen()) {
			session.close();
			threadLocal.set(null);
		}
	}

	public static void main(String[] args) {
		Session session = null;
		Transaction transaction = null;
		try {
			session = getSession();
			transaction = session.beginTransaction();

			User user = new User();
			IdCard idCard = new IdCard();
			Department department = new Department();

			/* add start */
			user.setName("陈涛");
			user.setBirthday(new Date());

			idCard.setName("123456789012345678");

			department.setName("开发部");
			department.setDesc("2");

			user.setIdCard(idCard);
			user.setDepartment(department);

			idCard.setUser(user);
			department.getUsers().add(user);
			/* 这里我只使用了一个save方法,相关联的持久对象在些时都会持久化到数据库 */
			session.save(user);
			transaction.commit();
			System.out.println("添加成功!开始获取数据");
			session.flush();
			/* 当添加成功之后再使用flush方法将数据库数据与持久化对象数据进行同步 */
			System.out.println("User 数据== " + user.getId() + ";"
					+ user.getName() + ";" + user.getBirthday());

			System.out.println("Card 数据 == " + user.getIdCard().getId() + ";"
					+ user.getIdCard().getName() + ";"
					+ user.getIdCard().getUser().getName());

			System.out.println("部门数据 == " + user.getDepartment().getId() + ";"
					+ user.getDepartment().getName() + ";"
					+ user.getDepartment().getDesc());
			/* 添加结束 */
			
			/* 删除操作开始 */
			user = (User)session.get(User.class,1);
			session.delete(user);
			/* 删除操作结束 */
			
			/* 更新开始 */
			user = (User)session.get(User.class,1);
			user.setName("chentao");
			
			idCard = user.getIdCard();
			idCard.setName("907867564534231258");
			
			department = user.getDepartment();
			department.setName("测试部");
			department.setDesc("1");
			
			user.setIdCard(idCard);
			user.setDepartment(department);
			
			session.saveOrUpdate(user);
			/* 更新结束 */
		} catch (HibernateException ex) {
			transaction.rollback();
			ex.printStackTrace();
		} catch (Exception ex) {
			transaction.rollback();
			ex.printStackTrace();
		} finally {
			closeSession();
		}
	}

}

  

 

好了,我想要实现的目的也达到了,其实说白了就是说了一些使用级联来简化编程的操作,其中包括了 one-to-one 和 many-to-one 的级联操作,实现级联主要就是在关联映射文

件关联对象的配置节点上添加了属性cascade,该属性参数你可以选择,使用 all 就代表全部的相关CRUD操作,save-update表示添加和更新的操作,delete 只使用删除上的功能

,这些都可以随意选择,根据自已的情况来定义,感兴趣的朋友可以把代码复制下去体验一下哦!

 

总节:
通过在上面的实现中,可以充分理解到Hibernate的实用之处,当然还有一点就是在添加之后使用了 flush 来将数据进行同步的操作可以将数据库数据与持久对象数据保持一至,

如果是分开使用save来持久化,将会达不到想要的结果,因为相关的关联对象都是独立,但它们共同指向了一个内存地址

1
1
分享到:
评论

相关推荐

    hibernate many-to-many级联保存,级联更新,级联删除

    本文将深入探讨如何在Hibernate中处理Many-to-Many关系的级联保存、级联更新和级联删除。 一、Many-to-Many关系基础 在数据库设计中,Many-to-Many关系意味着两个实体之间存在多对多的关系。例如,学生可以选修多门...

    Hibernate one-to-many / many-to-one关系映射

    总结,Hibernate的one-to-many和many-to-one关系映射是数据库对象关联的基础,理解和熟练掌握它们能帮助开发者更高效地设计和实现Java持久化层。通过合理的配置和实践,可以构建出高性能、易于维护的数据访问层。

    hibernate many-to-one(多对一)及 cascade(级联).doc

    ### Hibernate Many-to-One (多对一) 及 Cascade (级联) #### 一、Many-to-One(多对一) 在数据库设计中,实体之间的关系主要包括一对一、一对多、多对多等几种类型。而在ORM(对象关系映射)框架Hibernate中,...

    Hibernate one-to-many-annotation

    在Hibernate中,`one-to-many`关系是常见的实体间关系之一,表示一个实体可以与多个其他实体相关联。本文将深入探讨`Hibernate one-to-many`注解的使用和实现细节。 ### 一、`@OneToMany`注解概述 `@OneToMany`...

    hibernate one-to-many 单/双向关联映射配置心得

    本文主要关注Hibernate中的一个核心概念——一对一(One-to-One)、一对多(One-to-Many)和多对一(Many-to-One)关联映射,特别是关于“一到多”单向和双向关联映射的配置心得。 首先,让我们了解“一到多”关联...

    Hibernate应用例子one-to-one

    【Hibernate应用例子one-to-one】 Hibernate 是一个强大的Java对象关系映射(ORM)框架,它允许开发者以面向对象的方式操作数据库,从而简化了数据库应用程序的开发。在Hibernate中,"one-to-one"(一对一)关联是...

    Hibernate的级联操作(增,删,该)

    除了上述常见的级联类型,Hibernate还提供了其他的级联选项,如`CascadeType.REFRESH`用于刷新关联对象的状态,`CascadeType.DETACH`用于断开与Session的关联,以及`CascadeType.HALF`等更复杂的级联行为。...

    Hibernate one to many(many to one) 配置

    标题"Hibernate one to many(many to one) 配置"涉及到的是关系型数据库在Java中的持久化框架Hibernate中的两种关联映射关系:一对一(One-to-One)和多对一(Many-to-One)。在数据库设计中,这种关系很常见,例如...

    Hibernate many-to-many

    "Hibernate many-to-many"指的是Hibernate中处理多对多关联关系的一种方式。多对多关系是两个实体类之间存在的一种复杂关联,比如学生和课程之间的关系,一个学生可以选修多门课程,一门课程也可以被多个学生选修。 ...

    Hibernate Many-To-Many Mapping Annotations

    在Java的持久化框架Hibernate中,Many-to-Many映射是一种常见的关系模型,它用于表示两个实体类之间多对多的关系。在这个主题中,我们将深入探讨如何使用注解来实现这种映射,以及其背后的数据库原理和实际应用。 ...

    Hibernate one to one详细配置

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是常见的关系映射类型之一。它用于表示两个实体之间一对一的关联关系,即一个实体对应另一个实体的唯一实例。下面将详细介绍Hibernate中如何进行一对一...

    hibernate中基于外键的one2one

    在Java的持久化框架Hibernate中,一对一(One-to-One)关系映射是一种常见的实体关联方式。基于外键的One-to-One映射是其中的一种实现方式,它通过在一方或双方实体的表中添加外键来建立关联。接下来,我们将深入...

    hibernate-release-4.3.10.Final.zip

    - **HQL(Hibernate Query Language)**:面向对象的查询语言,类似于SQL,但操作的是对象和对象集合。 - **Criteria API**:提供动态构建查询的方式,无需预先编写查询字符串,更加安全。 6. **缓存策略**: - ...

    hibernate基础 二 关联映射 级联操作

    ### Hibernate基础之关联映射与级联操作 ...以上是关于Hibernate中关联映射和级联操作的基础知识概述,掌握了这些内容后,开发者能够在实际项目中更加灵活高效地使用Hibernate进行数据持久化操作。

    hibernate-jpa-2.1-api-1.0.0.final.jar.zip

    总的来说,`hibernate-jpa-2.1-api-1.0.0.final.jar`为开发者提供了丰富的JPA 2.1特性的实现,使得在Java项目中使用Hibernate进行数据库操作变得更加便捷和标准化。通过深入理解和熟练运用这个API,我们可以构建出...

    Spring+Hibernate一对多关联映射---部门与员工表的级联添加

    在Java企业级开发中,Spring和Hibernate是两个非常重要的框架,Spring主要用于依赖注入和管理对象,而Hibernate则是一个优秀的持久层框架,它简化了数据库操作。本教程将深入探讨Spring和Hibernate结合使用时的一对...

    第七章_Hibernate_-_级联策略

    第七章_Hibernate_-_级联策略 第七章

    hibernate--- jar包

    11. **级联操作**: 在关联映射中,可以设置级联操作,比如CascadeType.ALL会将父对象的操作级联到子对象,实现一次操作多个关联对象。 通过学习和掌握Hibernate,开发者可以更专注于业务逻辑,而不是底层的数据库...

    Hibernate的缓存级联查询

    在IT领域,尤其是在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它允许开发者用面向对象的方式操作数据库。尽管随着Spring Data JPA等现代技术的崛起,Hibernate的使用频率有所下降,但其核心...

    hibernate5--3.映射关系

    本文将深入探讨Hibernate5中的映射关系,主要包括多对多(Many-to-Many)和一对多(One-to-Many)这两种关系。 一、多对多映射(Many-to-Many) 多对多关系在数据库中表现为两个表之间存在多个连接记录,而在对象...

Global site tag (gtag.js) - Google Analytics