`
clq9761
  • 浏览: 592458 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

Hibernate应用总结

阅读更多

1.hibernate初始化


在hibernate.cfg.xml文件中配置,可根据Demo进行调整。
hibernate.show_sql为true,显示SQL操作语句。
hibernate.hbm2ddl.auto属性:
  为create-drop,表示自动创建表和删除表。
  为update,表示会更新表,但不会删除表。
  为create,每次自动创建表,如果存在则删除。
示例代码:

Configuration cfg = new Configuration();
cfg.configure();//默认classpath下,可指定其它路径下的文件
SessionFactory sf = cfg.buildSessionFactory();
Session session = sf.openSession();
session.save(po);

 

2.hibernate一些要点


(1)hibernate需手动的开启事务并提交,否则不去更新数据(不同于JDBC)
(2)hibernate的开发流程(object->mapping->db,官方推荐),
        但现实中一般使用较多的为(db->生成mapping和po)
(3)hibernate无法管理带参数的构造函数,须有一个默认的不带参数的构造函数。
(4)po最好非final,对懒加载有影响。
(5)配置文件如果列名不指定,则默认与类属性名一致。
(6)Session关闭应放在finally块中,确保连接被关闭。
(7)懒加载是通过asm和cglib二个包来实现的,hibernate默认都使用懒加载。
(8)Session是非线程安全的,生命周期较短,代表一个和数据库的连接,如果长时间打开,
        会长时间占用内存和数据库连接。SessionFactory是线程安全的,一个数据库对应
        一个SessionFactory,在系统生命周期内有效。

 

3.Session的相关方法


(1)get(User.class,”id”),根据主键Id查得用户记录。
(2)load(User.class,”id”),功能同get,主要区别在于load在第一次使用对象时
      才会去查询数据库,返回的对象永远不会为空,即使查询不到数据也会为一个空对象。
(3)persist(po),与save最大的区别在于没有开启事务时save会插入语句,然后执行
      完后回滚,而persist不会执行插入语句。
(4)saveOrUpdate(po),会自动根据po的Id和version的值来确定是save或update,
      如果是瞬时对象(没有ID)用save,脱管对象(有ID)用update,执行完后po对象变为持久对象。
(5)merge(po),同saveOrUpdate一样,区别在于执行完后PO对象还是脱管的。
(6)delete(po),将持久对象变成瞬时对象,删除对象时必须根据对象来删除,可用new一个空对象,
      将主键ID赋值,前提是对象的其它属性没有非空或其它约束。
(7)evict(),close(),clear()将持久变成脱管。
(8)update(),saveOrUpdate(),lock()将脱管变成持久的。
(9)flush(),将一级缓存与数据库同步,一般不自己调用,让hibernate自动维护,hibernate一般会延迟处理。
(10)save(),一般自增长的主键,save后会马上插入数据库,大批量操作数据时可能会造成内存溢出,
     解决办法如下:

例:	for(int i=0;i<100000;i++){
	session.save(po);
	if(i%50==0){
		session.flush();
		session.clear();
	}
}

 

4.PO对象状态

 

 

(1)瞬时对象(transient),new出来没有与session关联的对象,会自动被回收销毁。
(2)持久对象(persistent),数据库中有数据与之对应,当前与session有关联,
      并且session没有关闭,事务没有提交。
(3)脱管对象(detached),数据库中有数据与之对应,但当前没有session与之关联,或称为游离对象。
(4)在session域中,如果对象发生变化,则自动会调用update语句(在提交事务时),
     在脱管状态中,如果对象发生变化,则需显示地调用update(po)来执行update语句。


5.HQL查询

例:Query query = session.createQuery("from User as user 
				where user.name=?");
	query.setString(0, "chen");
	List list = query.list();// 获取查询列表
	query.uniqueResult();//在确定查询结果只有一条时使用
   //如果hql为“from User as user where user.name=:name”
   //则应为:
	query.setString("name", "chen");
	query.setFirstResult(0);//首记录
	query.setMaxResults(10);//取10条记录(可用于分页)

 6.SQL查询

例:Query query = session.createSQLQuery("select * from User");
   List rs = query.list();

 返回的rs结果为一对象数组。
 如果添加.addEntity(User.class),则返回的结果为User对象List.
 不足:如果采用SQL查询,则Hibernate的数据库移植性可能会受到影响,因为每种数据库的查询SQL有差别。

 

7.Hql,Sql查询映射文件配置


一般不建议将hql写在业务中,而是在映射文件中进行配置,然后通过命名查询调用,方便以后修改,维护。

例: <query name="getUserByUserId">
    	<![CDATA[from User where userId==userId]]>
    </query>

 

此配置语句可放在class里面进行定义,也可放在class外面,需保证名字在所有配置文件中是唯一的。

Query query = session.getNamedQuery("getUserByUserId");
query.setString("userId", userId);
List list = query.list();

 

如果getUserByUserId命名查询放在class配置里面,则获取时需将包名和类名完整写入,
例:com...User.getUserByUserId. 

 

8.Criteria条件查询(面向对象查询)

例 :
Criteria c = session.createCriteria(User.class);
// 约束条件为等于,还有大于,小于,like等
c.add(Restrictions.eq("name", "chen"));

 9.离线查询(动态构造查询语句)

 DetachedCriteria dc = DetachedCriteria.forClass(User.class)	
 dc.add(Restrictions.eq("name", name));
 dc.add(Restrictions.eq("age", age));
 Criteria c = dc.getExecutableCriteria(session);
 List rs = c.list();

 

10.Iterator查询

Query query = session.createQuery("from user");
Iterator<User> users = query.iterate();

 

iterator()方法会先查找Id,再根据ID查找记录,如果缓存中没有数据,会有N+1次查询数据库。
懒加载也会造成N+1次的查询,先查找当前属性,再到关联数据库逐一查找。

 

11.Hibernate事件监听
  拦截器与事件都是Hibernate的扩展机制作,拦截器是老的实现机制,现在改成事件监听机制。

例:class SaveListener implements SaveOrUpdateEventListener{
	   public void onSaveOrUpdate(SaveOrUpdateEvent event)
			throws HibernateException {
		if(event.getObject() instanceof User){
			// 具体处理逻辑
		}
	 }	
}

 

  配置信息:

<event type = "save">
  <listener class="com.icsshs.smis.listener.SaveListener">
  <listener class="org.hibernate.event.def.DefaultSaveOrUpdateEventListener">
</event>
		

 12.Hibernate对象关联映射


(1)<id name=””></id> 用来映射主键,有以下几种方式:
     1.native,会自动根据数据库选择自增长的方式。
     2.assigned,手工分配标志符,除非编码有意义时,否则不建议使用。
     3.composite-id,联合主键,也不建议使用,引用外键时性能不高。
(2)多对一(例:员工->部门),在员工对象中加部门外键
   

 <many-to-one name="depart" column="depart_id"/> 

 

(3)一对多(例:部门->员工),在部门对象中创建

   <set name="employeeSet">
       <one-to-many class="Employee"/>
       <key column="depart_id"/>
   </set> 

           
(4)一对一(例:用户->身份证)
  例:Person类:id,name,IdCard;(id为主键)
       IdCard类: id,name,Person(id为主键,也是外键)
      Person类映射:

<id name="id" column="person_id">
	<generator class="native"/>
</id>    
<one-to-one name="idCard" />

 

    IdCard类映射:

<id name="id" column="personID">
<generator class="foreign">
 	<param name="property">person</param>
	</generator>
</id>
<!-- constrained="true"添加外键约束 -->
<one-to-one name="person" class="Person" constrained="true"/>

 

   一对一的另外一种建立关系,则从表有自己的主键ID,并建立一外键与主表关联(需限制为唯一)
   例:主表(person)的关联映射需改为

<one-to-one name="idCard" property-ref="person" />

   从表(idCard)的关联映射需改为

<many-to-one name="person" unique="true"  column="person_id"/> 

 

(5)多对多(例老师-学生)
    操作和性能不太理想,实际使用中最好转换成一对多的对象模型,创建中间表,转换成两个一对多。
    例:Teacher:id,name,studentSet;
          Student:id,name,TeacherSet;
    Teacher表映射:

<set name="studentSet" table="teacher-student">        
	<many-to-many class="Student" column="student_id" />    
	<key column="teacher_id"></key>        	
</set>

 

    Student表映射类似于Teacher.
    在更新数据时,只需单方进行set(),双方都进行set更新时会出错。
(6)在session范围外,要获得关联的对象,如果没有配置延迟加载false,则取不到数据,
      可用Hibernate.initialize(emp.getDepart()),初始化员工的部门对象。
(7)Cascade用来说明当对主对象进行某种操作时是否对其关联的从对象也进行类似的操作。
       常用的有:none,all,save-update,delete,lock,refresh,evict,replicate,
       persist,merge,delete-orphan。一般对<many-to-one>,<many-to-many>不设置级联,
       而在<one-to-one>和<one-to-many>中设置级联。
(8)一对一关系中主对象查询时默认不使用懒加载,使用左外连接查询,而从对象查询时使用懒加载。
(9)fetch是指以什么方式抓取数据,fetch=”join”,通过关联表一次性把数据都查出来,
       懒加载无效,默认情况下都是select.
      当使用一对多或多对多时,尽量不设置fetch=”join”,可能会关联多张表,性能差。
(10)Lazy是指什么时候抓取数据,lazy=”false”则懒加载无效,查出所有关联的数据,
      默认情况下lazy=”proxy”,即使用对象时才查询。当使用懒加载时,访问代理对象的getId()
      和getClass()不会去查询访问数据库。当设置fetch=”join”时,lazy的配置失效,没有意义。

 

13.Hibernate缓存


(1)首先从缓存中取数据,如果不存在则从数据库取数据,然后放入缓存。在更新对象时,将对象从缓存中移除。
(2)一级缓存,属于session级共享,session中存在一级缓存,当session关闭后,一级缓存也就不存在了,
     当查找同个对象时,需再次查找数据库。Save,update,saveOrUpdate,load,get,list,iterate,lock
     这些方法都会将对象放在一级缓存中,一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能内存溢出,
     可以用evict,clear方法清除缓存中的内容。
     Query()方法每次都从数据库查询,不会从缓存中取数据。
(3)二级缓存,属于sessionFactory级共享,可以被所有的session共享,hibernate二级缓存交给第三方实现,
     配置如下:

例:<session-factory>
	 <!--开启二级缓存-->
	 <property name="hibernate.cache.use_second_level_cache">
 		true
	 </property> 
 	<!-- 设置缓存提供者,相关第三方缓存配置文件需放在classpath下 -->
 	<property name="hibernate.cache.provider_class">
 		org.hibernate.cache.EhCacheProvider
 	</property> 
</session-factory>

 

还需告诉hibernate哪些类需要缓存,一般是较少修改的使用缓存,频繁修改的不使用缓存。
如果想对User类进行缓存, 有以下两种方式:
方式(一):可在hibernate主配置文件中配置:

<session-factory>
   <class-cache class="com.entity.User" usage="read-only"/> 
</session-factory>

 方式(二):在具体对象映射文件中配置:

<class name="com.entity.User" table="t_user"> 
			<cache usage="read-only"/> 
			<id name="id"> 
				<generator class="native"/>
			 </id> 
 </class> 

 

     Usage为使用策略,主要有以下几种方式:
        1.read-only,在确保对象不修改时使用。
        2.read-write,修改时同步缓存,保证并发读写时正确性,但效率较低。
        3.nonstrict-read-write,非严格的读写,比第二种方式效率较高,但不考虑并发操作。
        4.transactional,较少使用,用于事务性控制。
(4)二级缓存的清理,通过sessionFactory.evict()进行清理。
(5)使用缓存的条件:
     1.读取大于修改。
     2.数据量不能超过内存容量。
     3.对数据要有独享的控制。
     4.可以容忍出现无效数据。
(6)StatelessSession接口,是无状态的session,不和一级缓存,二级缓存交互。

 

14. 事务管理


  事务控制一般应放在三层架构的业务逻辑层。
(1)JDBCTranction,一个SessionFactory对应一个数据库。
(2)JTATranction,跨数据库的事物,由应用JTA容器实现。(tomcat不提供)。
(3)OpenSessionInview,主要解决以下问题:
     1.解决事务问题。事务在过滤器打开,在页面渲染后,执行过滤器后关闭。不在业务层进行控制。
     2.解决懒加载问题。
   存在以下问题:
     1.一级缓存一直保留到页面渲染后才释放,占用内存较大。
     2.数据库连接长时间没释放,并发大操作时有问题。
(4)悲观锁:当读取数据时加上锁,修改提交后释放锁。
(5)乐观锁:给数据库加上版本号进行控制。在hibernate中具体应用如下:
     1.给对象加上版本号.(int型ver属性)
     2.在hibernate中配置。<version name=”ver”/>,也可用
        <timestamp name=”ver”/>来控制,但精确度有限。
     3.在数据库中加上版本号字段。
     4.Hibernate在更新数据时会自动读取版本号和更新版本号,同时读取时后面提交的会报错。

分享到:
评论

相关推荐

    Hibernate知识点总结

    ### Hibernate知识点总结 #### 一、Hibernate概述 Hibernate是一个开源的ORM(Object Relational Mapping,对象关系映射)框架,用于Java应用与关系型数据库之间的交互。它通过使用描述对象和数据库之间映射的元...

    hibernate学习总结文档

    Hibernate 是一个开源的对象关系映射(ORM)框架,它为 Java 开发者提供了一种在 Java 应用程序中管理关系数据库的方式。通过 ORM,Hibernate 可以将 Java 类与数据库表之间的映射关系自动化,从而简化数据访问层的...

    Hibernate4总结文档

    《Hibernate4总结文档》 Hibernate4作为一款强大的Java对象关系映射框架,简化了数据库操作,使得开发者可以更专注于业务逻辑而不是数据库层面的细节。本文将深入探讨Hibernate4的配置和使用,帮助开发者更好地理解...

    hibernate文档总结,技术汇总,PDF版的,hibernate简明参考文档

    总结来说,Hibernate是一个强大的ORM框架,它极大地简化了Java应用的数据库操作,提高了开发效率,并提供了高级特性如缓存、事务管理等。通过深入理解和熟练使用Hibernate,开发者可以构建更高效、更易于维护的...

    简单的HIBERNATE应用

    总结,这个“简单的Hibernate应用”提供了学习和实践Hibernate的基础,包括如何配置、创建实体、执行查询以及在Web环境中集成Hibernate的方法。通过深入理解并熟练运用这些知识,开发者可以更高效地进行Java数据库...

    Hibernate 简单 PPT 总结

    【Hibernate 简单 PPT 总结】 Hibernate 是一个流行的开源对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作。通过提供一套API和元数据,Hibernate允许开发者将业务对象直接映射到数据库表,从而避免了...

    Hibernate重点总结

    - **SessionFactory**: Hibernate的核心组件,负责创建Session实例,它是线程不安全的,通常在应用启动时创建并全局共享。 - **Session**: 实现业务逻辑的主要接口,代表与数据库的一次会话,负责对象的持久化操作...

    Hibernate大总结/Hibernate面试题大全

    以上总结了Hibernate的一些核心概念和面试中可能遇到的关键知识点。了解这些概念有助于更好地掌握Hibernate框架的使用,以及如何高效地利用Hibernate进行数据库操作。此外,对于面试者而言,熟悉这些概念也能帮助...

    Hibernate 经典总结

    Hibernate 是一个流行的 Java ORM(对象关系映射)框架,它使得开发者可以用面向对象的方式来处理数据库操作,极大地简化了Java应用程序中的数据访问层。Hibernate 对 JDBC 进行了封装,使得程序员无需编写大量的 ...

    hibernate学习总结

    **hibernate学习总结** Hibernate 是一款开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序与数据库之间的交互。在Java世界中,Hibernate 提供了一种在对象模型和关系数据库之间进行转换的机制,使得开发...

    hibernate技术研究对比总结

    **HIBERNATE技术总结** Hibernate 是一个流行的 Java 应用程序框架,它提供了一种对象关系映射(ORM)解决方案,将数据库操作转化为面向对象的编程。此文档旨在研究和对比 Hibernate 技术的不同方面,帮助开发者更...

    Hibernate课程的总结

    总结所述,Hibernate为Java开发者提供了强大的数据库操作工具,通过理解并熟练运用其核心概念和技术,能极大地提升开发效率和应用质量。通过阅读提供的“hibernate课堂笔录_0906.txt”,可以进一步巩固这些知识,并...

    SSH应用开发-Hibernate应用入门.zip_hibernate

    本教程提供的"SSH应用开发-Hibernate应用入门.docx"文档,将详细讲解如何配置Hibernate环境,创建实体类,编写映射文件,以及如何进行基本的CRUD操作。对于初学者,这是一个很好的起点,通过学习可以掌握Hibernate的...

    struts\Hibernate 学习总结.doc

    Struts和Hibernate是Java开发中两个非常重要的框架,它们分别关注于Web应用的MVC(Model-View-Controller)架构的实现和数据持久化的处理。 Struts是一个经典的MVC框架,它帮助开发者将业务逻辑、用户界面和数据...

    Hibernate工作中应用的总结.doc

    【Hibernate工作应用总结】 在IT行业中,Hibernate是一个广泛使用的对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。以下是对Hibernate在实际工作应用中的总结,旨在帮助开发者更好地理解和使用...

    hibernate关联关系总结

    总的来说,理解并熟练运用Hibernate的关联关系对于开发高效、可靠的Java应用程序至关重要。通过合理的关联设计,可以简化对象模型与数据库之间的转换,提高开发效率,减少潜在的错误。在实际项目中,开发者应根据...

Global site tag (gtag.js) - Google Analytics