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操作

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

  1. Hibernate中持久化类与持久化对象

    1.JavaBean类 JavaBean类是实体类,必须一下属性,private修饰的成员属性,public修饰的getter与setter访问方法,public修饰的空参构造器,实现Serializ ...

  2. java框架之Hibernate(2)-持久化类&主键生成策略&缓存&事务&查询

    持久化类 概述 持久化:将内存中的对象持久化到数据库中的过程就是持久化.Hibernate 就是用来进行持久化的框架. 持久化类:一个 Java 对象与数据库的表建立了映射关系,那么这个类在 Hibe ...

  3. hibernate的持久化类、主键生成策略

    一.hibernate的持久化类 1.什么是持久化类: 持久化:将数据存储到关系型数据库. 持久化类:与数据库中的数据表建立了某种关系的java类.(持久化类=javabean+映射配置文件) 2.持 ...

  4. Hibernate的持久化类状态

    Hibernate的持久化类状态 持久化类:就是一个实体类 与 数据库表建立了映射. Hibernate为了方便管理持久化类,将持久化类分成了三种状态. 瞬时态 transient (临时态):持久化 ...

  5. Hibernate学习——持久化类的学习

    A.概念 持久化:将内存中的对象持久化(存储)到数据库的过程.Hibernate就是持久化的框架. 持久化类:一个普通java对象与数据库的表建立了映射关系,那么这个类在Hiberna中被称为持久化类 ...

  6. hibernate 中持久化标识 OID

    OID 全称是 Object Identifier,又叫做对象标识符 是 hibernate 用于区分两个对象是否是同一个对象的标识的方法 标识符的作用:可以让 hibernate 来区分多个对象是否 ...

  7. hibernate学习(三) hibernate中的对象状态

    hibernate对象的状态分为三种:  游离状态,持久化状态,瞬时状态 下面一行代码区分: Configuration   cfg=new Configuration().configure(); ...

  8. hibernate中java类的成员变量类型如何映射到SQL中的数据类型变化

    hibernate映射文件??.hbm.xml配置映射元素详解--Hibernate映射类型 在从Hibernate的java的成员类型映射到SQL中的数据类型,其内映射方式它满足,SQL可以自己调制 ...

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

    三态的基本概念: 1,  暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象 ...

随机推荐

  1. C#break和continue学习

    一,代码 static void Main(string[] args) { ; while (true) { int num = Convert.ToInt32(Console.ReadLine() ...

  2. Java面试之String、StringBuffer和StringBuilder的区别和原理

    首先我们先来谈谈String: String 对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象,即修改了 String 的引用. 因为 String 的底层是用数组来 ...

  3. Springboot整合Hikari数据库连接池,密码加密

    1.application.yml配置 spring: datasource: jdbcUrl: jdbc:mysql://127.0.0.1:3306/jby?serverTimezone=UTC& ...

  4. 将一个对象赋值给另一个对象(使用element CheckBox中length报错)

    注意两个对象相似(比如form表单),千万不要直接赋值(会把对象的属性也变化),很容易漏掉一些属性.比如此次CheckBox报length的错误,就是因为用于存放checkbox复选框选项的数组进过赋 ...

  5. javax.net.ssl.SSLKeyException: RSA premaster secret error

    环境jdk1.7, 调用第三方接口时,出现javax.net.ssl.SSLKeyException: RSA premaster secret error错误,解决方案,将jre/lib/ext所有 ...

  6. windows 安装 jenkins笔记

    Jenkins 所有镜像列表: http://mirrors.jenkins-ci.org/status.html 可在镜像网站上下载安装文件,比官方下载快些 jenkins 官网地址: https: ...

  7. 【leetcode】999. Available Captures for Rook

    题目如下: On an 8 x 8 chessboard, there is one white rook.  There also may be empty squares, white bisho ...

  8. boost multi index

    Boost.MultiIndex makes it possible to define containers that support an arbitrary number of interfac ...

  9. HTTP详解教程 / HTTP 响应头信息 HTTP 响应头信息

    HTTP请求头提供了关于请求,响应或者其他的发送实体的信息. 在本章节中我们将具体来介绍HTTP响应头信息.直线电机哪家好 应答头 说明 Allow 服务器支持哪些请求方法(如GET.POST等). ...

  10. QGroundControl编译出错记录

    运行时出现错误: /home/myfly2/Downloads/qgroundcontrol/QGroundControl: error : cannot open shared object fil ...