Hibernate学习笔记

来源:互联网 发布:jsp界面js加载失败 编辑:程序博客网 时间:2024/05/22 10:56

一、hibernate简介

Hibernate是一个ORM、持久层框架

ORM:Object-Relation Mapping  其中Object指的是持久化对象,Relation指的是关系型数据库,hibernate将两者通过映射文件建立关联关系,

把对数据库的操作转换为对对象的操作,相当于封装了对数据库的操作,并对数据库的相关操作进行了优化。(个人理解)

 

二、hibernate3.6环境搭建

1、添加jar文件

      解压hibernate-distribution-3.6.0.Final-dist.zip压缩包后

      a、先加入hibernate的主jar文件(hibernate3.jar)【好像4.0以上已经没有这个jar文件了】

      b、再加入lib\required目下的*.jar,这些是hibernate依赖的jar文件

      c、最后加入lib\jpa目录下的那个jar文件

      以上jar文件加到项目中后,hibernate的基本环境就欧了,当然了如果测试别忘了加入连接数据库的jar文件

2、添加配置文件

hibernate.cfg.xml文件可以到\hibernate-distribution-3.6.0.Final-dist\project\etc下copy,然后修改修改就行了。

xxx.hbm.xml文件可以到\hibernate-distribution-3.6.0.Final-dist\project\testing\src\main\java\org\hibernate\testing\cache下copy

然后将其放到和对应持久化类相同的包下【可以不放到同一个包下,需要配置,但是又何必呢】,xxx修改为持久化类的名称。

 

关联hibernate源码:点击关联源码后选择以文件方式导入源码,选择为以下路径

\hibernate-distribution-3.6.0.Final-dist\project\core\src

三、hibernate一级缓存---》session缓存

session利用对象快照进行脏检查,如果快照和session缓存中的信息不一致,会进行缓存清理

默认情况下 Session 在以下时间点清理缓存:

当应用程序调用 Transaction 的 commit()方法的时, 该方法先清理缓存,然后再向数据库提交事务

*当应用程序执行一些查询(HQL, Criteria)操作时,如果缓存中持久化对象的属性已经发生了变化,会先清理缓存,以保证查询结果能够反映持久化对象的最新状态显式调用

Session 的 flush() 方法

*Session 清理缓存的例外情况: 如果对象使用 native 生成器生成 OID, 那么当调用 Session 的 save() 方法保存对象时, 会立即执行向数据库插入该实体的 insert 语句。

commit() 和 flush() 方法的区别:flush 进行清理缓存的操作, 执行一些列sql语句,但不提交事务;commit方法先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数

据库操作永久保存下来。

 

 

 

四、持久化对象

 

Session的saveOrUpdate()方法

Session的merge()方法

             从数据库加载id为1的News持久化对象    

 

Session的delete()方法

Session 的 delete() 方法既可以删除一个游离对象, 也可以删除一个持久化对象。

Session 的 delete() 方法处理过程:
        ①若传入的是一个游离对象, 先使游离对象被当前 Session 关联, 使它变为持久化对象(为了确保使用了拦截器情况下, 拦截器能正常工作)。
        ②计划执行一条 delete 语句。
        ③把对象从 Session 缓存中删除, 该对象进入删除状态。

Hibernate 的 cfg.xml 配置文件中有一个 hibernate.use_identifier_rollback 属性, 其默认值为 false, 若把它设为 true, 将改变 delete() 方法的运行行为,

delete() 方法会把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象。

五、hibernate配置文件:hibernate.cfg.xml常用属性

http://blog.csdn.net/zcyhappy1314/article/details/8693405

 

六、持久化类映射文件*.hbm.xml

http://blog.csdn.net/zcyhappy1314/article/details/8693416

 

七、Hibernate 检索策略

 http://blog.csdn.net/zcyhappy1314/article/details/8718698

 

八、Hibernate二级缓存

http://write.blog.csdn.net/postedit/8740473

 

 九、批量处理数据

批量处理数据是指在一个事务中处理大量数据。

在应用层进行批量操作, 主要有以下方式:

①通过 Session

Session 的 save() 及 update() 方法都会把处理的对象存放在自己的缓存中。如果通过一个 Session 对象来处理大量持久化对象,应该及时从缓存中清空已经处理完毕并且

不会再访问的对象。具体的做法是在处理完一个对象或小批量对象后,立即调用 flush() 方法清理缓存,然后在调用 clear() 方法清空缓存。

通过 Session 来进行处理操作会受到以下约束

          a、需要在  Hibernate 配置文件中设置 JDBC 单次批量处理的数目, 应保证每次向数据库发送的批量的 SQL 语句数目与 batch_size 属性一致

          b、若对象采用 “identity” 标识符生成器, 则 Hibernate 无法在 JDBC 层进行批量插入操作

          c、进行批量操作时, 建议关闭 Hibernate 的二级缓存

int i = 0;

for(Order order :  orders){

     session.save(order);

     if(orders.size() % 30 == 0){

           session.flush();

           session.clear();

     }

}

if(orders.size() % 30 == 0){

           session.flush();

           session.clear();

}

②通过 HQL
③通过 StatelessSession
④通过 JDBC API(Session的doWork()方法获取底层JDBC API)
session.doWork(new Work() {
   @Override
   public void execute(Connection connection) throws SQLException {
    // TODO Auto-generated method stub
    Statement stmt = connection.createStatement();
    PreparedStatement ps = connection.prepareStatement(sql);
    System.out.println(connection);
   }
  });

 

十、管理 Session

尽管让程序自主管理 Session 对象的生命周期也是可行的,但是在实际 Java 应用中,把管理 Session 对象的生命周期交给 Hibernate 管理,

可以简化 Java 应用程序代码和软件架构。Hibernate 3 自身提供了三种管理 Session 对象的方法:
①Session 对象的生命周期与本地线程绑定
②Session 对象的生命周期与 JTA 事务绑定
③Hibernate 委托程序管理 Session 对象的生命周期
在 Hibernate 的配置文件中, hibernate.current_session_context_class 属性用于指定 Session 管理方式,可选值包括:
①thread: Session 对象的生命周期与本地线程绑定
②ta*: Session 对象的生命周期与 JTA 事务绑定
③managed: Hibernate 委托程序来管理 Session 对象的生命周期

Session 对象的生命周期与本地线程绑定

如果把 Hibernate 配置文件的 hibernate,current_session_context_class 属性值设为 thread,Hibernate 就会按照与本地线程绑定的方式来管理 Session
Hibernate 按以下规则把 Session 与本地线程绑定:
当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时,该方法会创建一个新的 Session(sessionA) 对象,

把该对象与 threadA 绑定, 并将 sessionA 返回 。

当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时,该方法将返回 sessionA 对象。

当 threadA 提交 sessionA 对象关联的事务时,Hibernate 会自动清理 sessionA 对象的缓存,然后提交事务,关闭 sessionA 对象。

当 threadA 撤销 sessionA 对象关联的事务时,也会自动关闭 sessionA 对象。

若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时,该方法会又创建一个新的 Session(sessionB) 对象,

把该对象与 threadA 绑定,并将 sessionB 返回 。

 

note:

hibernate执行写(保存、修改)操作时,app的新对象调用setXxx()方法完成对象的实例化赋值。然后调用hibernate的Session中的相关方法执行持久化操作,

在把对象持久化到数据库之前,hibernate会根据映射文件调用对象的getXxx()方法获得用户为对象赋得值,然后再把相应值赋给SQL语句对应的占位符,完成写操作。

hibernate在执行读(查询)操作时,hibernate会调用setXxx()方法为对象赋值,然后app会调用getXxx()方法获取相应值。

 

持久化类的属性与数据表的列不同的情况

就拿name说吧,数据表中有一个name列,持久化类有firstName和lastName两个属性,以及其get、set方法,另外还有一个private的getName()和setName()方法,如下:

private String getName(){

         if(condition){

                 return firstName + "," + lastName;

         }

        return null;

}

 

private void setName(String name){

         if(name != null && name.length() > 0){

                     String[] names = name.split(",");

                     if(names != null && names.length > 1){

                                   this.firstName = names[0];

                                   this.lastName = names[1];

                     }

        }

}

以上这两个方法是提供给hibernate使用的,访问修饰符为private不会影响其使用,java app 看不到此方法,而firstName和lastName的get、set方法java app 使用的。

hbm.xml中对应的映射如下:

<property name = "name" column = "NAME" type = "string"/>,而不是firstName或者lastName。因为这样配置后,hibernate就会根据 name 属性通过反射调用其持久化类的

getName()方法来为写操作中对应的占位符填充值。当用户进行读操作时。hibernate从数据中读出相应的值,并通过调用setName()方法,将值赋给持久化类的

firstName 和 lastName属性,用户再通过getLastName()方法等就可以访问其值了。

 

待续。。

原创粉丝点击