Hibernate三种状态和Session常用的方法

我们知道hibernate的核心就是对数据库的操作,里面的核心接口就是org.hibernate.Session接口。要想对数据库操作我们就要理清楚对象在整个操作中的所属的状态(Transient,Persistent,Detached)。就像马士兵老师在视频中所说的,我们并不必死抠这些字眼,我们通过自己编写测试类就可以他们之间不同的区别。

其实三种状态各自的不必总结那么多,只是一个重要的地方就是Transient状态里面的对象是没有id的。

session中常用的方法是save(),update(),saveOrUpdate(),get(),load(),delete(),clear(),flush()这些

其中大学期间我其实对get和load方法都不是太熟悉,死记硬背才在考试中答题,现在想起完全没有这个必要。我们可以根据配置好的hibernate环境来进行junit测试。

首先我们进行get()方法进行测试。

这里我们首先建立一个实体类,StudentEntity.Java 和数据库中student所对应

package com.cwnu.entities;
import javax.persistence.*;
import java.io.Serializable;
/**
 * Created by yangy on 2015/12/19.
 */
@Table(name = "student")
@Entity
public class StudentEntity implements Serializable{
 private int id;
 private String name;
 @Id
 @Column(name = "id")
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 @Column(name = "name")
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}

junit类都是idea编译环境给我们配置好了,这里我们要注意,要使用getCurrentSession()来操作的话,我们首先要在Junit类中加上@Transaction注解,下面是相关的测试方法:

 @Test
public void testGetOrLoad() {
 Session session = sessionFactory.getCurrentSession();
 StudentEntity student = (StudentEntity)session.get(StudentEntity.class, 1);
 //StudentEntity student_load = (StudentEntity)session.load(StudentEntity.class,1); String name = student.getName();
} 

先测试get方法,我们发现一旦我们只是拿student这个实体操作,get方法是会输出相关的sql查询语句的,而我们注释掉get方法,换load方法的话,load方法执行拿student这个实体的数据是没有输出相应的sql语句的。但是我们在对student类进行操作的时候,这时才输出相关的语句.

所以我们看出get()和load()之间的差别:

get()每次执行都会执行sql语句,不会延迟。load()方法只是会在我们对拿到的实体进行操作的时候才去执行查询,拿到相应的实体信息。load方法返回的是一个代理对象(马士兵老师视频)。无论是get还是load首先都会查一级缓存(session)中有没有相应的对应值,如果没有,再去数据库进行查找。

clear()方法是对session里面的缓存进行了清理,测试这个方法我们可以根据下面的Junit进行测试:

@Test
 public void testClear() {
  Session session = sessionFactory.getCurrentSession();
  session.get(StudentEntity.class,1);
  session.clear();
  session.get(StudentEntity.class,1);
 } 

如果我们把session.clear()注释掉的话,我们就可以看到只执行了一条sql语句

flush()方法是是对数据库同步的一条语句,执行完这个后立即刷新到数据库。粗浅的来看哈,其实里面还是有很多东西,比如FlushMode这个类,我们默认设置的是FlushMode.AUTO,这个一般不修改,只是为了以后的性能调优。其实我们在执行事务的时候,事务完成之后它会帮我们执行flush()方法。只是我们在进行大规模插入的时候,我们经常可以看到下面的操作:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) {
//20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}}
tx.commit();session.close(); 

这样做的目的就是避免大量插入,造成session里面内存溢出,所以我们定时清理一下就可以避免这个问题。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • 深入理解hibernate的三种状态

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别,比如瞬时状态就是刚new出来一个对象,还没有被保存到数据库中,持久化状态就是已经被保存到数据库中,离线状态就是数据库中有,但是session中不存在该对象.但是大家又是否对hibernate的session的那几个特殊方法一清二楚呢?或者说大家是否能够一眼就快速看出一个测试用例在反复的调用sess

  • hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更改后的数据却神奇的保存到数据库里面去了. 最后简单粗暴的解决办法是把这份从数据里面查出来的List  复制了一份,然后再操作,再返回.数据就正常了,数据库也没更新.后面找了资料才发现是jpa是对hibernate的封装,底层是hibernate,这是hibernate的持久状态搞的鬼. 二.hibe

  • Hibernate三种状态和Session常用的方法

    我们知道hibernate的核心就是对数据库的操作,里面的核心接口就是org.hibernate.Session接口.要想对数据库操作我们就要理清楚对象在整个操作中的所属的状态(Transient,Persistent,Detached).就像马士兵老师在视频中所说的,我们并不必死抠这些字眼,我们通过自己编写测试类就可以他们之间不同的区别. 其实三种状态各自的不必总结那么多,只是一个重要的地方就是Transient状态里面的对象是没有id的. session中常用的方法是save(),updat

  • 浅谈Java实体对象的三种状态以及转换关系

    最新的Hibernate文档中为Hibernate对象定义了四种状态(原来是三种状态,面试的时候基本上问的也是三种状态),分别是:瞬时态(new, or transient).持久态(managed, or persistent).游状态(detached)和移除态(removed,以前Hibernate文档中定义的三种状态中没有移除态),如下图所示,就以前的Hibernate文档中移除态被视为是瞬时态. 瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区

  • java 三种将list转换为map的方法详解

    java 三种将list转换为map的方法详解 在本文中,介绍三种将list转换为map的方法: 1) 传统方法 假设有某个类如下 class Movie { private Integer rank; private String description; public Movie(Integer rank, String description) { super(); this.rank = rank; this.description = description; } public Int

  • 浅谈三种配置linux环境变量的方法(以java为例)

    1. 修改/etc/profile文件 如果你的计算机仅仅作为开发使用时推荐使用这种方法,因为所有用户的shell都有权使用这些环境变量,可能会给系统带来安全性问题. ·用文本编辑器打开/etc/profile ·在profile文件末尾加入: export JAVA_HOME=/usr/share/jdk1.6.0_14 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/li

  • 三种Java自定义DNS解析器方法与实践

    目录 1.InMemoryDnsResolver 2.SystemDefaultDnsResolver 3.自定义DnsResolver 4.连接池管理器 5.测试 前言: 最近终于用上了高性能的测试机(54C96G * 3),相较之前的单机性能提升了三倍,数量提升了三倍,更关键的宽带提单机升了30倍不止,总体讲提升了100多倍,这下再也不用担心单机压力机瓶颈,直接原地起飞. 不过没高兴5分钟,我发现接口居然请求不通,经过一阵拨乱反正终于找到原因:域名无法解析,IP无法直接访问. 自然而然,解决

  • 三种获取网页源码的方法(使用MFC/Socket实现)

    第一个方法是使用MFC里面的 <afxinet.h> 复制代码 代码如下: CString GetHttpFileData(CString strUrl){     CInternetSession Session("Internet Explorer", 0);     CHttpFile *pHttpFile = NULL;     CString strData;     CString strClip;     pHttpFile = (CHttpFile*)Ses

  • Bootstrap三种表单布局的使用方法

    Bootstrap提供了三种表单布局:垂直表单,内联表单和水平表单  创建垂直或基本表单:  •·向父 <form> 元素添加 role="form".  •·把标签和控件放在一个带有 class .form-group 的 <div> 中.这是获取最佳间距所必需的.  •·向所有的文本元素 <input>.<textarea> 和 <select> 添加 class .form-control <form role=&

  • MySql三种避免重复插入数据的方法

    前言 MySql 在存在主键冲突或唯一键冲突的情况下,根据插入方式,一般有以下三种插入方式避免错误. insert ignore. replace into insert on duplicate key update insert ignore insert ignore 会忽视数据库中已经存在的数据,根据主键或者唯一索引判断,如果数据库没有数据,就会插入新的数据,如果有数据的话就跳过这条数据 小case 表结构 root:test> show create table t3G *******

随机推荐