Hibernate笔记(2)

来源:互联网 发布:台湾衰落知乎 编辑:程序博客网 时间:2024/06/05 21:58
1.主键生成方法(Hibernate 对主键的管理)
   在*.hbm.xml 映射描述中,可以指定主键值采用哪种方法生成和管理。(仅使用于添加操作)
   <generator class="生成方法">
    //.....
  <generator>
 class 属性用于指定主键生成方法,Hibernate 提供了一下几个预定义的方法:
  1)sequence      采用一个序列生成主键值。只适用于Oracle数据库。
      <generator class="sequence">
      <param name="sequence"> 指定序列名称 </param>
     </generator>
  2)identity          Hibernate 会采用数据库自动增长机制生成主键。适用于MySQL、SQLServer 数据库
     <generator class="identity"></generator>
 注意:建表时需要为主键字段设置自增长功能
========遇到MySQL 存储乱码========
 ① 检查MySQL表存储编码,是否为utf8 :  show create table xxx
 ② 在程序的连接字符串中加入characterEncoding=utf8 的指定
==============================
  3) native              根据hibernate.cfg.xml 中的dialect 属性指定主键生成方法。如果dialect 是OracleDialect 会采用sequence 方法;如果是MySQLDialect 会采用identity 方法。
  4)increment      首先发送一个select max(ID) 语句查询当前表中ID最大值,然后将最大值加1给insert 语句指定。使用于各种类型数据库。
    <generator class="increate"></generator>
   注意:该方式在并发时,有可能产生重复ID,因此并发几率高时,不要使用。
  5)assigned        Hibernate 会放弃主键值的生成和管理。意味着程序员需要在程序中显示指定ID值。
  6)hilo、uuid 等算法
      hilo: 采用高地位算法生成一个主键值
      uuid: 采用UUID 算法生成一个主键值(字符串类型的ID)
     <generator class="uuid"></generator>


2.Hibernate 的基本特性
 1)一级缓存(以内存空间换取时间的一种策略)
    ① 一级缓存(默认开启):session.get/load 方法时,会先去一级缓存查找,没有对象信息才去数据库查找,查找后将返回的对象放入一级缓存。
         后续再查找该对象会返回缓存中的信息,从而减少访问数据库的次数。 一级缓存是属于Session 级别的缓存,由Session 对象负责管理。
         不同的Session 对象有不同的缓存空间,不能互相访问。
    ② 一级缓存的好处:利用同一个Session 多次访问同一个实体对象时,对数据库只查询一次,后续几次从缓存获取。
    ③ 一级缓存的管理:
         session.evict(obj);  //将obj 对象从一级缓存移除
         session.clear();      //清空一级缓存的所有对象
        session.close();     //关闭连接,释放缓存资源
====================================
  循环次数很多,每次id 不同时
  for(){
CostBean cost = (CostBean)session.get(CostBean.class, id);
        //使用cost 对象 -- 省略
       session.evict(cost);   //及时清理混存的对象
  }
====================================
 2)对象持久化
      ① 持久化: Hibernate 的持久化是指将程序中Java对象的数据以数据库存储形式保存下来。
      Hibernate 是一个持久层框架。
     持久层里面都是由持久对象构成,这些对象的持久化操作由Hibernate 实现。
     对象持久性:当一个对象的数据发生改变,会与数据库记录进行同步修改。
     ② 对象的状态 :Hibernate 中对象可以有以下3种状态
         临时状态(临时对象):调用new 方式创建的实体类对象,未经sesssion 处理的。
         持久状态(持久对象,在一级缓存里存放的对象):实体类对象与session 发生关联。通过session 的save()、update()、get()、load() 方法处理后,
                                                    该对象与session 发生关联。
         ◆  具有持久性的对象都是一级缓存中存放的。
         ◆  持久对象不能被垃圾回收器回收,它的数据状态改变可以与数据库同步,由session 负责同步操作
         ◆  持久对象数据改变后,在事务commit之后执行update更新。
                session.flush();       //将缓存中对象与数据库同步
                tx.commit();            //等价于session.flush + 事务提交
     ③  游离状态(游离对象):持久对象经过以下方法处理后会变成游离状态:session 的clear()、evict()、close()  方法,使用上述方法,将对象从缓存中清除出去,因此丧失了持久性。
   //向COST插入100000条记录
  Transaction tx = session.beginTransaction(); 
 //插入操作
 for(int i=1;i<=100000;i++){
   CostBean cost = new CostBean();
   //设置cost属性值
  session.save(cost);
  //分批执行
  if(i % 100 == 0){
       session.flush();   //将缓存对象与数据库同步操作
       session.clear();   //清除缓存的对象
  }
 }
 tx.commit();
 session.close();
 3)延迟加载
    ① 延迟加载:当使用了延迟加载操作方法后,再查询时并没有立刻返回数据库中的数据信息,而是在调用实体对象的getXXX() 方法
                             时才会发送SQL 语句加载数据库数据。
   ② 采用延迟加载机制的操作:
        查询:load() 延迟加载; get() 非延迟加载
        执行HQL:iterator() 延迟加载; list() 非延迟加载
       关联操作:获取关联对象属性值时,采用的延迟加载机制。
   ③ 使用延迟加载机制需要注意的问题
        org.hibernate.LazyInitializationException:
        could not initialize proxy - no Session
        上述异常原因是:采用了延迟加载的方法,但是将session 关闭过早(在加载数据前关闭),导致的错误。
       解决方法:1. 放弃延迟加载方法,采用立刻加载方法; 2.坚持使用延迟加载方法,将session 关闭推迟到数据加载后。在项目中如果使用了
                            延迟加载方法,一般会采用openSessionInView 思想控制Session 关闭。
       思想:在JSP 标签解析之前不关闭Session, 而是在JSP解析之后关闭Session, 实现方案如下:1.采用Struts2 的Interceptor 拦截器;
                   2. 采用Servlet 中的过滤器
0 0
原创粉丝点击