Hibernate实体状态

工作中遇到好几次的问题这次终于探了个底,转自 http://blog.csdn.net/sunhuwh/article/details/9183539 ,感谢作者!

一.Hibernate实体状态的定义
1.瞬态:
 一个实体通过new操作符创建后,没有和Hibernate的Session建立关系,也没有手动赋值过该实体的持久化标识(持久化标识可以认为是映射表的主键)。
 此时该实体中任何属性的更新都不会反映到数据库表中。

2.持久化:
 当一个实体和Hibernate的Session创建了关系,并获取了持久化标识,而且在Hibernate的Session生命周期内存在。
 此时针对该实体任何属性的更改都会直接影响到数据库表中一条记录对应字段的更新,即与数据库表同步。

3.脱管:
 当一个实体和Hibernate的Session创建了关系,并获取了持久化标识,而此时Hibernate的Session生命周期结束,实体的持久化标识没有被改动过。
 针对该实体任何属性的修改都不会及时反映到数据库表中。

二.实体状态的代码实现
1.瞬态-->持久化的实现

    public void test1() {
        Catalogs catalog = new Catalogs();
        // 设置Catalogs属性,持久化标识id属性在映射表中为自增长,不用设置
        catalog.setName("Cosmo's Catalog");
        catalog.setStatus(1L);
        catalog.setType(1L);
        // 启动Session
        Session session = HibernateSessionFactory.getSession();
        // 启动事务
        Transaction tx = session.beginTransaction();
        // 瞬时-->持久化的实现,保存Catalogs代表的一条记录到数据库
        session.save(catalog);
        // 打印结果
        System.out.println("----Id:" + catalog.getId());
        System.out.println("----Name:" + catalog.getName());
        System.out.println("----Status:" + catalog.getStatus());
        System.out.println("----Type:" + catalog.getType());
        // 对持久化的Catalogs进行属性的更新,此时将同步数据库
        catalog.setName("方寸心间的目录");
        catalog.setType(0L);
        catalog.setStatus(0L);
        // 不调用update方法,持久化状态的Catalogs会自动同步数据库
        // 打印结果
        System.out.println("----Id:" + catalog.getId());
        System.out.println("----Name:" + catalog.getName());
        System.out.println("----Status:" + catalog.getStatus());
        System.out.println("----Type:" + catalog.getType());
        // 提交事务
        tx.commit();
        // 关闭Hibernate Session
        HibernateSessionFactory.closeSession();
    }

2.脱管-->持久化、持久化-->脱管

    public void test2() {
        // 创建Catalogs实例
        Catalogs catalog = new Catalogs();
        // 启动Session
        Session session = HibernateSessionFactory.getSession();
        // 启动事务
        Transaction tx = session.beginTransaction();
        // 得到持久化Catalogs,此时Catalogs为持久化状态
        session.load(catalog, new Long(101));
        // 提交事务
        tx.commit();
        // 关闭Hibernate Session
        HibernateSessionFactory.closeSession();
        // 关闭Hibernate Session后Catalogs的状态为脱管状态
        // 此时依然能够得到数据库在持久化状态时的数据
        System.out.println("----Id:" + catalog.getId());
        System.out.println("----Name:" + catalog.getName());
        System.out.println("----Status:" + catalog.getStatus());
        System.out.println("----Type:" + catalog.getType());
        // 对Catalogs实体的属性的操作将不影响数据库中主键为101的记录
        catalog.setName("我的目录");
        catalog.setStatus(1L);
        catalog.setType(1L);
        // 启动Session
        session = HibernateSessionFactory.getSession();
        // 启动事务
        tx = session.beginTransaction();
        // 从脱管状态到持久化状态的转变,此时将更新数据库中对应主键为101的记录
        session.update(catalog);
        // 打印结果
        System.out.println("----Id:" + catalog.getId());
        System.out.println("----Name:" + catalog.getName());
        System.out.println("----Status:" + catalog.getStatus());
        System.out.println("----Type:" + catalog.getType());
        // 提交事务
        tx.commit();
        // 关闭Hibernate Session
        HibernateSessionFactory.closeSession();
    }

三.持久化方法对状态的影响
1.session.delete()方法
 该方法将已经存在的表记录删除,其所影响的状态是从持久化、脱管状态变为瞬时状态。

    public void testDelete() {
        // 创建Catalogs实例
        Catalogs catalog = new Catalogs();
        // 启动Session
        Session session = HibernateSessionFactory.getSession();
        // 启动事务
        Transaction tx = session.beginTransaction();
        // 得到持久化Catalogs,此时Catalogs为持久化状态
        session.load(catalog, new Long(101));
        // 删除持久化状态的Catalogs实体,此时Catalogs实体为瞬时状态。
        session.delete(catalog);
        // 提交事务
        tx.commit();
        // 关闭Hibernate Session
        HibernateSessionFactory.closeSession();
        // 由于执行了session.delete()因此Catalogs实体为瞬时状态,在数据库中找不到主键为101的数据
        // 此时依然能够显示该实体的属性
        System.out.println("----Id:" + catalog.getId());
        System.out.println("----Name:" + catalog.getName());
        System.out.println("----Status:" + catalog.getStatus());
        System.out.println("----Type:" + catalog.getType());
        // 更新Catalogs实体的持久化标志,使其成为脱管状态
        catalog.setId(new Long(1));
        System.out.println("----Id:" + catalog.getId());
        System.out.println("----Name:" + catalog.getName());
        System.out.println("----Status:" + catalog.getStatus());
        System.out.println("----Type:" + catalog.getType());
        // 启动Session
        session = HibernateSessionFactory.getSession();
        // 启动事务
        tx = session.beginTransaction();
        // 调用delete方法将脱管状态的Catalogs实体转变为瞬时状态。
        session.delete(catalog);
        // 提交事务
        tx.commit();
        // 关闭Hibernate Session
        HibernateSessionFactory.closeSession();
    }

2.session.merge()方法
 该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,即该实体依然是脱管状态。
代码省略。

3.session.lock()方法
 它为解决事务处理而使用,它会将实体从脱管状态转变为持久化状态。但是值得注意的是,调用session.lock()方法后,脱管状态的实体信息不会同步到数据库,而是会从数据库中返回该持久化状态。即使在脱管状态对实体属性进行了修改,一旦调用了session.lock()方法,这种修改该就成了无效。
代码省略。

4.session.saveOrUpdate()方法
 它是Hibernate提供的既可以新增也可以更新的方法,改方法使实体状态从脱管或瞬时直接变成持久化。
 session.saveOrUpdate()方法对实体的持久化标识非常敏感。当实体持久化标识存在,就回发送update SQL,当持久化标识不存在,就会发送insert SQL。
代码省略。

总结:
1.瞬时-->脱管状态的方法有以下几种。
a.直接将实体的持久化标识进行改变。
b.调用session.createQuery()方法。
c.调用session.getNameQuery()方法。
d.调用session.createFilter()方法。
e.调用session.createCriteria()方法。
f.调用session.createSQLQuery()方法。

2.瞬时-->持久化状态的方法有以下几种。
a.调用session.save()方法。
b.调用session.saveOrUpdate()方法。

3.脱管-->持久化状态的方法有以下几种。
a.调用session.load()方法。
b.调用session.lock()方法。
c.调用session.update()方法。
d.调用session.saveOrUpdate()方法。

4.脱管-->瞬时状态的方法有以下几种。
a.直接将实体的持久化标识清除。
b.调用session.delete()方法。

5.持久化-->脱管状态的方法:关闭Hibernate Session。

6.持久化-->瞬时状态的方法:调用session.delete()方法。

7.脱管状态-->脱管状态但影响数据库记录的方法:调用session.merge()方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值