Hibernate原理与应用 讲师:李勇 北京传智播客教育 www.itcast.cn.

Slides:



Advertisements
Similar presentations
第二章 简单的 SQL 语句. 本章要点  创建一个简单的表  SQL 语句介绍  最简单的查询语句 select  带有限制条件的查询  查询结果的排序显示.
Advertisements

JSP 与数据库 SQL 语言简介 SQL 语言简介 JDBC 简介 JDBC 简介 使用 JDBC 连接数据库 使用 JDBC 连接数据库 访问数据库 数据库访问应用举例.
第十章 Java 数据库编程. 内容提要 数据库有关概念; 介绍 JDBC 的结构; 重点介绍 JDBC 访问几种数据库的基本过程;
2010 年 6 月课件制作人:王亚楠 1 模块 2 项目开发概论 教学课件 年 6 月课件制作人:王亚楠 2 目录 目标 了解:数据库技术的基本概念与结构 理解:数据模型的分类与结构组成 掌握:关系数据库及 SQL 的基本理论 知识 掌握:数据库设计的方法与步骤 内容 2.1 数据库技术基础.
Data type P64 ‘’ 转义字符 P67 P68 EXE,选出某个教师的学生中最新的一 个,要姓名, ID (,LIMIT ) EXISTS,NOT EXISTS P409 Q,EXISTS 和 in 的区别( 1000 ,查询结果)
Java 技术与应用 数据库应用 ( 第 14 章 ) 西安交大 卫颜俊 2008 年 12 月 电子信箱: QQ: 网站 : /java.
第 9 章 测试部署  9.1 测试  9.2 部署. 9.1 测试  应用测试:使用 JUnit 单元测试框架 测试的目的是检验开发结果是否满足规定需求,测试是保证软件质量的一个重要手段, 在软件开发过程中是不可缺少的组成部分。 单元测试与集成测试分别有各自的定义:在实际开发中,两者之间的界定是模糊的。
第 7 章 数据库 1. Overview  数据库概述  数据库管理系统  数据库的体系结构和数据库模型  SQL 语言  数据库技术  构建数据库系统 2.
国家科学图书馆: 刘丹军、赵雅娟、王晓梅、胡正银等 创想通科技: 阎武鹏 等 2010年 洛阳
第5章 关系数据库标准语言SQL 主讲:张丽芳.
十一 ASP对数据库的访问.
第2讲 Transact-SQL语言.
第5章 索引及视图操作 数据库原理应用与实践 SQL SERver2014(第2版) 主编 贾铁军 科学出版社 编著 陈国秦 万程 邢一鸣
数据库技术 实践.
基于SSH的web开发 AND 企业级WEB应用开发新技术
第六章 Hibernate 入门.
第2章 数据模型 2.1 实体联系模型 2.2 关系模型 2.3 面向对象的数据模型 习 题 2.
第4章 关系数据库标准语言SQL 4.1 SQL语言概述 4.2 SQL数据查询功能 4.3 SQL数据操作功能 4.4 SQL数据定义功能.
MVC Servlet与MVC设计模式.
数据库概述 简而言之,数据库(DataBase)就是一个存储数据的仓库。为了方便数据的存储和管理,它将数据按照特定的规律存储在磁盘上。通过数据库管理系统,可以有效的组织和管理存储在数据库中的数据。如今,已经存在了Oracle、SQL Server、MySQL等诸多优秀的数据库。在这一章中将讲解的内容包括。
数据库原理及设计 --作业.
文科计算机小公共课规划教材 Access 程序设计.
J2EE Struts 和Spring 的区别.
第6章 資料庫管理系統 6-1 關聯式資料庫管理系統 6-2 SQL Server資料庫管理系統
建设数字化的卫生监督体系 深 圳 市 卫 生 监 督 所 2006年4月.
第5章 数据库保护 之事务.
第二章 JAVA语言基础.
Google App Engine Google 應用服務引擎.
第八章 分析與設計階段 – 物件導向設計(OOD)
第六章 學習SQL語言.
9 SELECT敘述的進階查詢 9-1 SQL的多資料表查詢 9-2 合併查詢 9-3 集合運算查詢 9-4 子查詢
第 8 章 資料的 新增、修改與刪除.
数据库操作示例 import java.sql.*; //导入java.sql包 public class JDBCDemo {
課程名稱:資料庫系統 授課老師:李春雄 博士
基于Hadoop的数据仓库Hive.
Chapter 12 T-SQL 語法與 ASP.NET.
Chap 10 SQL定義、操作與控制指令.
第十一章 面向对象设计 第十二章 面向对象实现
胡鹏 王慧锋 TEL: 数据库系统原理课程设计 实验环节1 胡鹏 王慧锋 TEL:
第9讲 Hibernate查询语言HQL.
資料庫安全 (Database Security)
崑山科技大學資訊管理系 伺服網頁程式設計 系統開發細部流程 教師:游峰碩.
電子商務網站建制技術與實習(II) 助教:江宜政 吳昇洋.
2018/11/23 面向对象与多线程综合实验-数据库操作 教师:段鹏飞.
Ch13 集合與泛型 物件導向程式設計(2).
An Introduce to NHibernate
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
SQL Server 2000 数据库入门.
第10章 面向对象分析设计与对象模型 面向对象方法中,从分析到设计不像传统方法那样有明显的方法、工具的转换,而是平滑(无缝)过渡。分析设计过程具有良好的可跟踪、可修改和可扩展性。 面向对象设计是面向对象分析到实现的一个桥梁。面向对象分析是将用户需求经过分析后,建立问题域精确模型的过程,而面向对象设计则是根据面向对象分析得到的需求模型,建立求解域模型的过程。
第3章 MySQL教學範本 主從式資料庫系統 - CH3.
第5章 資料倉儲的資料建置.
5.1.1 使用 ExecuteReader()操作数据库
Java程序设计 第9章 继承和多态.
Spring & mongodb java实战mongodb 曹巍 2013年9月22日.
王豐緒 銘傳大學資訊工程學系 問題:JAVA 物件檔輸出入.
DWR WEB开发交流 1、自我介绍 2、DWR概述 3、DWR DEMO介绍 4、DWR实现机制 5、DWR配置说明 6、JS开发注意事项.
第十七章 資料庫SQL 17-1 SELECT 17-2 INSERT 17-3 UPDATE 17-4 DELETE.
集合框架和泛型(一).
Google App Engine API.
第11章 ListView延迟加载效果 授课老师:高成珍 QQ号: QQ群: 、
CS, ZJU 4/18/2019 Chapter 7 数据库.
3. SQL语言的应用 3.1 SQL历史和优点 3.2 数据查询 3.3 数据操纵.
查询与视图 蔡海洋.
SQL查询语句 蔡海洋.
第二章 Java语法基础.
第二章 Java基本语法 讲师:复凡.
第2章 Java语言基础.
第4章 数据查询.
第二章 Java基础语法 北京传智播客教育
数据库应用技术 天津电大 翟迎建.
Presentation transcript:

Hibernate原理与应用 讲师:李勇 北京传智播客教育 www.itcast.cn

主要内容 最佳实践 引入 安装配置 基本概念和CURD HQL和Criteria 关联映射 继承映射 集合映射 懒加载 缓存 事务 其他 Hibernate不适合的场景 与JPA的集成(annotation方式) 最佳实践 北京传智播客教育 www.itcast.cn

引入 模型不匹配(阻抗不匹配) Java面向对象语言,对象模型,其主要概念有:继承、关联、多态等;数据库是关系模型,其主要概念有:表、主键、外键等。 解决办法 1使用JDBC手工转换。 2使用ORM(Object Relation Mapping对象关系映射)框架来解决,主流的ORM框架有Hibernate、TopLink、OJB。 北京传智播客教育 www.itcast.cn

安装配置 下载地址http://www.hibernate.org,本教程使用3.2.5。 将下载目录/hibernate3.jar和/lib下的hibernate运行时必须的包加入classpath中: antlr.jar,cglib.jar,asm.jar,commons-collections.jar,commons-logging.jar,jta.jar,dom4j.jar 北京传智播客教育 www.itcast.cn

安装配置 配置文件hibernate.cfg.xml和hibernate.properties,XML和properties两种,这两个文件的作用一样,提供一个即可,推荐XML格式,下载目录/etc下是示例配置文件。 可以在配置文件指定: 数据库的URL、用户名、密码、JDBC驱动类、方言等。 启动时Hibernate会在CLASSPATH里找这个配置文件。 映射文件(hbm.xml,对象模型和关系模型的映射)。在/eg目录下有完整的hibernate示例。 快速开始小例子 北京传智播客教育 www.itcast.cn

基本概念和CURD 开发流程 1由Domain object -> mapping->db。(官方推荐) 2由DB开始,用工具生成mapping和Domain object。(使用较多) 3由映射文件开始。 北京传智播客教育 www.itcast.cn

基本概念和CURD Domain Object限制 1.默认的构造方法(必须的)。 2有无意义的标示符id(主键)(可选) 3非final的,对懒加载有影响(可选) Domain Java Object(User) public class User { private int id; private String name; private Date birthDay; //getter setter… } 北京传智播客教育 www.itcast.cn

基本概念和CURD 1.hbm.xml <?xml version="1.0"?> <hibernate-mapping package=“cn.itcast.domain"> <class name="User" table="user"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <property name="birthday”/> </class> </hibernate-mapping> 主键生成器,参考文档P65 5.1.4 2.详细信息见参考文档P62 北京传智播客教育 www.itcast.cn

基本概念和CURD Java代码 1.初始化代码(只做一次) Configuration cfg = new Configuration(); cfg.configure(“config.cfg.xml”); 也可以通过cfg.setProperty设置属性。 SessionFactory sessionFactory = cfg.buildSessionFactory(); 2.模板代码 Session session = null;Transaction tx = null; try{ session = sessionFactory.openSession(); tx = session.beginTransaction(); //…你的代码save,delete,update,get… tx.commit(); }catch(Exception e){ if(tx !=null)tx.rollback();throw e; }finally{ if(session != null)session.close(); } 北京传智播客教育 www.itcast.cn

基本概念和CURD Session的几个主要方法 1.save,persist保存数据,persist在事务外不会产生insert语句。 2.delete,删除对象 3.update,更新对象,如果数据库中没有记录,会出现异常。 4.get,根据ID查,会立刻访问数据库。 5.Load,根据ID查,(返回的是代理,不会立即访问数据库)。 6.saveOrUpdate,merge(根据ID和version的值来确定是save或update),调用merge你的对象还是托管的。 7.lock(把对象变成持久对象,但不会同步对象的状态)。 北京传智播客教育 www.itcast.cn

对象状态 瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。 持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。 脱管(detached):数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,hibernate不能检测到。 北京传智播客教育 www.itcast.cn

对象状态 北京传智播客教育 www.itcast.cn

HQL和Criteria Criteria HQL(Hibernate Query Language) 面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态;HQL主要通过Query来操作,Query的创建方式: Query q = session.createQuery(hql); from Person from User user where user.name=:name from User user where user.name=:name and user.birthday < :birthday Criteria Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式: Criteria crit = session.createCriteria(DomainClass.class); 简单属性条件如:criteria.add(Restrictions.eq(propertyName, value)), criteria.add(Restrictions.eqProperty(propertyName,otherPropertyName)) 3 北京传智播客教育 www.itcast.cn

基本功能练习 实现UserDao public interface UserDao { public void saveUser(User user); public User findUserById(int id); public User findUserByName(String name); public void updateUser(User user); public void remove(User user); } 北京传智播客教育 www.itcast.cn

基本功能练习 实验步骤: 1.设计domain对象User。 2.设计UserDao接口。 3.加入hibernate.jar和其依赖的包。 4.编写User.hbm.xml映射文件,可以基于hibernate/eg目录下的org/hibernate/auction/User.hbm.xml修改。 5.编写hibernate.cfg.xml配置文件,可以基于hibernate/etc/hibernate.cfg.xml修改;必须提供的几个参数: connection.driver_class、connection.url、connection.username、connection.password、dialect、hbm2ddl.auto。 6.编写HibernateUtils类,主要用来完成Hibnerate初始化和提供一个获得Session的方法;这步可选。 7.实现UserDao接口。 北京传智播客教育 www.itcast.cn

关联映射 多对一(Employee - Department) 一对多(Department-Employee) 一对一(room - door) 多对多(teacher - student) 组件映射(User-Name) 集合映射(set, list, map, bag) inverse和cascade(Employee – Department) 2 北京传智播客教育 www.itcast.cn

关联映射 多对一(Employee - Department) 映射文件<many-to-one name=”depart” column=”depart_id”/> ER图 北京传智播客教育 www.itcast.cn

关联映射 一对多(Department-Employee) <set name=”employees”> <key column=”depart_id”/> <one-to-many class=”Employee”/> </set> 北京传智播客教育 www.itcast.cn

关联映射 一对一(Person - IdCard) 1)基于主键的one-to-one(person的映射文件) <id name=”id”> <generator class=”foreign”><param name=”property”>idCard</param></generator> <id> <one-to-one name=”idCard” constrained=”true”/> 北京传智播客教育 www.itcast.cn

关联映射 一对一(Person - IdCard) <!-唯一的多对一,其实就便成了一对一了--> 2)基于外健的one-to-one,可以描述为多对一,加unique=“true”约束 <one-to-one name=”idCard” property-ref=“person”/> property-ref用于指定关联类的一个属性,这个属性将会和本外键相对应 <many-to-one name=”person” column=”person_id” unique=”true” not-null=”true”/>  <!-唯一的多对一,其实就便成了一对一了--> 北京传智播客教育 www.itcast.cn

关联映射 多对多(teacher - student) 在操作和性能方面都不太理想,所以多对多的映射使用较少,实际使用中最好转换成一对多的对象模型;Hibernate会为我们创建中间关联表,转换成两个一对多。 <set name="teacher" table="teacher_student"> <key column="teacher_id"/> <many-to-many class="Student" column="student_id"/> </set> 北京传智播客教育 www.itcast.cn

关联映射 组件映射(User-Name) 关联的属性是个复杂类型的持久化类,但不是实体即:数据库中没有表与该属性对应,但该类的属性要之久保存的。 <component name=”name” class=”com.test.hibernate.domain.Name”> <property name=”initial”/> <property name=”first”/> <property name=”last”/> </component> 当组件的属性不能和表中的字段简单对应的时候可以选择实现: org.hibernate.usertype. UserType或 org.hibernate.usertype. CompositeUserType 北京传智播客教育 www.itcast.cn

继承映射 对象模型(Java类结构) 北京传智播客教育 www.itcast.cn

继承映射 一个类继承体系一张表(subclass)(表结构) 北京传智播客教育 www.itcast.cn

继承映射 一个类继承体系一张表(subclass)(映射文件) <class name="Employee" table="employee" discriminator-value="0"> <id name="id"> <generator class="native"/> </id> <discriminator column="type" type="int"/> <property name="name"/> <many-to-one name=”depart” column=”depart_id”/> <subclass name="Skiller" discriminator-value="1"> <property name=”skill”/> </subclass> <subclass name="Sales" discriminator-value="2"> <property name="sell"/> </class> 北京传智播客教育 www.itcast.cn

继承映射 每个子类一张表(joined-subclass) (表结构) 北京传智播客教育 www.itcast.cn

继承映射 每个子类一张表(joined-subclass) (映射文件) <class name="Employee" table="employee"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <joined-subclass name="Skiller" table="skiller"> <key column="employee_id"/> <property name="skill"/> </joined-subclass> <joined-subclass name="Sales" table="sales"> <property name="sell"/> </class> 北京传智播客教育 www.itcast.cn

继承映射 混合使用“一个类继承体系一张表”和“每个子类一张表” (表结构) 北京传智播客教育 www.itcast.cn

继承映射 混合使用“一个类继承体系一张表”和“每个子类一张表” (映射文件) <class name="Employee" table="employee"> <id name="id"> <generator class="native"/> </id> <discriminator column="type"/> <property name="name"/> <subclass name="Skiller"> <property name="net"/> </subclass> <subclass name=”Sales”"> <join table="sales"> <key column="employee_id"/> <property name="sell"/> </join> </class> 北京传智播客教育 www.itcast.cn

继承映射 每个具体类一张表(union-subclass) (表结构) 北京传智播客教育 www.itcast.cn

继承映射 每个具体类一张表(union-subclass) (映射文件) <class name="Employee" abstract="true"> <id name="id"> <generator class="hilo"/> </id> <property name="name"/> <union-subclass name="Skiller" table="skiller"> <property name="skill"/> </union-subclass> <union-subclass name="Sales" table="sales"> <property name="sell"/> </class> 主健不能是identity类型,如果父类是abstract=”true”就不会有表与之对应。 隐式多态,映射文件没有联系,限制比较多很少使用。 北京传智播客教育 www.itcast.cn

集合映射 集合映射(set, list, array,bag, map) <set name=”employees” > <key column=”depart_id”/> <one-to-many class=”Employee”/> <!-- <element type="string" column="name"/> --> <!-- <composite-element class=”YourClass”> <property name=”prop1”/> <property name=”prop2”/> </composite> --> </set> 3 北京传智播客教育 www.itcast.cn

集合映射 集合映射(set, list, array,bag, map) <list name=”employees” > <key column=”depart_id”/> <!—表中有单独的整型列表示list-index  <list-index column=”order_column”/> <one-to-many class=”Employee”/> </list> <array name=”employees” > </array> 北京传智播客教育 www.itcast.cn

集合映射 集合映射(set, list, array,bag, map) <bag name="employees " order-by="id desc"> <key column=”depart_id”/> <one-to-many class=”Employee”/> </bag> <map name="employees "> <map-key type="string" column="name"/> </map> 北京传智播客教育 www.itcast.cn

集合映射 集合映射(set, list, array,bag, map) 这些集合类都是Hibernate实现的类和JAVA中的集合类不完全一样,set,list,map分别和JAVA中的Set,List,Map接口对应,bag映射成JAVA的List;这些集合的使用和JAVA集合中对应的接口基本一致;在JAVA的实体类中集合只能定义成接口不能定义成具体类, 因为集合会在运行时被替换成Hibernate的实现。 集合的简单使用原则:大部分情况下用set,需要保证集合中的顺序用list,想用java.util.List又不需要保证顺序用bag。 北京传智播客教育 www.itcast.cn

集合映射 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade: none,all,save-update ,delete, lock,refresh,evict,replicate,persist, merge,delete-orphan(one-to-many) 。一般对many-to-one,many-to-many不设置级联,在<one-to-one>和<one-to-many>中设置级联。 inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。 one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。 注: 配置成one-to-one的对象不维护关联关系 北京传智播客教育 www.itcast.cn

懒加载 通过asm和cglib二个包实现;Domain是非final的。 1.session.load懒加载。 2.one-to-one(元素)懒加载: 必需同时满足下面三个条件时才能实现懒加载 (主表不能有constrained=true,所以主表没有懒加载) lazy!=false 2)constrained=true 3)fetch=select 3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select 4.many-to-one (元素) :1)lazy!=false 2)fetch=select 5.many-to-many (元素) :1)lazy!=false 2)fetch=select 6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。 3 北京传智播客教育 www.itcast.cn

缓存 缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。 一级缓存,Session级共享。 save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中,一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。 北京传智播客教育 www.itcast.cn

缓存 二级缓存,SessionFactory级共享。 实现为可插拔,通过修改cache.provider_class参数来改变; hibernate内置了对EhCache,OSCache,TreeCache,SwarmCache的支持,可以通过实现CacheProvider和Cache接口来加入Hibernate不支持的缓存实现。 在hibernate.cfg.xml中加入: <class-cache class="className" usage="read-only"/> 或在映射文件的class元素加入子元素: <cache usage="read-write"/> 其中usage:read-only,read-write,nonstrict-read-write,transactional Session的:save(这个方法不适合native生成方式的主键), update,saveOrUpdate,list,iterator,get,load,以及Query,Criteria都会填充二级缓存,但只有(没打开查询缓存时)Session的iterator,get,load会从二级缓存中取数据(iterator可能存在N+1次查询)。 Query,Criteria(查询缓存)由于命中率较低,所以hibernate缺省是关闭;修改cache.use_query_cache为true打开对查询的缓存,并且调用query.setCacheable(true)或criteria.setCacheable(true)。 SessionFactory中提供了evictXXX()方法用来清除缓存中的内容。 统计信息打开generate_statistics,用sessionFactory.getSatistics()获取统计信息。 北京传智播客教育 www.itcast.cn

缓存 分布式缓存和中央缓存。 使用缓存的条件 1.读取大于修改。 2.数据量不能超过内存容量。 3.对数据要有独享的控制。 4.可以容忍出现无效数据。 北京传智播客教育 www.itcast.cn

事务 JDBCTransaction 单个数据库(一个SesisonFactory对应一个数据库),由JDBC实现。 Session session = null; Transaction tx =null; try { session = sessionFactory.openSession(); tx = session.beginTransaction(); //process tx.commit(); } catch(HibernateException e){ if(tx != null)tx.rollback();throw e; }finally { if (session != null)session.close(); } connection.setAutoCommit(false); connection.commit();conn.rollback(); 北京传智播客教育 www.itcast.cn

事务 JTATransaction 可以简单的理解成跨数据库的事物,由应用JTA 容器实现;使用JTATransaction需要配置hibernate.transaction.factory_class参数,该参数缺省值是org.hibernate.transaction. JDBCTransactionFactory,当使用JTATransaction时需要将该参数改成org.hibernate.transaction.JTATransactionFactory,并配置jta.UserTransaction参数JNDI名(Hibernate在启动JTATransaction时要用该值到JNDI的上下文Context中去找javax.transaction.UserTransaction)。 javax.transaction.UserTransactin tx = context.lookup(“jndiName”); try{ tx.begin(); //多个数据库的session操作; //session1…. //session2…. tx.commit(); }catch(Exception e){ tx.rollback(); throw e; } 北京传智播客教育 www.itcast.cn

事务 session context和事务边界 用current_session_context_class属性来定义context(用sessionFactory.getCurrentSession()来获得session),其值为: 1.thread:ThreadLocal来管理Session实现多个操作共享一个Session,避免反复获取Session,并控制事务边界,此时session不能调用close当commit或rollback的时候session会自动关闭(connection.release_mode:after_transaction)。 Open session in view:在生成(渲染)页面时保持 session打开。 2.jta:由JTA事务管理器来管理事务(connection.release_mode:after_statement)。 悲观锁和乐观锁 悲观锁由数据库来实现;乐观锁hibernate用version和timestamp来实现 北京传智播客教育 www.itcast.cn

其他问题 hibernate.cfg.xml和hbm.xml内容解释 数据类型 1.<property name=“name” type=“java.lang.String”/> type可以是hibernate、java类型或者你自己的类型(需要实现hibernate的一个接口)。 2.基本类型一般不需要在映射文件(hbm.xml)中说明,只有在一个JAVA类型和多个数据库数据类型相对应时并且你想要的和hibernate缺省映射不一致时,需要在映射文件中指明类型(如:java.util.Date,数据库DATE,TIME,DATATIME,TIMESTAMP,hibernate缺省会把java.util.Date映射成DATATIME型,而如果你想映射成TIME,则你必须在映射文件中指定类型)。 3.数据类型的对应关系见参考文档5.2.2 Session是非线程安全的,生命周期较短,代表一个和数据库的连接,在B/S系统中一般不会超过一个请求;内部维护一级缓存和数据库连接,如果session长时间打开,会长时间占用内存和数据库连接。 SessionFactory是线程安全的,一个数据库对应一个SessionFactory,生命周期长,一般在整个系统生命周期内有效;SessionFactory保存着和数据库连接的相关信息(user,password,url)和映射信息,以及Hibernate运行时要用到的一些信息。 4 北京传智播客教育 www.itcast.cn

其他问题 flush时将一级缓存与数据库同步 大批处理 大量操作数据时可能造成内存溢出,解决办法如下: 1.清除session中的数据 for(int i=0;i<100000;i++)session.save(obj); for(int i=0;i<100000;i++){ session.save(obj); if(i% 50 == 0){session.flush(); session.clear();} } 2.用StatelessSession接口:它不和一级缓存、二级缓存交互,也不触发任何事件、监听器、拦截器,通过该接口的操作会立刻发送给数据库,与JDBC的功能一样。 StatelessSession s = sessionFactory.openStatelessSession();该接口的方法与Session类似。 3.Query.executeUpdate()执行批量更新,会清除相关联的类二级缓存(sessionFactory.evict(class)),也可能会造成级联,和乐观锁定出现问题 北京传智播客教育 www.itcast.cn

其他问题 HQL 1查询多个对象select art, user from Article art, User user where art.author.id=user.id and art.id=:id这种方式返回的是Object[],Object[0]:article,Object[1]:user。 2分页query.setFirstResult,query.setMaxResults. 查询记录总数query.iterate(“select count(*) from Person”).next() 3批量更新query.executeUpdate()可能造成二级缓存有实效数据。 Criteria 1排序Criteria.addOrder(Order.desc(propertyName)); 2关联查询criteria.setFetchMode(“propertyName”, FetchMode.SELECT)与映射文件中关联关系的fetch作用一致。 3投影Projections.rowCount(),max(propertyName), avg, groupProperty… 4分页Projections.rowCount(),criteria.setFirstResult(),criteria.setMaxResults() 5DetachedCriteria可在session外创建(在其他层创建比如在Service中创建)然后用getExecutableCriteria(session)方法创建Criteria对象来完成查询。 6Example查询,Example.create(obj);criteria.add(example)。 北京传智播客教育 www.itcast.cn

其他问题 N+1次查询和懒加载 1.用Query.iterator可能会有N+1次查询。 2.懒加载时获取关联对象。 3.如果打开对查询的缓存即使用list也可能有N+1次查询。 拦截器与事件 拦截器与事件都是hibernate的扩展机制,Interceptor接口是老的实现机制,现在改成事件监听机制;他们都是hibernate的回调接口,hibernate在save,delete,update…等会回调这些类。 SQL和命名查询 用Map代替Domain对象;将对象转化为XML。 北京传智播客教育 www.itcast.cn

Hibernate不适合的场景 不适合OLAP(On-Line Analytical Processing联机分析处理),以查询分析数据为主的系统;适合OLTP(on-line transaction processing联机事务处理)。 对于些关系模型设计不合理的老系统,也不能发挥hibernate优势。 数据量巨大,性能要求苛刻的系统,hibernate也很难达到要求, 批量操作数据的效率也不高。 北京传智播客教育 www.itcast.cn

与JPA的集成(annotation方式) 需要添加的包ejb3-persistence.jar, hibernate-entitymanager.jar, hibernate-annotations.jar, hibernate-commons-annotations.jar, jboss-archive-browsing.jar, javassist.jar 配置文件%CLASSPATH%/META-INF/persistence.xml JAVA代码: EntityManagerFactory emf = Persistence.createEntityManagerFactory(name); //(Name:在persistence.xml中指定。) EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); Tx.begin(); Em.persist(entity);//remove,merge,find Tx.commit(); Em.close(); Emf.close(); 北京传智播客教育 www.itcast.cn

最佳实践 见hibernate参考文档 北京传智播客教育 www.itcast.cn