Hibernate教材.ppt_第1页
Hibernate教材.ppt_第2页
Hibernate教材.ppt_第3页
Hibernate教材.ppt_第4页
Hibernate教材.ppt_第5页
免费预览已结束,剩余232页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Hibernate 本课程简介 预备知识熟悉Java编程语言了解SQL以及JDBC编程 课程内容Java对象持久化技术概述创建Hibernate应用映射一对多关联关系域对象在持久化层的状态Hibernate检索策略数据库事务与并发 Java对象持久化技术概述 应用程序的分层体系结构Java应用的持久化层软件的模型概念模型关系数据模型域模型域对象域对象之间的关系域对象的持久化概念 直接通过JDBCAPI来持久化实体域对象ORM简介实体域对象的其他持久化模式主动域对象模式JDO模式CMP模式 应用程序的分层体系结构发展 双层应用应用程序层数据库层三层应用表述层业务逻辑层数据库层 四层应用表述层业务逻辑层持久化层数据库层N层应用 软件层的特征 层与层之间存在自上而下的依赖关系 即上层组件会访问下层组件的API 而下层组件不应该依赖上层组件 例如 表述层依赖于业务逻辑层 而业务逻辑层依赖于数据库层 每个层对上层公开API 但具体的实现细节对外透明 当某一层的实现发生变化 只要它的API不变 不会影响其他层的实现 软件分层的优点 1 伸缩性伸缩性指应用程序是否能支持更多的用户 应用的层越少 可以增加资源 如CPU和内存 的地方就越少 层数越多 可以将每层分布在不同的机器上2 可维护性可维护性指的是当发生需求变化 只需修改软件的某一部分 不会影响其他部分的代码 3 可扩展性可扩展性指的是在现有系统中增加新功能的难易程度 层数越多 就可以在每个层中提供扩展点 不会打破应用的整体框架 4 可重用性可重用性指的是程序代码没有冗余 同一个程序能满足多种需求 例如 业务逻辑层可以被多种表述层共享 5 可管理性可管理性指的是管理系统的难易程度 将应用程序分为多层后 可以将工作分解给不同的开发小组 从而便于管理 应用越复杂 规模越大 需要的层就越多 Java应用的持久化层 Hibernate是持久化层的一种实现方式 软件的模型 在软件开发领域 模型用来表示真实世界的实体 在软件开发的不同阶段 需要为目标系统创建不同类型的模型 在分析阶段 需要创建概念模型 在设计阶段 需要创建域模型和数据模型 模型之间的关系 概念模型 概念模型用来模拟问题域中的真实实体 概念模型描述了每个实体的概念和属性 以及实体之间的关系 概念模型并不描述实体的行为 不管是技术人员还是非技术人员都能看得懂概念模型 他们可以很容易的提出模型中存在的问题 帮助系统分析人员及早对模型进行修改 购物网站应用的概念模型 实体与实体之间存在三种关系 Customer和Order实体 一对多 一个客户有多个订单 而一个订单只能属于一个客户 Category和Item实体 多对多 一个商品类别包含多个商品 而一个商品可以属于多个商品类别 Order和Item实体 多对多 一个订单包含多个商品 而一个商品可以属于多个订单 Customer和ShoppingCart实体 一对多 一个客户有多个购物车 而一个购物车只能属于一个客户ShoppingCart和Item实体 多对多 一个购物车包含多个商品 而一个商品可以属于多个购物车 关系数据模型 关系数据模型是在概念模型的基础上建立起来的 用于描述这些关系数据的静态结构 它由以下内容组成 一个或多个表表的所有索引视图触发器表与表之间的参照完整性 表的主键 在关系数据库表中 用主键来识别记录并保证每条记录的惟一性 作为主键的字段必须满足以下条件 不允许为null 每条记录具有惟一的主键值 不允许主键值重复 每条记录的主键值永远不会改变 使用代理主键机制 代理主键不具有业务含义 不会被改变 尽量不使用自然主键 表与表之间的参照完整性 用连接表表示多对多关系 域模型 域模型是面向对象的 在面向对象术语中 域模型也可称为设计模型 域模型由以下内容组成 具有状态和行为的域对象域对象之间的关系关联依赖聚集一般化 域对象 域对象可以代表业务领域中的人 地点 事物或概念 域对象分为以下几种 实体域对象 业务领域的名词过程域对象 业务领域的动词事件域对象 业务领域中的事件 实体域对象 实体对象可以代表人 地点 事物或概念 例如客户 订单 商品等作为实体域对象 在J2EE应用中 这些名词可以作为实体EJB 对于普通的Web应用 这些名词可以作为包含状态和行为的JavaBean 采用JavaBean形式的实体域对象也称为POJO PlainOldJavaObject 为了使实体域对象与关系数据库表中记录对应 可以为每个实体域对象分配惟一的OID ObjectIdentifier 即对象标识符 OID是关系数据库表中的主键 通常为代理主键 在实体域对象中的等价物 过程域对象 过程域对象代表应用中的业务逻辑或流程 它们通常依赖于实体域对象 可以把业务领域中的动词 例如客户发出订单 登入应用等作为过程域对象 在J2EE应用中 它们通常作为会话EJB或者消息驱动EJB 在非J2EE应用中 它们可作为常规的JavaBean 具有管理和控制应用的行为 过程域对象也可以拥有状态 例如在J2EE应用中 会话EJB可分为有状态和无状态两种类型 事件域对象 事件域对象代表应用中的一些事件 如异常 警告或超时 这些事件通常由系统中的某种行为触发 例如在多用户环境中 当一个客户端程序更新了某种实时数据 服务器端程序会创建一个事件域对象 其他正在浏览相同数据的客户端程序能够接受到这一事件域对象 随即同步刷新客户界面 域对象之间的关系 关联 Association 依赖 Dependency 聚集 Aggregation 一般化 Generalization 关联关系 依赖关系 在BusinessService类中访问Customer类的方法 并且构造Customer类的实例 聚集关系 聚集指的是整体与部分之间的关系 在实体域对象之间很常见 一般化关系 一般化指的是类之间的继承关系 域对象的持久化概念 域对象的持久化概念 狭义的理解 持久化 仅仅指把域对象永久保存到数据库中广义的理解 持久化 包括和数据库相关的各种操作 保存 把域对象永久保存到数据库中 更新 更新数据库中域对象的状态 删除 从数据库中删除一个域对象 加载 根据特定的OID 把一个域对象从数据库加载到内存中 查询 根据特定的查询条件 把符合查询条件的一个或多个域对象从数据库加载到内存中 通过JDBCAPI来持久化实体域对象 Java应用访问数据库的最直接的方式就是直接访问JDBCAPI JDBC是JavaDatabaseConnectivity的缩写 java sql包提供了JDBCAPI 在java sql包中常用的接口和类包括 DriverManager 驱动程序管理器 负责创建数据库连接 Connection 代表数据库连接 Statement 负责执行SQL语句 PreparedStatement 负责执行SQL语句 具有预定义SQL语句的功能 ResultSet 代表SQL查询语句的查询结果集 JDBCAPI 负责持久化Customer对象的BusinessService saveCustomer 把Customer域对象永久保存到数据库中 updateCustomer 更新数据库中Customer域对象的状态 deleteCustomer 从数据库中删除一个Customer域对象 loadCustomer 根据特定的OID 把一个Customer域对象从数据库加载到内存中 findCustomerByName 根据特定的客户姓名 把符合查询条件的Customer域对象从数据库加载到内存中 业务逻辑代码与数据访问代码耦合的saveCustomer 方法 con getConnection 获得数据库连接 开始一个数据库事务con setAutoCommit false 以下是业务逻辑代码 检查客户姓名是否为空if customer getName null thrownewBusinessException 客户姓名不允许为空 以下是数据访问代码 持久化Customer对象 为新的CUSTOMERS记录分配惟一的IDlongcustomerId getNextId con CUSTOMERS 把Customer对象映射为面向关系的SQL语句stmt con prepareStatement insertintoCUSTOMERS ID NAME AGE values stmt setLong 1 customerId stmt setString 2 customer getName stmt setInt 3 customer getAge stmt execute 业务逻辑代码与数据访问代码耦合的saveCustomer 方法 Iteratoriterator customer getOrders iterator while iterator hasNext 以下是业务逻辑代码 检查订单编号是否为空Orderorder Order iterator next if order getOrderNumber null thrownewBusinessException 订单编号不允许为空 以下是数据访问代码 级联持久化Order对象 为新的ORDERS记录分配惟一的IDlongorderId getNextId con ORDERS 把Order对象映射为面向关系的SQL语句stmt con prepareStatement insertintoORDERS ID ORDER NUMBER PRICE CUSTOMER ID values stmt setLong 1 orderId stmt setString 2 order getOrderNumber stmt setDouble 3 order getPrice stmt setLong 4 customerId stmt execute 提交数据库事务mit JDBC编程的缺点 实现业务逻辑的代码和数据库访问代码掺杂在一起 使程序结构不清晰 可读性差 在程序代码中嵌入面向关系的SQL语句 使开发人员不能完全运用面向对象的思维来编写程序 业务逻辑和关系数据模型绑定 如果关系数据模型发生变化 例如修改了CUSTOMERS表的结构 那么必须手工修改程序代码中所有相关的SQL语句 这增加了维护软件的难度 如果程序代码中的SQL语句包含语法错误 在编译时不能检查这种错误 只有在运行时才能发现这种错误 这增加了调试程序的难度 数据访问模式 业务逻辑和数据访问耦合ORM模式 在单个组件中负责所有实体域对象的持久化 封装数据访问细节 主动域对象模式 由实体域对象本身负责管理自己的持久化JDO模式 SUN公司制定的描述对象持久化语义的标准APICMP模式 由容器负责管理持久化 ORM模式 对象 关系映射 Object RelationMapping 的概念 ORM解决的主要问题就是对象 关系的映射 域模型和关系模型都分别建立在概念模型的基础上 域模型是面向对象的 而关系数据模型是面向关系的 一般情况下 一个持久化类和一个表对应 类的每个实例对应表中的一条记录 域模型与关系模型之间存在许多不匹配之处 域模型与关系模型之间存在许多不匹配之处 域模型中有继承关系 关系模型不能直接表示继承关系域模型中有多对多关联关系 关系模型通过连接表来表示多对多关联关系域模型中有双向关联关系 关系模型只有单向参照关系 而且总是many方参照one方 域模型提倡精粒度模型 而关系模型提倡粗粒度模型 域模型与关系模型之间的不匹配举例 精粒度域模型和粗粒度关系模型 第一个Hibernate应用 教学目标创建Hibernate的配置文件创建持久化类创建数据库Schema创建对象 关系映射文件映射文件的文档类型定义 DTD 把Customer持久化类映射到CUSTOMERS表通过HibernateAPI操纵数据库用ANT工具管理项目 在Java应用中使用Hibernate的步骤 创建Hibernate的配置文件创建持久化类创建对象 关系映射文件通过HibernateAPI编写访问数据库的代码 Helloapp应用的结构 Hibernate的配置文件 hibernate properties hibernate dialect net sf hibernate dialect MySQLDialecthibernate connection driver class com mysql jdbc Driverhibernate connection url jdbc mysql localhost 3306 SAMPLEDBhibernate connection username roothibernate connection password 1234hibernate show sql true Hibernate配置文件的属性 创建持久化类Customer 持久化类符合JavaBean的规范 包含一些属性 以及与之对应的getXXX 和setXXX 方法 持久化类有一个id属性 用来惟一标识Customer类的每个对象 在面向对象术语中 这个id属性被称为对象标识符 OID ObjectIdentifier 通常它都用整数表示Hibernate要求持久化类必须提供一个不带参数的默认构造方法 创建数据库Schema createtableCUSTOMERS IDbigintnotnullprimarykey NAMEvarchar 15 notnull EMAILvarchar 128 notnull PASSWORDvarchar 8 notnull PHONEint ADDRESSvarchar 255 SEXchar 1 IS MARRIEDbit DESCRIPTIONtext IMAGEblob BIRTHDAYdate REGISTERED TIMEtimestamp 创建对象 关系映射文件Customer hbm xml 元素映射OID 子元素用来设定标识符生成器 Hibernate提供了提供了多种内置的实现 元素映射值类型属性 name属性 指定持久化类的属性的名字 type属性 指定Hibernate映射类型 Hibernate映射类型是Java类型与SQL类型的桥梁 column属性 指定与类的属性映射的表的字段名 Java类型 Hibernate映射类型以及SQL类型之间的对应关系 Customer hbm xml配置的对象 关系映射 采用XML文件来配置对象 关系映射的优点 Hibernate既不会渗透到上层域模型中 也不会渗透到下层数据模型中 软件开发人员可以独立设计域模型 不必强迫遵守任何规范 数据库设计人员可以独立设计数据模型 不必强迫遵守任何规范 对象 关系映射不依赖于任何程序代码 如果需要修改对象 关系映射 只需修改XML文件 不需要修改任何程序 提高了软件的灵活性 并且使维护更加方便 通过HibernateAPI操纵数据库 通过HibernateAPI操纵数据库 创建BusinessService类 初始化Hibernate通过Hibernate的Session接口操纵数据库 保存Customer对象更新Customer对象加载Customer对象删除Customer对象检索Customer对象 Hibernate的初始化 static try 根据默认位置的Hibernate配置文件的配置信息 创建一个 Configuration实例Configurationconfig newConfiguration config addClass Customer class 创建SessionFactory实例 sessionFactory config buildSessionFactory catch Exceptione e printStackTrace Hibernate的初始化 1 创建一个Configuration类的实例 Configuration类的构造方法把默认文件路径下的hibernate properties配置文件中的配置信息读入到内存 Configurationconfig newConfiguration 2 调用Configuration类的addClass Customer class 方法 config addClass Customer class 该方法把默认文件路径下的Customer hbm xml文件中的映射信息读入到内存中 3 调用Configuration类的buildSessionFactory 方法 sessionFactory config buildSessionFactory SessionFactory接口 一个SessionFactory实例对应一个数据存储源 应用从SessionFactory中获得Session实例 SessionFactory有以下特点 它是线程安全的 这意味着它的同一个实例可以被应用的多个线程共享 它是重量级的 这意味着不能随意创建或销毁它的实例 如果应用只访问一个数据库 只需要创建一个SessionFactory实例 在应用初始化的时候创建该实例 如果应用同时访问多个数据库 则需要为每个数据库创建一个单独的SessionFactory实例 Session接口 Session接口是Hibernate应用使用最广泛的接口 Session也被称为持久化管理器 它提供了和持久化相关的操作 如添加 更新 删除 加载和查询对象 Session有以下特点 不是线程安全的 因此在设计软件架构时 应该避免多个线程共享同一个Session实例 Session实例是轻量级的 所谓轻量级是指它的创建和销毁不需要消耗太多的资源 这意味着在程序中可以经常创建或销毁Session对象 例如为每个客户请求分配单独的Session实例 或者为每个工作单元分配单独的Session实例 Session接口操纵数据库的方法 Session接口提供了操纵数据库的各种方法 如 save 方法 把Java对象保存数据库中 update 方法 更新数据库中的Java对象 delete 方法 把Java对象从数据库中删除 load 方法 从数据库中加载Java对象 find 方法 从数据库中查询Java对象 用Session来执行事务的流程 Sessionsession factory openSession Transactiontx try 开始一个事务tx session beginTransaction 执行事务 提交事务mit catch Exceptione 如果出现异常 就撤销事务if tx null tx rollback throwe finally 不管事务执行成功与否 最后都关闭Sessionsession close 正常执行数据库事务的流程 saveCustomer 方法 该方法调用Session的save 方法 把Customer对象持久化到数据库中 tx session beginTransaction session save customer mit 当运行session save 方法时 Hibernate执行以下SQL语句 insertintoCUSTOMERS ID NAME EMAIL PASSWORD PHONE ADDRESS SEX IS MARRIED DESCRIPTION IMAGE BIRTHDAY REGISTERED TIME values 1 Tom tom 1234 55556666 Shanghai M 0 Iamveryhonest 1980 05 06 null 在test 方法中并没有设置Customer对象的id属性 Hibernate会根据映射文件的配置 采用increment标识符生成器自动以递增的方式为OID赋值 在Customer hbm xml文件中相关的映射代码如下 findAllCustomers 方法 该方法调用Session的find 方法 查询所有的Customer对象 tx session beginTransaction Listcustomers session find fromCustomerascorderbyc nameasc for Iteratorit customers iterator it hasNext printCustomer context out Customer it next mit Session的find 方法有好几种重载形式 本例中传递的是字符串参数 fromCustomerascorderbyc nameasc 它使用的是Hibernate查询语言 运行session find 方法时 Hibernate执行以下SQL语句 select fromCUSTOMERSorderbyNAMEasc loadAndUpdateCustomer 方法 该方法调用Session的load 方法 加载Customer对象 然后再修改Customer对象的属性 tx session beginTransaction Customerc Customer session load Customer class customer id c setAddress address mit 以上代码先调用Session的load 方法 它按照参数指定的OID从数据库中检索出匹配的Customer对象 Hibernate会执行以下SQL语句 select fromCUSTOMERSwhereID 1 loadAndUpdateCustomer 方法接着修改Customer对象的address属性 那么 Hibernate会不会同步更新数据库中相应的CUSTOMERS表的记录呢 答案是肯定的 Hibernate采用脏检查机制 按照内存中的Customer对象的状态的变化 来同步更新数据库中相关的数据 Hibernate会执行以下SQL语句 updateCUSTOMERSsetNAME Tom EMAIL Tom ADDRESS Beijing whereID 1 尽管只有Customer对象的address属性发生了变化 但是Hibernate执行的update语句中会包含所有的字段 printCustomer 方法 该方法打印Customer对象的信息 privatevoidprintCustomer Customercustomer throwsException byte buffer customer getImage FileOutputStreamfout newFileOutputStream photo copy gif fout write buffer fout close System out println 以下是 customer getName 的个人信息 System out println ID customer getId System out println 口令 customer getPassword System out println E Mail customer getEmail System out println 电话 customer getPhone deleteAllCustomers 方法 该方法调用Session的delete 方法 删除所有的Customer对象 tx session beginTransaction session delete fromCustomerasc mit 运行session delete 方法时 Hibernate先执行select语句 查询CUSTOMERS表的所有Customer对象 select fromCUSTOMERS 接下来Hibernate根据Customer对象的OID 依次删除每个对象 deletefromCUSTOMERSwhereID 1 用ANT工具管理项目 在build xml文件中先定义了三个属性 source root属性指定Java源文件的路径 class root属性指定Java类的路径 lib dir属性指定所有JAR文件的路径 用ANT工具管理项目 在build xml文件中接着定义了三个target preparetarget 如果存在classes子目录 先将它删除 接着重新创建classes子目录 然后把src子目录下所有扩展名为 properties hbm xml xml 以及 gif 的文件拷贝到WEB INF classes目录下 compiletarget 编译src子目录下的所有Java源文件 编译生成的类文件存放在WEB INF classes子目录下 runtarget 运行BusinessService类 元素的depends属性指定所依赖的target 当运行runtarget时 会依次执行preparetarget compiletarget和runtarget 映射一对多关联关系 教学内容创建具有一对多关联关系的域模型创建具有一对多参照关系的关系模型映射一对多关联关系通过HibernateAPI级联操纵具有关联关系的域对象 Customer和Order的一对多双向关联 在Customer类中关联Order类 publicclassCustomerimplementsSerializable privateSetorders newHashSet publicSetgetOrders returnorders publicvoidsetOrders this orders orders ORDERS表参照CUSTOMERS表 数据库Schema createtableCUSTOMERS IDbigintnotnull NAMEvarchar 15 primarykey ID createtableORDERS IDbigintnotnull ORDER NUMBERvarchar 15 CUSTOMER IDbigintnotnull primarykey ID altertableORDERSaddindexIDX CUSTOMER ID CUSTOMER ID addconstraintFK CUSTOMER IDforeignkey CUSTOMER ID referencesCUSTOMERS ID 映射Order类 Order hbm xml Order类的orderNumber属性为值类型 而customer属性为实体类型 实体类型具有单独的OID 元素的属性 name 设定待映射的持久化类的属性名 此处为Order类的customer属性 column 设定和持久化类的属性对应的表的外键 此处为ORDERS表的外键CUSTOMER ID class 设定持久化类的属性的类型 此处设定customer属性为Customer类型 映射Customer类 Customer hbm xml 映射Customer类 Customer hbm xml 续 元素的属性 元素包括以下属性 name 设定待映射的持久化类的属性名 这里为Customer类的orders属性cascade 当取值为 save update 表示级联保存和更新 inverse 当取值为 true 表示在双向关联中 这一端为镜像端 元素还包含两个子元素 和 元素设定所关联的持久化类 此处为Order类 元素设定与所关联的持久化类对应的表的外键 此处为ORDERS表的CUSTOMER ID字段 cascade属性的取值 级联保存Customer和Order对象 tx session beginTransaction Customercustomer newCustomer Tom newHashSet Orderorder newOrder order setOrderNumber Tom Order001 建立双向关联关系order setCustomer customer customer getOrders add order session save customer mit Hibernate实用工具 Java源文件 数据库Schema 对象 关系映射文件 hbm2java XDoclet hbm2ddl Middlegen 在build xml中定义codegentarget 在build xml中定义schematarget 映射Category一对多双向自身关联关系 Category类的类框图 Category类的源程序 publicclassCategoryimplementsSerializable privateCategoryparentCategory privateSetchildCategories newHashSet publicCategorygetParentCategory returnparentCategory publicvoidsetParentCategory CategoryparentCategory this parentCategory parentCategory publicSetgetChildCategories returnchildCategories publicvoidsetChildCategories SetchildCategories this childCategories childCategories CATEGORIES表的结构 数据库Schema createtableCATEGORIES IDbigintnotnull NAMEvarchar 15 CATEGORY IDbigint primarykey ID altertableCATEGORIESaddindexIDX CATEGORY ID CATEGORY ID addconstraintFK CATEGORY IDforeignkey CATEGORY ID referencesCATEGORIES ID 映射parentCategory属性 映射childCategories属性 操纵Category对象 级联保存Category对象saveCategoryWithCascade 级联删除Category对象deleteCategoryWithCascade 域对象在持久化层的三种状态 教学内容Session的缓存的作用Session清理缓存的时间点对象的临时状态 持久化状态和游离状态用Session的update 方法使游离对象转变为持久化对象 理解Session的缓存 当Session的save 方法持久化一个Customer对象时 Customer对象被加入到Session的缓存中 以后即使应用程序中的引用变量不再引用Customer对象 只要Session的缓存还没有被清空 Customer对象仍然处于生命周期中 当Session的load 方法试图从数据库中加载一个Customer对象时 Session先判断缓存中是否已经存在这个Customer对象 如果存在 就不需要再到数据库中检索 理解Session的缓存 tx session beginTransaction Customerc1 newCustomer Tom newHashSet Customer对象被持久化 并且加入到Session的缓存中session save c1 Longid c1 getId c1变量不再引用Customer对象c1 null 从Session缓存中读取Customer对象 使c2变量引用Customer对象Customerc2 Customer session load Customer class id mit 关闭Session 清空缓存session close 访问Customer对象System out println c2 getName c2变量不再引用Customer对象 此时Customer对象结束生命周期 c2 null 理解Session的缓存 tx session beginTransaction Customerc1 Customer session load Customer class newLong 1 Customerc2 Customer session load Customer class newLong 1 System out println c1 c2 mit session close Session的缓存的作用 1 减少访问数据库的频率 应用程序从内存中读取持久化对象的速度显然比到数据库中查询数据的速度快多了 因此Session的缓存可以提高数据访问的性能 2 保证缓存中的对象与数据库中的相关记录保持同步 当缓存中持久化对象的状态发生了变换 Session并不会立即执行相关的SQL语句 这使得Session能够把几条相关的SQL语句合并为一条SQL语句 以便减少访问数据库的次数 从而提高应用程序的性能 Session清理缓存 清理缓存是指按照缓存中对象的状态的变化来同步更新数据库以下程序代码对Customer的name属性修改了两次 tx session beginTransaction Customercustomer Customer session load Customer class newLong 1 customer setName Jack customer setName Mike mit 当Session清理缓存时 只需执行一条update语句 updateCUSTOMERSsetNAME Mike whereID 1 清理缓存的时间点 Session会在下面的时间点清理缓存 当应用程序调用net sf hibernate Transaction的commit 方法的时候 commit 方法先清理缓存 然后再向数据库提交事务 当应用程序调用Session的find 或者iterate 时 如果缓存中持久化对象的属性发生了变化 就会先清理缓存 以保证查询结果能反映持久化对象的最新状态 当应用程序显式调用Session的flush 方法的时候 Hibernate的二级缓存结构 Hibernate提供了两级缓存 第一级缓存是Session的缓存 由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务 因此它的缓存是事务范围的缓存 第一级缓存是必须的 不允许而且事实上也无法被卸除 在第一级缓存中 持久化类的每个实例都具有惟一的OID 第二级缓存是一个可插拔的缓存插件 它由SessionFactory负责管理 由于SessionFactory对象的生命周期和应用程序的整个进程对应 因此第二级缓存是进程范围或群集范围的缓存 这个缓存中存放的是对象的散装数据 第二级缓存是可选的 可以在每个类或每个集合的粒度上配置第二级缓存 Hibernate的二级缓存结构 在Hibernate应用中Java对象的状态 临时状态 transient 刚刚用new语句创建 还没有被持久化 不处于Session的缓存中 处于临时状态的Java对象被称为临时对象 持久化状态 persistent 已经被持久化 加入到Session的缓存中 处于持久化状态的Java对象被称为持久化对象 游离状态 detached 已经被持久化 但不再处于Session的缓存中 处于游离状态的Java对象被称为游离对象 Customer对象的状态转换过程 用Session的update 方法关联游离对象 Customercustomer newCustomer customer setName Tom Sessionsession1 sessionFactory openSession Transactiontx1 session1 beginTransaction session1 save customer mit session1 close 此时Customer对象变为游离对象Sessionsession2 sessionFactory openSession Transactiontx2 session1 beginTransaction customer setName Linda 在和session2关联之前修改Customer对象的属性session2 update customer customer setName Jack 在和session2关联之后修改Customer对象的属性mit session2 close Session的update 方法 Session的update 方法完成以下操作 1 把Customer对象重新加入到Session缓存中 使它变为持久化对象 2 计划执行一个update语句 值得注意的是 Session只有在清理缓存的时候才会执行update语句 并且在执行时才会把Customer对象当前的属性值组装到update语句中 因此 即使程序中多次修改了Customer对象的属性 在清理缓存时只会执行一次update语句 客户层与业务逻辑层之间传递临时对象和游离对象的过程 Hibernate的检索策略 教学内容立即检索策略延迟检索策略迫切左外连接检索策略每种检索策略的适用范围在程序中显式指定迫切左外连接检索策略 CUSTOMERS表和ORDERS表中的记录 运行Session的find 方法 ListcustomerLists session find fromCustomerasc 运行以上find 方法时 Hibernate将先查询CUSTOMERS表中所有的记录 然后根据每条记录的ID 到ORDERS表中查询有参照关系的记录 Hibernate将依次执行以下select语句 select fromCUSTOMERS select fromORDERSwhereCUSTOMER ID 1 select fromORDERSwhereCUSTOMER ID 2 select fromORDERSwhereCUSTOMER ID 3 select fromORDERSwhereCUSTOMER ID 4 Customer与Order对象的关联对象图 默认的立即检索策略的缺点 select语句的数目太多 需要频繁的访问数据库 会影响检索性能 如果需要查询n个Customer对象 那么必须执行n 1次select查询语句 这种检索策略没有利用SQL的连接查询功能 例如以上5条select语句完全可以通过以下1条select语句来完成 select fromCUSTOMERSleftouterjoinORDERSonCUSTOMERS ID ORDERS CUSTOMER ID以上select语句使用了SQL的左外连接查询功能 能够在一条select语句中查询出CUSTOMERS表的所有记录 以及匹配的ORDERS表的记录 在应用逻辑只需要访问Customer对象 而不需要访问Order对象的场合 加载Order对象完全是多余的操作 这些多余的Order对象白白浪费了许多内存空间 在一对多关联级别使用延迟检索策略 对于元素 应该优先考虑使用延迟检索策略 此时运行 Customercustomer Customer session get Customer class newLong 1 仅立即检索Customer对象 执行以下select语句 select fromCUSTOMERSwhereID 1 在一对多关联级别使用延迟检索策略 Customer对象的orders变量引用集合代理类实例 当应用程序第一次访问它 例如调用customer getOrders iterator 方法时 Hibernate会初始化这个集合代理类实例 在初始化过程中到数据库中检索所有与Customer关联的Order对象 执行以下select语句 select fromORDERSwhereCUSTOMER ID 1 访问没有被初始化的游离状态的集合代理类实例 Sessionsession sessionFactory openSession tx session beginTransaction Customercustomer Customer session get Customer class newLong 1 mit session close 抛出异常IteratororderIterator customer getOrders iterator 执行以上代码 会抛出以下异常 ERRORLazyInitializer 63 Exceptioninitializingproxy 延迟检索策略 优点由应用程序决定需要加载哪些对象 可以避免执行多余的select语句 以及避免加载应用程序不需要访问的对象 因此能提高检索性能 并且能节省内存空间 缺点应用程序如果希望访问游离状态的代理类实例 必须保证它在持久化状态时已经被初始化 适用范围一对多或者多对多关联 应用程序不需要立即访问或者根本不会访问的对象 在多对一关联级别使用迫切左外连接检索策略 默认情况下 多对一关联使用迫切左外连接检索策略 如果把Order hbm xml文件的元素的outer join属性设为true 总是使用迫切左外连接检索策略 对于以下程序代码 Orderorder Order session get Order class newLong 1 在运行session get 方法时 Hibernate执行以下select语句 select fromORDERSleftouterjoinCUSTOMERSonORDERS CUSTOMER ID CUSTOMERS IDwhereORDERS ID 1 迫切左外连接检索策略 优点1 对应用程序完全透明 不管对象处于持久化状态 还是游离状态 应用程序都可以方便的从一个对象导航到与它关联的对象 2 使用了外连接 select语句数目少 缺点1 可能会加载应用程序不需要访问的对象 白白浪费许多内存空间 2 复杂的数据库表连接也会影响检索性能 适用范围1 多对一或者一对一关联 2 应用程序需要立即访问的对象 3 数据库系统具有良好的表连接性能 在程序中显式指定迫切左外连接检索策略 在映射文件中设定的检索策略是固定的 要么为延迟检索 要么为立即检索 要么为外连接检索 但应用逻辑是多种多样的 有些情况下需要延迟检索 而有些情况下需要外连接检索 Hibernate允许在应用程序中覆盖映射文件中设定的检索策略 由应用程序在运行时决定检索对象图的深度 在程序中显式指定迫切左外连接检索策略 以下Session的find 方法都用于检索OID为1的Customer对象 session find fromCustomerascwherec id 1 session find fromCustomerascleftjoinfetchc orderswherec id 1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论