Hibernate系列---(二)主键生成策略&持久化类状态&一级缓存&事务

本文详细介绍Hibernate持久化类的编写规则,包括属性访问、构造方法、OID标识等;讲解主键生成策略,如increment、identity、sequence、uuid及native;探讨持久化对象的三种状态:瞬时态、持久态和托管态;并介绍Hibernate的一级缓存机制和事务管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Hibernate持久化类的编写规则

持久化类:

一个Java对象与数据库的表建立了映射关系,那么这个类在hibernate中成为持久化类

编写规则:

  • 对持久化类提供一个无参的构造方法(Hibernate底层需要使用反射生成实例)
  • 属性为private,对私有属性提供public的get和set方法(Hibernate中获取,设置对象的值)
  • 对持久化类提供一个唯一标识OID与数据库主键对应(Java中通过对象地址区分是否是同一个对象,数据库通过主键值确定是否是同一个纪录,Hibernate通过持久化类的OID的属性区分是否是同一个对象)
  • 持久化类不能使用final进行修饰(如为final,则load方法无法返回代理对象,因为不能继承这个类进行代理。此时load和get方法一致)

二、主键生成策略

2.1 主键分类

  • 自然主键:主键本省就是表中所用的字段,即实体中的一个具体的属性

  • 代理主键:主键本省不是表中的字段,即不是实体中某个具体的属性

使用代理主键较好,方便后期修改属性

2.2 主键的生成策略

在Hibernate中,id元素的子元素用于生成持久化类的对象的主键生成策略

<!-- 主键生成策略 -->
     			<generator class="native"></generator>

hibernate提供了多种主键生成策略:

increment :
Hibernate中的自动增长机制,适用于short、int、long类型的主键。在单线程程序中使用。

identity :
数据库底层的自动增长机制,适合short、int、long类型的主键

sequence :
采用序列方式,适用于short、int、long类型的主键

uuid :
采用Hibernate中随机方式生成字符串主键,适用于字符串类型主键

native :
本地策略,在identity和sequence之间进行自动切换

assigned :
Hibernate不管理外键,需用户设置

foreign :
外部的,一对一的关系映射下使用

三、持久化类的三种状态

3.1 瞬时态(transient)

瞬时态:没有唯一标识OID,没有被session管理

3.2 持久态(persistent)

持久态:有唯一标识OID,被session管理

3.3 托管态(detached)

托管态:有唯一标识OID,没有被session管理

3.4 状态列子:

package com.hibernate.user.demo;

import java.io.Serializable;
import java.util.List;

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

import com.hibernate.utils.HibernateUtils;

/**
 * hibernate测试案例
 * 
 * @author cf
 *
 */
public class HibernateTestDemo01 {

	@Test
	// 保存用户
	public void demo01() {
		//获取连接
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		// 执行代码
		User user = new User(); //瞬时态对象:无OID,无session管理
		user.setName("星星");
		
		Serializable id = session.save(user); //持久态对象:有OID,被session管理
		
		session.get(User.class, id);
		
		// 事务提交
		transaction.commit();
		//资源释放
		session.close();
		
		System.out.println(user);//托管态对象:有OID,无session管理
	}
}

3.5 持久态对象特征:

持久态对象可以自动更新数据库

@Test
// 自动更新数据库
public void demo02() {
	//获取连接
	Session session = HibernateUtils.openSession();
	Transaction transaction = session.beginTransaction();
	// 执行代码
	User user = session.get(User.class, 1);
	user.setEmail("123456789@qq.com");
	user.setPassword("654321");
	user.setTelephone("13388888888");
	//session.update(user);  自动更新,此句可以省略
	
	// 事务提交
	transaction.commit();
	//资源释放
	session.close();
}

结果如下:
在这里插入图片描述
以上代码再重复执行一次,结果如下:

在这里插入图片描述
并无更新,仅执行查询。

底层原理为一级缓存,下一节介绍

四、一级缓存

Hibernate提供了一级缓存和二级缓存来提供应用程序的性能。本章先介绍一级缓存。

一级缓存:
session对象保存了一级缓存,默认情况下启用。不可用于整个应用程序,生命周期同session一致。

@Test
	// 一级缓存
	public void demo03() {
		// 获取连接
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		// 执行代码
		//第一次查询user
		User user = session.get(User.class, 1); 
		System.out.println(user);
		
		//第二次查询user
		User user1 = session.get(User.class, 1);
		System.out.println(user1);

		//判断两次user是否相同
		System.out.println(user == user1);
		// 事务提交
		transaction.commit();
		// 资源释放
		session.close();
	}

结果如下:
在这里插入图片描述
可以看出,结果查询语句仅执行了一次,第二次从一级缓存中取出。

使用session.clear()可以清空一级缓存

五、事务

事务具有ACID属性(原子性,一致性,隔离性和持久性)。

5.1 设置事务的隔离级别:

在核心配置文件hibernate.cfg.xml中使用一下语句配置隔离级别

<!-- 事务隔离级别 
		hibernate.connection.isolation - 4
		1 - Read uncommitted isolation
		2 - Read committed isolation
		4 - Repeatable read isolation
		8 - Serializable isolation
	-->
	<property name="hibernate.connection.isolation">4</property>

5.2 Service层使用事务

dao层和Service层需保证连接对象是同一个

1.HibernateUtils.java中增加getCurrentSession方法

package com.hibernate.utils;
/**
 * Hibernate的工具类
 * @author cf
 *
 */

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

public class HibernateUtils {
	public static final Configuration cfg;
	public static final SessionFactory sf;

static {
	cfg = new Configuration().configure();
	sf = cfg.buildSessionFactory();
}

public static Session openSession() {
	return sf.openSession();
}

public static Session getCurrentSession() {
	return sf.getCurrentSession();
}
}

2.核心配置文件增加以下配置

  <!-- 配置当前线程绑定的session -->
   <property name="hibernate.current_session_context_class">thread</property>

此时session在线程结束后会自动关闭,session.close()语句可以省略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值