Hibernate学习笔记(二)

本文深入解析Hibernate框架,涵盖主键生成策略、持久化类状态、一级缓存机制、事务管理等核心概念,助您掌握Hibernate的高效应用。

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

目录

 

一 、主键的分类

二 、主键的生成策略

三 、持久化类的三种状态

四 、一级缓存

五 、事务管理


一 、主键的分类

(1)、自然主键 :以表中的一个字段为主键

(2)、代理主键 :自定义一个与表中不相关的一个字段为主键

 

二 、主键的生成策略

 increment   :hibernate 中提供的自动增长机制 ,由Hibernate发送语句从数据库中查出主键的最大值(每个session只查1                                   次),以 该值为基础,每次增量+1,在内存中生成主键,在单线程中使用,适用于 short  、int 、long 类型的主                           键。

 identity       :适用于 short  、int 、long 类型的主键。使用的是数据库底层的自动增长机制 ,因此适用于有自动增长机制的数                            据 库(MySQL),不适用于Oracle,因为Oracle没有自动增长 ,是采用序列的方式 。 

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

 uuid            :随机生成字符串类型的主键

 native         :根据使用的数据库自行判断采用identity、sequence其中一种作为主键生成方式 

 assigned    :Hibernate不负责维护主键生成,需要手动设置

 

在映射配置文件中设置主键的生成策略,代码如下 :  <generator class="native"/>

<?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>
	<!-- 建立类与表的映射 -->
	<class name="czm.hibernate.demo.User" table="UserData">  //全路径+类名称 , 数据库表名称



		<!-- 建立类中的属性与表中的主键对应 -->
		<id name="uid" column="uid" >
                <!-- 定义主键生成策略 -->
			<generator class="native"/>
		</id>
		


		<!-- 建立类中的普通的属性和表的字段的对应 -->
		<property name="username" column="username" length="32" />
		<property name="age" column="age"/>
		<property name="password" column="password"/>
		<property name="phone" column="phone"/>
		<property name="address" column="address"/>
	</class>
</hibernate-mapping>

 

三 、持久化类的三种状态

1 、瞬时态 :此对象没有唯一的标识 id ,没有被 session 管理 ,称为瞬时态对象

2 、持久态 :此对象有唯一标识 id ,并且被 session 管理 ,称为持久态对象

3 、脱管态 :此对象有唯一标识 id ,但没有被 session 管理 ,称为脱管态对象 

	public void demo(){
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		User user = new User (); //瞬时态对象 :没有唯一id ,没被session管理
		user.setName("张三");

                Serializable id = session.save(user);  //持久态对象:有唯一id ,被session管理
				
		transaction.commit();
		session.close(); //session失效

                System.out.println("姓名 :" + user.getName()); //脱管态对象:有唯一标识 ,没被 session 管理

	}

四 、一级缓存

  1.       Hibernate中的一级缓存,也叫做session的缓存,它可以在session范围内减少数据库的访问次数,当执行一次查询操作的时候,执行第二次查询操作,先检查缓存中是否有数据,如果有数据就不查询数据库,直接从缓存中获取数据。
  2.      一级缓存只在session范围内有效,session关闭,一级缓存失败。
  3.      session的缓存是由hibernate维护的,用户不能操作缓存内容;如果想操作缓存内容,必须通过hibernate提供的 evict / clear方法操作
  • session.flush();  :让一级缓存与数据库同步;
  • session.evict();  :清空一级缓存中指定的对象;
  • session.clear();  :清空一级缓存中所有的对象;

备注 :不同的session不会共享缓存数据

 

五 、事务管理

    1 、事务概述 :事务就是指作为单个逻辑工作单元执行的一组数据操作,这些操作要么必须全部成功,要么必须全部失败,以保证数据的一致性和完整性。

    2 、事务属性

  •        原子性 :在事务中的所有操作要么都发生,要么都不发生。
  •       一致性  :事务执行前后 ,数据的完整性保持一致
  •       隔离性  :事务执行过程中 ,不应该受到其它事务的干扰
  •       持久性  :事务执行完成 ,数据持久化

 

  如果不考虑隔离性,会引发的安全性问题如下:

  •       脏读:一个事务读到另一个事务未提交的更新数据。
  •       幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
  •       不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
  •       第一类丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。
  •       第二类丢失更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据。

   4 、为了解决多个事务并发会引发的问题 ,应该设置事务的隔离级别 :

  •      Read Uncommitted:以上读的问题都有可能发生。隔离级别最差
  •      Read Committed:解决脏读,但幻读和不可重复读有可能发生  (一般用于Oracle)
  •      Repeatable Read:解决脏读和不可重复读,但幻读有可能发生   (一般用于MySQL)
  •      Serializable:解决所有读的问题,隔离级别最高, 但效率低 

   5 、在Hibernate的配置文件中设置隔离级别。每一种隔离级别对应着一个正整数。

  •     Read Uncommitted: 1
  •     Read Committed: 2
  •     Repeatable Read: 4
  •     Serializable: 8

在hibernate.cfg.xml中设置隔离级别代码如下:

<session-factory>
<!-- 设置事务的隔离级别 -->
<property name="hibernate.connection.isolation">4</property>
</session-factory>

    6  、线程绑定的 session :保证业务逻辑层与数据持久层是同一个事务连接对象

(1) 、在hibernate核心配置文件中配置 Session对象与本地线程进行绑定。

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

(2)、编写工具类 HibernateUtils

package czm.hibernate.utils;
 
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 sfa;
	
	static{
		cfg = new Configuration().configure();
		sfa = cfg.buildSessionFactory();
	}
	
	public static Session openSession(){
		return sfa.openSession();
	}


    public static Session getCurrentSession(){  //在工具类里面获取与本地线程绑定的session。
        return sfa.getCurrentSession();
    }



}

   (3) 、 编写测试类

	public void testdemo(){
		Session session = HibernateUtils.getCurrentSession(); //调用getCurrentSession()方法
		Transaction ts = session.beginTransaction();
		
		User user = new User ();
		user.setName("张三");
		Serializable name = session.save(user);
		
		ts.commit();
	      //session.close();  //绑定了本地线程的session后,无需手动关闭session,线程关闭,session也就被关闭了
	}

  注意 :绑定了本地线程的session是不用我们自己去关闭的!!!当本地线程被关闭后,session也就自然而然的被关闭了。如果我们的sesson是没有与本地线程绑定的,是通过sessionFactory.openSession()获取的,那么就要我们自己手动进行关闭。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值