`
fyzjhh
  • 浏览: 16324 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Hibernate 实体状态,主键生成

阅读更多
一.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()方法。




四:主键生成


increment:
由hibernate自动以递增的方式生成标识符,每次增量为1.适用于代理主键.

identity:
由底层数据库生成标识符.数据库必须支持自动增长字段类型,不便于不同数据库之间的移植.适用于代理主键.

sequence:
Hibernate根据底层数据库序列来生成标识符.前提是条件是底层数据库支持序列(如Oracle).适用于代理主键.

hilo:
Hibernate根据high/how算法来生成标识符.适用于代理主键.

seqhilo:
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字.适用于代理主键.

native:
根据底层数据库对自动生成标识符的支持能力,来选择identity,sequence或hilo.适用于代理主键.

uuid.hex:
Hibernate采用128位的UUID(Universal Unique Identification)算法来生成标识符.UUID算法能够在网络环境中生成唯一的字符串标识符.但字符串型的主键比整型的主键占用更多的数据库空间.适用于代理主键.

uuid.string:
使用UUID算法来生成标识符.UUID被编码为一个16个字符长的任意ASCII组成的字符串。适用于代理主键.

assigned:
由Java应用程序负责生成标识符,需在保存数据前完成.适用于自然主键.





分享到:
评论

相关推荐

    持久化类主键生成策略+例子

    持久化类主键生成策略+例子 jpa 4种 hibernate 13种

    java程序生成器 本软件生成Struts2.1.8,Spring2.5,Hibernate3代码

    生成实体类,Dao层,Biz层,Action,Jsp页面,struts.xml,applicationcontext.xml,hibernate.cfg.xml,web.xml。 支持关系映射。 若想更好的利用此软件加快开发效率,减少成本,请遵循Hibernate规范。 例如: 表必须...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     8.3 Java对象在Hibernate持久化层的状态  8.3.1 临时对象的特征  8.3.2 持久化对象的特征  8.3.3 被删除对象的特征  8.3.4 游离对象的特征  8.4 Session接口的详细用法  8.4.1 Session的save()和persist()...

    15hibernate_day04_pm_v1.zip_K.

    如何使用Myeclipse生成映射文件和实体类? 映射文件和实体类《=========》DB 1)如何根据DB生成实体类和映射文件 =========利用Myeclipse追加Hibernate框架======== ...点表名可以设置实体类名和主键生成方法 l.完成

    hibernate学习笔记

    主键生成器Generator 6 多对一, 一对一, 一对多, 多对多 7 hibernate多对一关联映射(Hibernate_Many2One) 7 hibernate一对一主键关联映射(单向关联Person---->IdCard) 8 hibernate一对一主键关联映射(双向关联...

    Hibernate注解

    * @GenericGenerator —— 注解声明了一个hibernate的主键生成策略。支持十三种策略。该注解有如下属性 * name 指定生成器名称 * strategy 指定具体生成器的类名(指定生成策略)。 * parameters 得到strategy指定的...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    本章主要介绍关系数据库中的代理主键(不具有业务含义),接着介绍Hibernate提供的几种内置标识符生成器的用法及适用范围。 6.1 关系数据库按主键区分不同的记录 123 6.1.1 把主键定义为自动增长标识符类型 123 ...

    Hibernate Annotations 中文文档

    生成的属性 2.4.4. 继承 2.4.5. 关于单个关联关系的注解 2.4.5.1. 延迟选项和获取模式 2.4.6. 关于集合类型的注解 2.4.6.1. 参数注解 2.4.6.2. 更多的集合类型 2.4.7. 缓存 2.4.8. 过滤器 2.4.9. 查询 3. ...

    Hibernate实战(第2版 中文高清版)

    第一部分 从Hibernate和EJB 3.0开始  第1章 理解对象/关系持久化   1.1 什么是持久化   1.1.1 关系数据库   1.1.2 理解SQL   1.1.3 在Java中使用SQL   1.1.4 面向对象应用程序中的持久化   1.2 范式不...

    hibernate annotation 中文文档

    生成的属性 2.4.4. 继承 2.4.5. 关于单个关联关系的注解 2.4.5.1. 延迟选项和获取模式 2.4.6. 关于集合类型的注解 2.4.6.1. 参数注解 2.4.6.2. 更多的集合类型 2.4.7. 缓存 2.4.8. 过滤器 2.4.9. 查询 3. 通过XML...

    Hibernate注释大全收藏

    @Id 注解可将实体Bean中某个属性定义为主键,使用@GenerateValue注解可以定义该标识符的生成策略。 • AUTO - 可以是 identity column, sequence 或者 table 类型,取决于不同底层的数据库 • TABLE - 使用table...

    精通Hibernate:对象持久化技术第二版part3

    本章主要介绍关系数据库中的代理主键(不具有业务含义),接着介绍Hibernate提供的几种内置标识符生成器的用法及适用范围。 6.1 关系数据库按主键区分不同的记录 123 6.1.1 把主键定义为自动增长标识符类型 123 ...

    Hibernate 中文 html 帮助文档

    触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对一...

    最全Hibernate 参考文档

    触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (optional) 5.1.9. property 5.1.10. 多对一...

    hibernate 体系结构与配置 参考文档(html)

    触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对...

    hibernate annotation帮助文档

    2.4. Hibernate独有的注解扩展 2.4.1. 实体 2.4.2. 标识符 2.4.3. 属性 2.4.3.1. 访问类型 2.4.3.2. 公式 2.4.3.3. 类型 2.4.3.4. 索引 2.4.3.5. @Parent 2.4.3.6. 生成的属性 2.4.4. 继承 2.4.5. 关于...

    Hibernate教程

    触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. 多...

    Hibernate_Annotation关联映射

    在多对多关联中很多值是自动生成,党双向多对多关联中没有定义任何物理映射时,Hibernate根据以下规则生成相应的值,关联表名:主表表名+下划线+从表表名,关联到主表的外键名:主表名+下划线+主表中的主键列名,...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     8.3 Java对象在Hibernate持久化层的状态  8.3.1 临时对象的特征  8.3.2 持久化对象的特征  8.3.3 被删除对象的特征  8.3.4 游离对象的特征  8.4 Session接口的详细用法  8.4.1 Session的save()和persist()...

Global site tag (gtag.js) - Google Analytics