上篇文章讨论了Hibernate持久对象的生命周期,在整个生命周期中一个对象会经历三个状态,三种状态的转换过程在开发过程中是可控的。并且是通过用法来控制它们的转化过程。详细的转化过程今天就来着重讨论下。

二、状态转化方法

前面说到对象之间的转化过程是通过用法来实现的,这些方法是非常重要的。先看张图

上面这张图在三篇文章中都实用到,它具体描写叙述了持久对象三种状态的转换过程及具体的转化方法。另外还有垃圾回收器,对象在瞬态和脱管状态下假设长时间不适用将会在某一时刻被Java回收器回收,消亡。

1、对象直接进入Persistent状态

1.1 get方法

从数据库中获取一行信息。并将该信息同步到创建的对象中,该方法返回一个Object对象,假设没有查询到内容则返回null。以下的实例通过採用Session的get方法来获取一个对象。并将对象转换为实例。

public void testGet1(){
Session session=null;
Transaction tx = null;
try{
session=HibernateUtils.getSession();
//开启事务
tx= session.beginTransaction();
//get载入上来的对象为持久对象
//运行get会立即发出查询语句。假设不存在会返回null
User user=(User)session.get(User.class,"ff80808145bc28cc0145bc28ce020002");
System.out.println(user.getName()); //persistent状态
//persistent状态的对象,当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
user.setName("赵柳"); session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}

设置断点。获取User对象。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

获取到了该对象,通过强制转换后得到了一个user对象。程序中加入了setName方法,也就是说会更新数据库中的名称。运行完毕后检查数据库,例如以下图更新结果。                       

1.2 load方法

功能类似于get方法,也是从数据库中获取数据并同步到对象中,该方法支持lazy是一种懒汉操作,它返回的是一个持久化的Object对象或者一个代理,所以须要进行转化。

public void testLoad1(){
Session session=null;
try{
session=HibernateUtils.getSession();
//不会立即查询语句,由于load支持lazy(延迟载入/懒载入)
//什么教lazy?仅仅有真正使用这个对象的时候。再创建,对于Hibernate来说
//才真正发出查询语句,主要为了提高性能,lazy是Hibernate中很重要的特性
//Hibernate的lazy是怎样实现的?採用代理对象实现。代理对象主要採用的是CGLIB库生成的
//而不是JDK的动态代理。由于JDK的动态代理仅仅能对实现了借口的类生成代理,CGLIB能够对类生成
//代理。它採用的是继承方式
User user=(User)session.load(User.class,"8a1b653745bcc7b50145bcc7b7140001");
System.out.println(user.getName()); //persistent状态
//persistent状态的对象,当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候。会和数据库同步
user.setName("zhaoliu"); session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
}finally{
HibernateUtils.closeSession(session);
}
}

查询获取该User对象例如以下图:



        分析上图,获取的User对象并不完整。或者说并没有常见一个User对象。更是一种代理,它使用了CGLIB来预载入对象,仅仅有在使用该对象时才真正创建。

1.3 Get Vs load

get和load方法非常重要。在面试Hibernate时常常会考到,以下对照下两者。

同样点:(1)功能同样,将关系数据转化为对象;

(2)用法相同。相同须要制定两个參数

       不同点:(1)load方法支持lazy操作。预载入对象。在使用时才创建。get是直接将关系数据转化为对象;

(2)load载入对象假设不存在会抛出objectNotFoundException异常,get假设没有获取数据会返回null。

2、手动构造detached对象

想要获取对象还有第二种方法。它差别于get与load方法。是一种手动获取的方法,首先常见一个对象,然后通过制定id的方式获取该对象的数据。方法例如以下:

public void testUer(){
Session session=null;
try{ session=HibernateUtils.getSession();
session.beginTransaction(); //手动构造detached对象
User user=new User();
user.setId("8a1b653745bcc7b50145bcc7b7140001"); //persistent状态
//persistent状态的对象,当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候。会和数据库同步
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
}finally{
HibernateUtils.closeSession(session);
}
}

查看获取的结果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

                    

       分析结果图,代码中使用了setId方法为该对象制定了id号。在制定id号后就行对该对象进行操作,在事务提交后同步到数据库中,採用了手动指定,手动指定了对象的信息。

2.1 Delete方法

删除数据库中指定的对象,在删除前必须将对象转化到Persistent状态,能够使用get、load或者手动的方法指定对象,用法例如以下代码:

session=HibernateUtils.getSession();
session.beginTransaction();
User user=(User)session.load(User.class,"8a1b653745bcc6d50145bcc6d67a0001");
//建议採用此种方式删除,先载入再删除
session.delete(user);

2.2 Update

更新数据。该方法会改动数据库中的数据。在使用的时候会出现量中情况。更新数据库某个字段值或者更新数据库的整行值

2.2.1  更新某个字段值

假设仅仅想要更新某个字段的值,在update前。须要使用load或者get方法使对象转化为persistent状态代码例如以下:

//获取session对象
session=HibernateUtils.getSession();
//开启事务
session.beginTransaction();
//或者能够使用另外的方法开启
//session.getTransaction().begin(); //载入获取User对象
//方法一:使用load方法
//User user=(User)session.load(User.class, "8a1b653745bcc7b50145bcc7b7140001");
//方法二:手动获取
User user=new User();
user.setId("8a1b653745bcc7b50145bcc7b7140001"); //更新姓名
user.setName("zhangsan");
session.update(user);
session.getTransaction().commit();

2.2.2 更新整行

想要更新整行的数据,能够採用手动将状态转换到detached状态。手动指定对象的id值,代码例如以下:

//获取session对象
session=HibernateUtils.getSession();
//开启事务
session.beginTransaction();
//或者能够使用另外的方法开启
//session.getTransaction().begin(); //手动获取
User user=new User();
user.setId("8a1b653745bcc7b50145bcc7b7140001"); //更新姓名
user.setName("zhangsan");
session.update(user);
session.getTransaction().commit();

查看更新结果:



      分析更新结果,它事实上更新了数据库的整行数据,这样的更新操作有太多的不确定因素,不建议使用。

2.3 save方法

插入数据。

在运行save方法时会调用数据库的insert语句,向数据库中加入新的一行。save后的对象会转化为持久态,在此状态下的对象可以再次更新对象,在最后提交事务时会同更改更新到数据库。例如以下:

public void testSave2(){
Session session=null;
Transaction tx = null;
try{
session=HibernateUtils.getSession();
//开启事务
tx= session.beginTransaction(); //Transient状态
User user=new User();
user.setName("zhangsi");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date()); //persistent状态
//persistent状态的对象。当对象的属性发生改变的时候
//Hibernate在清理缓存(脏数据检查)的时候。会和数据库同步
session.save(user);
user.setName("lisi"); tx.commit(); }catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
} //detached状态
}

查看上例执行结果视图:



        分析结果:session在提交事务的时候事实上做了两部的操作,结合代码中的更新过程,首先是新增了一个User对象,之后运行了save操作,它会调用insert语句。然后在代码中做了一个setName的操作,又一次改动了名称。但这时还没有同步到数据库中而是在内存中。这时就会有两种状态。我们称此时的数据位脏数据,最后提交事务的时候更新到数据库中。

结语

本文针对持久对象的转化方法展开了具体的讨论。一个对象在整个生命周期中有三种状态。文章讨论至此。核心对象和持久对象的讨论已经完毕。核心对象构成了Hibernate的内部执行机制,持久对象是关系模型和对象模型进行转化的核心。

【Hibernate步步为营】--核心对象+持久对象全析(三)的更多相关文章

  1. 【Hibernate步步为营】--核心对象+持久对象全析(一)

    引言         上篇博客对Hibernate进行了基本的解析.并分析了它的一些特性. Hibernate可以如此的流行也是由于它有诸多长处,不论什么事物都有两面性.Hibernate尽管流行.可 ...

  2. 【Hibernate步步为营】--核心对象+持久对象全析(二)

    上篇文章讨论了Hibernate的核心对象,在开发过程中经经常使用到的有JTA.SessionFactory.Session.JDBC,当中SessionFactory可以看做数据库的镜像,使用它可以 ...

  3. Hibernate的核心对象关系映射

    Hibernate的核心就是对象关系映射: 加载映射文件的两种方式: 第一种:<mapping resource="com/bie/lesson02/crud/po/employee. ...

  4. hibernate在持久对象的生命周期(三州:自由状态,持久状态,自由状态 之间的转换)

    三种状态的基本概念: 1.  临时身份(Transient):也被称为自由状态,它只存在于内存中,并且在数据库中没有相应的数据. 使用new创建的对象,久化,没有处于Session中,处于此状态的对象 ...

  5. Hibernate入门(3)- 持久对象的生命周期介绍

    在hibernate中对象有三种状态:瞬时态(Transient). 持久态(Persistent).脱管态或游离态(Detached).处于持久态的对象也称为PO(Persistence Objec ...

  6. Hibernate(开放源代码的对象关系映射框架)

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...

  7. JavaEE之Hibernate(开放源代码的对象关系映射框架)

    Hibernate(开放源代码的对象关系映射框架) 1.简介 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全 ...

  8. Hibernate一级缓存Session和对象的状态

    建议看原文:https://blog.csdn.net/qq_42402854/article/details/81461496 一.session简介        首先,SessionFactor ...

  9. Hibernate的session缓存和对象的四种状态

    一.session缓存 说session缓存就得说到JAVA对象的生命周期,当没有任何引用指向一个对象时,对象则可以被gc回收,也就是生命周期结束了 而hibernate获取一个对象后,会将对象存入s ...

随机推荐

  1. 【SDOJ 3741】 【poj2528】 Mayor's posters

    Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...

  2. JDBC 学习笔记(五)—— Statement

    JDBC 使用 Statement 作为 SQL 语句的执行器. Statement 通过 Connection.createStatement() 方法创建,一共支持以下6种方式执行 SQL 语句: ...

  3. formData使用总结

    1.formData基本使用 //可以从form元素初始化一个FormData对象,或者new一个空对象 var formData = new FormData([fromElement]); //可 ...

  4. d3 添加元素相关api

    选择元素 d3.select([dom]) d3.selectAll([dom]) 添加元素 d3.select("body").append("p") 插入内 ...

  5. jQuery控件之分页控件-- kkpager v1.3使用简介

    js分页展示控件,传入简单参数就能使用的分页效果控件 在线测试链接: http://pgkk.github.io/kkpager/example/pager_test.html http://pgkk ...

  6. FootAwesome字体图标

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 学习javascript设计模式之装饰者模式

    1.装饰者模式定义:给对象动态添加职责的方式称为装饰者(decorator)模式. js如何实现装饰者模式 通过保存原函数引用方式改写某函数 window.onload = function(){al ...

  8. django:访问本地静态文件的配置

    1.在setting.py中新增如下配置,static为静态文件的目录,BASE_DIR为项目根目录 STATIC_URL = '/static/' STATIC_ROOT = os.path.joi ...

  9. 标准C程序设计七---70

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  10. Day 15 python 之 列表、元组、字典

    基础: #! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "DaChao" # Date: 2017/6/ ...