`
im127im
  • 浏览: 14148 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Hibernate 学习 总结

 
阅读更多

Hibernate 学习 总结
2010年08月21日
     一、PO的数据类型设置
  int 还是Integer Integer 允许为 null 
  Hibernate 既可以访问Field也可以访问Property,访问Property是只是调用getXXX()、setXXX()方法,因此在from Customer where c.name='Tom' HQL中,name属性不需要存在,只要getName()存在就可以了。 
  二、Hibernate映射
  1、映射复合主键
  
  主键类   
  Public class CustomerId implements Serializable{   
  Private final String name;   
  Private final String companyid;   
  }   
  映射文件   
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
         或      
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
  主键类 Public class CustomerId implements Serializable{ Private final String name; Private final String companyid; } 映射文件                     或                   
  2、映射组成关系
  
     
     
     
     
     
     
     
     
     
     
     
     
     
  Public class Customer implements Serializable{   
  Address homeAddress;   
  Address comAddress;   
  }   
  Public class Address implements Serializable{//是VO不是PO不能单独Save,也不能关联。   
  Customer customer;   
  }  
               Public class Customer implements Serializable{ Address homeAddress; Address comAddress; } Public class Address implements Serializable{//是VO不是PO不能单独Save,也不能关联。 Customer customer; }
  3、映射聚合关系
  
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
                  
  4、映射继承关系
  
  DOClass{   
  id    }   
  ClassA extends DOClass{   
  A1   
  }      
  ClassC extends ClassA{   
  C1   
  }      
  ClassD extends ClassA{   
  D1   
  }      
  ClassG extends ClassD{   
  G1   
  }      
  ClassH extends ClassD{   
  H1   
  }      
  ClassB extends DOClass{   
  B1   
  }      
  ClassE extends ClassB{   
  E1,e2,e3,e4,e5,e6   
  }      
  ClassF extends ClassB{   
  F1,f2,f3,f4,f5,f6,f7   
  }      
  TABLE_A {ID(PK),A_TYPE(discriminator),A1,C1,D1,G1,H1}   
  TABLE_B {ID(PK),B1}   
  TABLE_E {B_ID(PK/FK),E1,E2,E3,E4,E5,E6}   
  TABLE_F {B_ID(PK/FK),F1,F2,F3,F4,F5,F6,F7}   
  ClassA.hbm.xml   
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  ClassB.hbm.xml   
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
  DOClass{ id } ClassA extends DOClass{ A1 } ClassC extends ClassA{ C1 } ClassD extends ClassA{ D1 } ClassG extends ClassD{ G1 } ClassH extends ClassD{ H1 } ClassB extends DOClass{ B1 } ClassE extends ClassB{ E1,e2,e3,e4,e5,e6 } ClassF extends ClassB{ F1,f2,f3,f4,f5,f6,f7 } TABLE_A {ID(PK),A_TYPE(discriminator),A1,C1,D1,G1,H1} TABLE_B {ID(PK),B1} TABLE_E {B_ID(PK/FK),E1,E2,E3,E4,E5,E6} TABLE_F {B_ID(PK/FK),F1,F2,F3,F4,F5,F6,F7} ClassA.hbm.xml                    ClassB.hbm.xml                         
  5、映射Bag,List和Map
  IDBag
  
  IMAGES{ID(PK),CUSTOMER_ID(FK),FILENAME}   
  List images = new ArrayList();   
  Customer.hbm.xml   
     
     
     
     
     
     
    
  IMAGES{ID(PK),CUSTOMER_ID(FK),FILENAME} List images = new ArrayList(); Customer.hbm.xml       
  List
  
  IMAGES{CUSTOMER_ID(PK/FK),POSITION(PK),FILENAME}   
  List images = new ArrayList();   
  Customer.hbm.xml   
     
     
     
     
    
  
  IMAGES{CUSTOMER_ID(PK/FK),IMAGE_NAME(PK),FILENAME}   
  Map images = new HashMap();   
     
     
     
     
     
  Set idbag map 支持数据库排序  order by ="ID"   
  Set map 支持内存排序  sort = "MyComparator"  
  IMAGES{CUSTOMER_ID(PK/FK),IMAGE_NAME(PK),FILENAME} Map images = new HashMap();      Set idbag map 支持数据库排序 order by ="ID" Set map 支持内存排序 sort = "MyComparator"
  6、映射一对一关联关系特殊情况一
  
  Address homeAddress;   
  Address comAddress;   
  }      
  Customer.hbm.xml   
     
     
  Address.hbm.xml   
    
  Public class Customer{ Address homeAddress; Address comAddress; } Customer.hbm.xml   Address.hbm.xml 
  映射一对一关联关系主键映射
  
  
     
     
        
     
     
         
     
     
     
     
    
  
     
  三、Inverse与cascade
  Inverse 
  应该将Set的inverse属性设置为true,如果为many-to-many 需要将一方设置为true 
  如Customer:Order为1:N双向关联,将Customer的Set的inverse设置为true,表示Customer与Order之间的关联关系由Order端来维护,如customer.getOrders().addOrder(o)不会更新Customer与Order之间的关联关系,而order.setCustomer(o)才会更新Customer与Order之间的关联关系。 
  Cascade 
  Save-update 保存、更新Customer会同步更新Order. 
  Delete 同步删除 
  All 包含save-update和delete操作,另外调用当前对象的evice或者lock时,对关联对象也调用相应方法。 
  Delete-orphan 删除所有和当前对象解除关联关系的对象。 
  All-delete-orphan 当关联双方为父子关系是(父亲控制孩子的持久化生命周期),如果父方删除,子方自动删除(同delete),如果子方无父亲,子方应删除。包含Delete和all-orphan的行为。 
  四、Hibernate缓存
  Session 缓存(一级缓存),每一session确保自己的缓存的所有的持久对象唯一
  通过调用session.setFlushMode()可设定缓存的清理模式,缓存的清理模式有三种: 
  FlushMode.AUTO:query、commit和flush的时候清理缓存。 
  FlushMode.COMMIT:commit和flush的时候清理缓存。 
  FlushMode.NEVER:只有在调用session.flush()的时候才清理缓存。 
  Session 只有在清理缓存的时候才会执行相应的sql操作。 
  可以使用session.evict()和session.clear()清空缓存。 
  Save、update、query都加入Session缓存 
  Select c.ID,c.Name,c.age,o.ORDER_NUM,o.CUSTOMER_ID from Customer c,inner join c.orders c 除外。 
  SessionFactory缓存(二级缓存)
  
     
     
     
     
     
     
     
     
     
     
        
  Hibernate.cache.provider=………& hellip;EhCacheProvider   
  Hibernate.cache.user_query_cache=true     
  Ehcache.xml   
     
     
     
        
        
        
     
              Hibernate.cache.provider=………& hellip;EhCacheProvider Hibernate.cache.user_query_cache=true Ehcache.xml        
  Query q = session.createQuery(); 
  q.setCacheable(true); 
  q.setCacheRegion("customerQueries"); 
  SessionFactory.evict(),SessionFactory.evictCollection()清除二级缓存。 
  直接调用JDBC API不会使用任何缓存。 
  二级缓存适合查询较多但是很少更新的情况。 
  尽量对数据库的所有操作由Hibernate来完成,而不要用其它方式对数据库进行操作,否则可能与缓存冲突,当然如果对缓存有深入研究的除外。
  五、临时对象(Transient Object)、持久对象(Persistent Object)和游离对象(Detached Object)
  临时对象:表示对象的主键不存在(OID不存在),Hibernate通过key的unsave-value或者version的unsaved-value来判断是否为临时对象。Session对临时对象的唯一操作应该是save()。 
  持久对象:在session缓存中存在持久对象,数据库中存在相应纪录。 
  游离对象:数据库中有相应纪录,session中不存在持久对象,可通过session.evict()获得。 
  Session缓存中存在,数据库中不存在,这是什么类型的对象?实际这种情况不存在,因为所有的Session操作均在事务中进行,缓存中的数据是通过save、update或者query生成,而save或者update得到的是数据库的独占锁,因此其它事务没有可能删除数据库中的数据。而query获得的是数据库的共享锁,因此其它事务也不可能获得独占锁来更新数据。因此在一个事务内部session缓存才有意义,如果脱离事务,仅仅是只读操作也可能导致session缓存中存在数据库中根本不存在相应纪录的持久性对象。 
  六、Hibernate 的检索策略
  设定批量检索数量 batch-size 
  外连接深度控制hibernate.max_fetch_depth
  类级别检索 load、get和find。其中load可以设置延迟检索(cglib生成代理类,可通过Hibernate.initialize()初始化),这也是load和get的区别之一。Get/find立即检索,与是否设置延迟无关。 
  关联检索 立即检索,延迟检索,迫切左外连接检索。Set/list/map等,无论是否延迟检索得到的都是代理集合类。而非HashSet,ArrayList等。 
  Lazy与outer-joint 
  False,false 立即检索 
  False,true 迫切左外连接, 
  True,false 延迟检索 
  Many-to-one 的outer-join属性 
  Auto:Customer的lazy为true则延迟加载,否则迫切左外连接 
  True:迫切左外连接 
  False:延迟加载或者立即加载由Customer的lazy决定。 
  One-to-one的延迟加载策略 
   
  HQL会忽略迫切左外连接检索和lazy(只有load才为代理对象)策略。 
  Session.find("from Customer c as c left join fetch c.orders where c.id=1") 
  Hibernate的检索方式 
  HQL、NativeSql和QBC 
  From Customer c inner join c.orders o 查询结果保存到session缓存 
  Select c.ID,c.Name,c.age,o.ORDER_NUM,o.CUSTOMER_ID from Customer c,inner join c.orders c查询结果不存入Session缓存。 
  七、Hibernate并发控制
  乐观锁:VERSION或者timestamp控制,session.lock()立刻进行版本检查,session.update(),update的时候执行版本检查。 
  悲观锁:select for upload,session.get(Customer.class,new Long(1),LockMode.UPGRADE) 
  总结:本文绝大多数为摘录内容,有些地方加上自己的理解,有不对之处恳请批评指正。看了书,阅读了相关帖子后,感觉学习Hibernate的重点应该是Hibernate的缓存策、查询和如何提高性能方面。 
  另外说点自己的感受,本人做项目到现在都是在设计阶段先有关系模型后有对象模型(其实一个Table一个对象),在这种情况下Hibernate的优势大大降低了,其实是为了Hibernate而Hibernate了,个人感觉在先有关系模型的情况下用Hibernate的意义不大。 
  如果按照OOAD的开发流程先有对象模型,然后根据对象模型生成关系模型,那应该说用Hibernate用对了地方。毕竟Hibernate对继承、多态,各种复杂的关系都有很好的支持。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics