三、hibernate中持久化类的使用

hibernate的持久化类

  • 持久化:将内存中的一个对象持久化到数据库中的过程,hibernate就是一个用来进行持久化的框架
  • 持久化类:一个Java对象与数据库中表建立了关系映射,那么这个类在hibernate中就可以称之为持久化类
    • Java实体类
    • 该Java类的映射文件 

持久化类的使用 

提供无参构造

从之前测试类中查询的使用来看:

User user = session.get(User.class, 1);

说明hibernate内部是使用反射技术实现生成对象实例,所以持久化类中的Java实体类必须提供一个无参构造

定义私有属性,公有的getter/setter方法

hibernate生成对象实例时,需要获取、设置属性值

定义唯一标识属性OID(对应数据库表中的主键)

  • hibernate缓存是一个map,他会根据OID作为缓存对象的key,我们的映射文件中<id>标签指定的属性值会作为OID
  • Java对象通过地址来定位一个对象,数据库的表中通过主键来定位到一条数据记录
  • hibernate中通过持久化类的唯一标识属性来定位一个对象

例如User中的id

public class User {

	private Integer id;
	private String name;
	private String password;
	......
} 

映射文件配置id属性

<hibernate-mapping>
	<!-- 配置表与实体的映射关系 -->
	<class name="com.qf.entity.User" table="user">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		......
	</class>
</hibernate-mapping>

属性定义最好使用包装类

因为基本数据类型默认值是0,容易出现很多问题

例如:

  • 保存数据时,id属性如果没有设置具体值,默认使用0,保存两次就会出现异常
  • 表中某些字段值是0,无法区分是没存值还是存的值就是0

最好不要使用final修饰持久化类

  • 主要原因是影响延迟加载的使用,延迟加载是用于优化hibernate的
  • 延迟加载返回的是一个代理对象,hibernate延迟加载是使用javassist技术来实现的
  • javassist可以对没有实现接口的类产生代理,使用字节码增强技术继承这个类并进行代理
  • final修饰的类无法被继承,那么就无法产生代理对象,也就不能做延迟加载了(get方法和load方法的查询完全一致)

主键

主键分类

  • 自然主键:就是充当主键的字段本身具有一定的含义,是构成记录的组成部分,比如学生的学号,除了充当主键之外,同时也是学生记录的重要组成部分
  • 代理主键:就是充当主键的字段本身不具有业务意义,只具有主键作用,比如自动增长的ID
  • 实际开发中推荐使用代理主键,因为不涉及业务逻辑,后期不会发生修改源代码的情况(OCP原则)

主键生成策略

<hibernate-mapping>
	<!-- 配置表与实体的映射关系 -->
	<class name="com.qf.entity.User" table="user">
		<id name="id" column="id">
			<!-- 主键生成策略 -->
			<generator class="native"></generator>
		</id>
		<property name="name" column="name"/>
		<property name="password" column="password"/>
	</class>
</hibernate-mapping>

increment

  • 由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1
  • 适用于int、short、long类型的主键
  • 线程不安全,适用于单线程程序

identity

  • identity由底层数据库生成标识符

    • identity是由数据库自己生成的,但这个主键必须设置为自增长,使用identity的前提条件是底层数据库支持自动增长字段类型
    • 适用DB2、SQL Server、MySQL、Sybase和HypersonicSQL,不适用Oracle
  • 适用于int、short、long类型的主键
  • 线程安全

sequence

  • 采用数据库提供的sequence机制生成主键,需要数据库支持sequence
  • oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence适用,Mysql不适用 
  • 适用于int、short、long类型的主键

uuid

  • Hibernate在保存对象时,生成一个UUID字符串作为主键,保证了唯一性,但其并无任何业务逻辑意义,只能作为主键
  • 唯一缺点长度较大,32位(Hibernate将UUID中间的“-”删除了)的字符串,占用存储空间大
  • Hibernate在维护主键时,不用去数据库查询,从而提高效率,而且它是跨数据库的,以后切换数据库极其方便

native(常用)

  • native由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强

assigned

  • Hibernate不负责维护主键生成
  • 人为控制主键生成,存储对象前,必须要使用主键的setter方法给主键赋值

foreign

  • 使用另外一个相关联的对象的主键作为该对象主键
  • 主要用于一对一关系中

持久化类的状态

状态

  • 瞬时态:没有唯一标识OID(映射到数据库表的主键上具体的值),也不被session管理
  • 持久态:有唯一标识OID,被session管理
  • 脱管态:有唯一标识OID,不被session管理
        @Test
	public void save(){
		Session session = SessionFactoryUtil.getSession();

		Transaction ts = session.beginTransaction();
		//瞬时态对象:新建对象,还没有唯一标识OID,也没有被session对象管理
		User user = new User("hz", "0");

		//持久态对象:有唯一标识OID,并且被session对象管理
		Serializable save = session.save(user);
		System.out.println("user:"+user);

		ts.commit();
		session.close();

		//脱管态对象:session销毁了,不被session对象管理,但是还有唯一标识OID
		System.out.println("user:"+user);
	}

几种状态的转换

瞬时态对象

获取:User user = new User();

转换

  • 转换成持久态对象:save()、saveOrUpdate()
  • 转换成脱管态对象:user.setId(2);

持久态对象

获取:get()、load()、find()、iterate()

转换

  • 转换成瞬时态对象:delete()
  • 转换成脱管态对象:
    • session.close():销毁session对象
    • session.clear():清空所有对象
    • session.evict(obj):清空某一个对象

脱管态对象

获取:User user = new User(3,"","");或者User user = new User(); user.setId(3);

转换

  • 转换成瞬时态对象:user.setId(null);
  • 转换成持久态对象:update()、saveOrUpdate()、lock()

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

        @Test
	public void test(){
		Session session = SessionFactoryUtil.getSession();
		Transaction ts = session.beginTransaction();

		//获得持久化对象
		User user = session.get(User.class, 1);
		System.out.println("name:"+user.getName());
		user.setName("test");

		ts.commit();
		session.close();
	}

  控制台输出

Hibernate:
    select
        user0_.id as id1_0_0_,
        user0_.name as name2_0_0_,
        user0_.password as password3_0_0_
    from
        user user0_
    where
        user0_.id=?
name:wxf
Hibernate:
    update
        user
    set
        name=?,
        password=?
    where
        id=?

再次执行test()方法,console输出

Hibernate:
    select
        user0_.id as id1_0_0_,
        user0_.name as name2_0_0_,
        user0_.password as password3_0_0_
    from
        user user0_
    where
        user0_.id=?
name:test
  • 测试方法中并没有做update操作,但是执行了update操作,是因为get方法获取的user是持久化对象,可以自动更新数据库
  • 如果setName方法设置的值和数据库里的name一样,也不会执行update操作

原文地址:https://www.cnblogs.com/qf123/p/10150561.html

时间: 2024-10-03 13:38:50

三、hibernate中持久化类的使用的相关文章

hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)

三态的基本概念: 1,  暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象: 2,  持久化状态(Persistent):与session关联而且在数据库中有对应数据.已经持久化,添?到了Session缓存中.如通过hibernate语句保存的对象.处于此状态的对象叫持久对象: 3,  游离状态(Detached):持久化对象脱离了Session的对象.如Session缓

hibernate中持久化类映射到数据表的注意事项。

在web项目中,我们用到hibernate的话要先在用java语言创建一个持久化的bean类,然后在映射到数据库中的表! 在这里我要说的是这个数据表的创建 应该使用SQL的DDL语言来完成,不要用management studio,我在做项目的时候用management studio建表导致id主键和java持久化类当中的id不匹配.报了很多错误,所以写此随笔作为警示. 我的栗子! 先贴我的映射文件 1 <?xml version="1.0" encoding="UTF

hibernate中实体类注解

一.JPA通用策略生成器 通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, 其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出. Target({METHOD,FIELD}) @Retention(RUNTIME) public @interface GeneratedValue{ G

hibernate中Configuration类的作用

问题:我们在获得一个SessionFactory对象的时候经常是写下面这行代码: 1 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); 那么这行代码到底有什么作用,Configuration的对象的作用是什么? 要回答上述问题必须首先知道Configuration对象的作用. Configuration的作用是:An instance of org.hibernate.cf

hibernate中持久化对象的生命周期(转载)

三态的基本概念 1, 临时状态(Transient):也叫自由态,只存在于内存中,而在数据库中没有相应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象: 2, 持久化状态(Persistent):与session关联并且在数据库中有相应数据.已经持久化,加入到了Session缓存中.如通过hibernate语句保存的对象.处于此状态的对象叫持久对象: 3, 游离状态(Detached):持久化对象脱离了Session的对象.如Session缓存被清空的

hibernate中实体类对象的四种状态

1.临时状态(transient):用new语句创建,还没有被持久化,并且不在Session的缓存中. 标识:OID为null,没有和Session建立关系.2.持久化状态(persistent):已经计划被持久化,并且加入到Session的缓存中.(为什么说计划:因为事务问题,是否已经提交事务)标识:OID不为null,建立了和Session的关系.3.删除状态(removed):(可以不管,如果说三种状态,就是没有此种)不在Session的缓存中,且Session已经计划将其从数据库中删除.

Hibernate中持久化注解的java文件在applicationContext.xml中的配置

之前用Hibernate操作数据库,都是写下.hbm.xml配置文件的.这段时间发现注解要比.hbm.xml方便很多时,决定用注解. 之前用.hbm.xml时,在applicationContext.xml里配置是: <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="da

(转) Hibernate持久化类与主键生成策略

http://blog.csdn.net/yerenyuan_pku/article/details/65462930 Hibernate持久化类 什么是持久化类呢?在Hibernate中持久化类的英文名称是Persistent Object(简称PO),PO=POJO+hbm映射配置文件. 对于Hibernate中的PO,有如下编写规则: 必须提供一个无参数的public构造方法. 所有属性要用private修饰,对外提供public的get/set方法. 在PO类必须提供一个标识属性,让它与

笔记:Hibernate 持久化类标注说明

持久化类标注 标注 @Entity:注解声明该类是一个Hibernate的持久化类 标注 @Table:指定该类映射的表 参数 name:指定映射数据库表的名称 参数 uniqueConstraints:为持久化类所映射的表设置唯一约束,该属性的值是 @UniqueConstraint 标注数组 参数 indexes:为持久化类说映射的表设置索引,该属性的值是 @Index 标注数组 参数 catalog:设置持久化类说映射的表放入指定的 catalog 中,没有指定则放入默认 catalog