Session接口是Hibernate向程序提供操纵数据库的最主要接口,是单线程对象,它提供了基本的保存、更新、删除和查询方法。它有一个缓存,保存了持久化对象,当清理缓存时,按照这些持久化对象同步更新数据库。

注意:session的某些方法(persist,load)不会立即把改动写入数据库,而是缓存到session的一级缓存中,除非显示调用flush,或者关闭session时才会更新到数据库

  1. 临时状态(Transient):没与session关联
  2. 持久化状态(Persistent):与session关联,没close
  3. 游离状态(Detached):当session.close后

Session的方法详解

1.保存

save:立即插入数据库,并且返回主键

persist:不立即(延迟)插入数据库,无返回值

2.获取

load:加载对象后,对对象的改动不会立即刷新到db,必须flush到db

ex: User user=session.load(User.class,2);

user.setName(‘gt’);

user.flush();   (延迟加载)

get:加载对象后,对对象的改动立即刷新到db

3.更新

update:持久化对象,更新

saveOrUpdate:包含save()和update()功能,如果传入的参数是临时对象(没有保存过)就调用save()方法;如果传入的参数是游离对象,就调用update()方法

merge:不会持久化对象,只会把托管对象的修改更新到db

4.删除

delete:从数据库中删除与JAVA对象对应的记录

5.清理

flush:把缓存同步到db

clear:清除session的缓存大小(更新批量时,应考虑)

三种状态的转换关系

下面通过实例讲解:

实体:

package cn.itcast.h_session_method;

public class User {
    private Integer id;
    private String name;
    private byte[] data = new byte[1024 * 1024 * 5];

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

映射文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.h_session_method">

    <!--
        lazy属性:默认为true,默认可以懒加载。
     -->
    <class name="User" table="user" lazy="true">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="name"/>
    </class>

</hibernate-mapping>

配置文件:hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

    <!--数据库连接设置 -->
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="connection.url">
        jdbc:mysql://localhost:3306/mytest
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>

    <!-- 方言 -->
    <property name="dialect">
        org.hibernate.dialect.MySQL5Dialect
    </property>

    <!-- 控制台显示SQL -->
    <property name="show_sql">true</property>

    <!-- 自动更新表结构 -->
    <property name="hbm2ddl.auto">update</property>
    <mapping resource="cn/itcast/h_session_method/User.hbm.xml" />

</session-factory>

</hibernate-configuration>

测试文件

package cn.itcast.h_session_method;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import com.java1234.util.HibernateSessionFactory;

public class App {

    private static SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory();

    // save():把临时状态变为持久化状态(交给Sessioin管理)
    // 会生成:insert into ...
    @Test
    public void testSave() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        User user = new User(); // 临时状态
        user.setName("test");
        session.save(user); // 变为了持久化状态

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();

        user.setName("李四"); // 游离状态
        System.out.println(user.getName()); // 游离状态
    }

    // update():把游离状态变为持久化状态
    // 会生成:update ...
    // 在更新时,对象不存在就报错
    @Test
    public void testUpdate() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        User user = (User) session.get(User.class, 1);
        System.out.println(user.getName()); // 持久化状态

        // session.clear(); // 清除Session中所有的对象
        session.evict(user); // 清除Session中一个指定的对象

        user.setName("newname3");
        session.update(user);
        System.out.println("----");
        // session.flush(); // 刷出到数据库

        // --------------------------------------------
        session.getTransaction().commit(); //
        session.close();
    }

    // saveOrUpdate():把临时或游离状态转为持久化状态
    // 会生成:insert into 或 update ...
    // 在更新时,对象不存在就报错
    // 本方法是根据id判断对象是什么状态的:如果id为原始值(对象的是null,原始类型数字是0)就是临时状态,如果不是原始值就是游离状态。
    @Test
    public void testSaveOrUpdate() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        User user = new User();
        user.setId(3); // 自己生成一个游离状态对象
        user.setName("newName");

        session.saveOrUpdate(user);

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

    // delete():把持久化或游离转为删除状态
    // 会生成:delete ...
    // 如果删除的对象不存在,就会抛异常
    @Test
    public void testDelete() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        // User user = (User) session.get(User.class, 2); // 持久化

        User user = new User();
        user.setId(300);

        session.delete(user);
        session.flush();

        System.out.println("---");

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

    // get():获取数据,是持久化状态
    // 会生成:select ... where id=?
    // 会马上执行sql语句
    // 如果数据不存在,就返回null
    @Test
    public void testGet() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        User user = (User) session.get(User.class, 5); // 持久化
        System.out.println(user.getClass());
        // System.out.println("---");
        // System.out.println(user.getName());

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

    // load():获取数据,是持久化状态
    // 会生成:select ... where id=?
    // load()后返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能了。
    // 让懒加载失效的方式:一、把实体写成final的;二、在hbm.xml中写<class ... lazy="false">
    // 不会马上执行sql语句,而是在第1次使用非id或class属性时执行sql。
    // 如果数据不存在,就抛异常:ObjectNotFoundException
    @Test
    public void testLoad() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        User user = (User) session.load(User.class, 5);
        System.out.println(user.getClass());
        System.out.println("---");
        System.out.println(user.getId());
        System.out.println(user.getName());
        // System.out.println(user.getName());

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

    // 操作大量数据,要防止Session中对象过多而内存溢出
    @Test
    public void testBatchSave() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        for (int i = 0; i < 30; i++) {
            User user = new User();
            user.setName("测试");
            session.save(user);

            if (i % 10 == 0) {
                session.flush(); // 先刷出
                session.clear(); // 再清空
            }
        }

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

    @Test
    public void test2() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        User user = (User) session.get(User.class, 5); // 持久化
        System.out.println(user.getName());

        // session.clear();
        // user = (User) session.get(User.class, 5); // 持久化

        session.refresh(user); // 刷新Session缓存中对象的状态,即重新select一下
        System.out.println(user.getName());

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }
}

对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是临时对象(Transient)

临时对象调用save方法,或者游离对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句

游离对象就是,数据库存在该对象,但是该对象又没有被session所托管

Java Hibernate 之 Session 状态的更多相关文章

  1. java框架篇---hibernate之session状态

    Session接口是Hibernate向程序提供操纵数据库的最主要接口,是单线程对象,它提供了基本的保存.更新.删除和查询方法.它有一个缓存,保存了持久化对象,当清理缓存时,按照这些持久化对象同步更新 ...

  2. Hibernate,Session方法使得java对象进入持久化状态;持久化对象特征

    以下情况java对象进入持久化状态: session.save()方法把临时对象转变为持久化对象. session.load()和session.get()方法得到的对象总是处于持久化状态. sess ...

  3. Hibernate(3)——实例总结Hibernate对象的状态和ThreadLoacl封闭的session

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: Hibernate的内部执行过程(CRUD) 对象的状态及其转换图和例子 使用JUnit测试 使用getCur ...

  4. Hibernate Open Session In View模式【转】

    来源:http://www.yybean.com/opensessioninviewfilter-role-and-configuration 一.作用 Spring为我们解决Hibernate的Se ...

  5. 简单理解Hibernate三种状态的概念及互相转化

    本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...

  6. hibernate中session

    hibernate中的session是一级缓存,可以理解为进程级的缓存.在进程运行期间一直存在. session可以理解为一个可以操作数据库的对象 具体如何操作数据库? session中有方法, 如果 ...

  7. Hibernate对象的状态和映射

    一. Hibernate对象的状态 实体对象的三种状态: 1) 暂态(瞬时态)(Transient)---实体在内存中的自由存在,它与数据库的记录无关. po在DB中无记录(无副本),po和sessi ...

  8. hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...

  9. 1.1Hibernate持久化类和Hibernate持久化对象状态

    一.持久化对象po类 1.po定义 PO,是Persistent Object的缩写,是持久化类.PO是由PO=POJO+hbm映射配置组成. 2.通俗理解 PO类即持久化类,其实就是一个普通的Jav ...

随机推荐

  1. linux系统应用--Linux下用virtualBox安装win7(共享文件夹)

    1. deepin终端: sudo apt-get install virtualbox 2. 下载win7 iso文件 3. deepin终端启动virtualbox   : ./virtualbo ...

  2. 数据库 SQL 外键约束 多表查询

    多表设计与多表查询 1.外键约束        表是用来保存现实生活中的数据的,而现实生活中数据和数据之间往往具有一定的关系,我们在使用表来存储数据时,可以明确的声明表和表之前的依赖关系,命令数据库来 ...

  3. mysql source命令导入sql文件效率分析和索引整理

    Query OK, 24918 rows affected (0.90 sec)Records: 24918  Duplicates: 0  Warnings: 0 Query OK, 24923 r ...

  4. WCF理论 【转载】

    原文地址:http://blog.itpub.net/23109131/viewspace-661613/ WCF是什么? WCF是"Windows Communication Founda ...

  5. 【转】C#注册快捷键

    转自:http://blog.csdn.net/xiahn1a/article/details/42561015 这里需要引用到“user32.dll”.对于Win32的API,调用起来还是需要dll ...

  6. ios视图切换之push与present混用

    在变成过程中,经常遇到两个视图控制器之间的切换,导航控制器即UINaVigation是最常用的一种,有时为了某些效果又需要进行模态切换,即present. 我们的布局经常是在window上加一个nav ...

  7. A Linear Time Majority Vote Algorithm

    介绍一种算法,它可以在线性时间和常数空间内,在一个数组内找出出现次数超过一半的某个数字. 要解决这个问题并不难,可以使用排序或哈希,但是这两种算法都不能同时满足时间或空间的要求. 然而,该算法(A L ...

  8. 正则表达式中/g的含义

    关于正则表达式 g,m 参数的总结,为了回答“正则表达式(/[^0-9]/g,'')中的"/g"是什么意思?”   为了解答“正则表达式(/[^0-9]/g,'')中的" ...

  9. Thinkphp 控制器

    控 制 器: 1.命名方法:新建一个主页面的控制器 controller文件夹下新建一个文件,命名为:MainController.class.php首字母都大写,称为驼峰命名法 eg: <?p ...

  10. iScroll 下拉刷新

    <!doctype html> <html> <head> <meta charset="utf-8"> <script ty ...