J2EE的SSH框架的搭建和性能优化本科毕业论文.doc_第1页
J2EE的SSH框架的搭建和性能优化本科毕业论文.doc_第2页
J2EE的SSH框架的搭建和性能优化本科毕业论文.doc_第3页
J2EE的SSH框架的搭建和性能优化本科毕业论文.doc_第4页
J2EE的SSH框架的搭建和性能优化本科毕业论文.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

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

文档简介

保定电力职业技术学院 顶岗实习技术应用论文 题 目 j2ee 的 ssh 框架的搭建和性能优化 系 部 信息工程与管理系 保定电力职业技术学院顶岗实习技术应用(论文) - 2 - 目录目录 j2eej2ee 的的 sshssh 框架的搭建和性能优化框架的搭建和性能优化 .- 3 - 摘要摘要 - 3 - 1.1.引言引言 - 3 - 2.2. springspring + + strutsstruts +hibernate+hibernate 简介简介 - 4 - 2.1 struts框架结构.- 4 - 2.1.1model部分.- 4 - 2.1.2.view部分- 4 - 2.1.3.controller组件.- 5 - 2.2 spring.- 5 - 2.2.1.轻量.- 5 - 2.2.2.控制反转.- 5 - 2.2.3.面向切面.- 5 - 2.2.4.容器.- 5 - 2.2.5.框架.- 6 - 2.3 hibernate- 6 - 2.3.1.session接口- 6 - 2.3.2.sessionfactory接口.- 6 - 2.3.3.configuration接口.- 7 - 2.3.4.transaction接口.- 7 - 2.3.5.query和criteria接口.- 7 - 3.3.阐述阐述 sshssh 整合框架整合框架 - 7 - 3.1 集成 ssh 框架.- 7 - 4.4. 基于基于 sshssh 框架的框架的 webweb 应用系统的实现应用系统的实现 - 8 - 4.1 数据持久层.- 8 - 4.2 业务逻辑层.- 8 - 4.3 表示层.- 10 - 5 5 sshssh 性能的优化性能的优化 .- 10 - 5.1 struts优化- 10 - 5.1.1 logging和开和开发发模式模式.- 10 - 5.1.2. 拦拦截器截器- 11 - 5.1.3.缓缓存和存和过过期期时间时间.- 11 - 5.1.4. ajax theme(dojo)或者或者calendar标签标签.- 11 - 5.1.5. freemark载载入模板入模板- 11 - 5.1.6.freemark模板模板缓缓存存.- 11 - 5.1.7. 模板路径模板路径- 11 - 5.1.8. session- 11 - 保定电力职业技术学院顶岗实习技术应用(论文) - 3 - 5.1.9.标签标签的使用的使用.- 12 - 5.2 spring 优化 .- 12 - 5.3 hibernate 优化 - 13 - 5.3.1、 数据库设计- 13 - 5.3.3、 主配置- 14 - 5.3.4、 缓存- 14 - 5.3.5、 延迟加载- 14 - 5.3.6、 方法选用- 15 - 5.3.7、 集合的选用- 15 - 5.3.8、 事务控制- 15 - 5.3.9、 批量操作- 16 - 5.3.10、hibernate的缓存.- 16 - 5.3.11hibernate性能调优.- 18 - 6.6.结语结语 - 20 - 致谢致谢 - 21 - 参考文献参考文献 - 22 - 保定电力职业技术学院顶岗实习技术应用(论文) - 4 - j2ee 的 ssh 框架的搭建和性能优化 姓名:李朝云 班级:软件 1101 班 学号:180111121 摘要 针对当前 web 应用程序开发面临的问题,结合目前比较流行的开源框架 spring、strut s 和 hibernate,提出了一种开发 j2ee web 应用的轻量级解决方案,以帮助开发人员 在短期内搭建结构清晰、可复用性好、维护方便的 web 应用程序。并且,通过案例具 体说明了如何将这一方案应用到实际项目中。 关关键词键词:j2ee mvc struts spring hibernate 1.引言 大型企业级 web 应用系统的开发通常要求有一个良好的软件架构、便于协作开 发和扩展升级,而传统的开发模式不能很好地满足这些要求。本文针对当前 web 应 用程序开发面临的问题,结合目前比较流行的开源框架 ssh(spring、struts、hibernate), 提出一种开发 j2ee 企业级 web 应用的轻量级解决方案,并通过案例具体说明如何 将这一方案应用到实际项目中。 2. spring + struts +hibernate 简介 ssh 在 j2ee 项目中表示了 3 种框架,即 spring + struts +hibernate。 struts 对 model,view 和 controller 都提供了对应的组件。spring 是一个轻量级的控制反转(ioc)和面 向切面(aop)的容器框架,它由 rod johnson 创建。它是为了解决企业应用开发的复杂性而创 建的。spring 使用基本的 javabean 来完成以前只可能由 ejb 完成的事情。 hibernate 是一个 开放源代码的对象关系映射框架,它对 jdbc 进行了非常轻量级的对象封装,可以应用在任 何使用 jdbc 的场合,可以在 servlet/jsp 的 web 应用中使用,也可以在应用 ejb 的 j2ee 架 构中取代 cmp,完成数据持久化的重任。 保定电力职业技术学院顶岗实习技术应用(论文) - 5 - 2.1 struts 框架结构 如图: struts 对 model,view 和 controller 都提供了对应的组件。 在右图中,actionservlet,这个类是 struts 的核心控制器,负责拦截来自用户的请求。 action,这个类通常由用户提供,该控制器负责接收来自 actionservlet 的请求,并根 据该请求调用模型的业务逻辑方法处理请求,并将处理结果返回给 jsp 页面显示。 2.1.1model 部分部分 由 actionform 和 javabean 组成,其中 actionform 用于封装用户的请求参数,封装 成 actionform 对象,该对象被 actionservlet 转发给 action,action 根据 actionform 里面的请求参数处理用户的请求。 javabean 则封装了底层的业务逻辑,包括数据库访问等。 2.1.2.view 部分部分 该部分采用 jsp 实现。 struts 提供了丰富的标签库,通过标签库可以减少脚本的使用,自定义的标签库可以 实现与 model 的有效交互,并增加了现实功能。对应上图的 jsp 部分。 保定电力职业技术学院顶岗实习技术应用(论文) - 6 - 2.1.3.controller 组组件件 controller 组件有两个部分组成系统核心控制器,业务逻辑控制器。 系统核心控制器,对应上图的 actionservlet。该控制器由 struts 框架提供,继承 httpservlet 类,因此可以配置成标注的 servlet。该控制器负责拦截所有的 http 请求, 然后根据用户请求决定是否要转给业务逻辑控制器。 业务逻辑控制器,负责处理用户请求,本身不具备处理能力,而是调用 model 来完成 处理。对应 action 部分。 2.22.2 springspring 简介简介 目的:解决企业应用开发的复杂性 功能:使用基本的 javabean 代替 ejb,并提供了更多的企业应用功能 范围:任何 java 应用 简单来说,spring 是一个轻量级的控制反转(ioc)和面向切面(aop)的容器框架。 2.2.1.轻轻量量 从大小与开销两方面而言 spring 都是轻量的。完整的 spring 框架可以在一个大小 只有 1mb 多的 jar 文件里发布。并且 spring 所需的处理开销也是微不足道的。此外, spring 是非侵入式的:典型地,spring 应用中的对象不依赖于 spring 的特定类。 2.2.2.控制反控制反转转 spring 通过一种称作控制反转(ioc)的技术促进了松耦合。当应用了 ioc,一个对象依 赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖 对象。你可以认为 ioc 与 jndi 相反不是对象从容器中查找依赖,而是容器在对 保定电力职业技术学院顶岗实习技术应用(论文) - 7 - 象初始化时不等对象请求就主动将依赖传递给它。 2.2.3.面向切面面向切面 spring 提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务 (例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它 们应该做的完成业务逻辑仅此而已。它们并不负责(甚至是意识)其它的系统 级关注点,例如日志或事务支持。 2.2.4.容器容器 spring 包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以 配置你的每个 bean 如何被创建基于一个可配置原型(prototype),你的 bean 可以 创建一个单独的实例或者每次需要时都生成一个新的实例以及它们是如何相互 关联的。然而,spring 不应该被混同于传统的重量级的 ejb 容器,它们经常是庞大与 笨重的,难以使用。 2.2.5.框架框架 spring 可以将简单的组件配置、组合成为复杂的应用。在 spring 中,应用对象被声明 式地组合,典型地是在一个 xml 文件里。spring 也提供了很多基础功能(事务管理、 持久化框架集成等等),将应用逻辑的开发留给了你。 所有 spring 的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它 们也为 spring 中的各种模块提供了基础支持。 2.32.3 hibernatehibernate 简介简介 hibernate 是一个开放源代码的对象关系映射框架,它对 jdbc 进行了非常轻量 保定电力职业技术学院顶岗实习技术应用(论文) - 8 - 级的对象封装,使得 java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 hibernate 可以应用在任何使用 jdbc 的场合,既可以在 java 的客户端程序使用,也 可以在 servlet/jsp 的 web 应用中使用,最具革命意义的是,hibernate 可以在应用 ejb 的 j2ee 架构中取代 cmp,完成数据持久化的重任。 hibernate 的核心接口一共有 5 个,分别为:session、sessionfactory、transaction、query 和 configuration。这 5 个核心接口在任何开发中都会用到。通过这些接口,不仅可以 对持久化对象进行存取,还能够进行事务控制。下面对这五个核心接口分别加以介绍。 2.3.1.session 接口接口 session 接口负责执行被持久化对象的 crud 操作(crud 的任务是完成与数据库的 交流,包含了很多常见的 sql 语句。)。但需要注意的是 session 对象是非线程安全的。 同时,hibernate 的 session 不同于 jsp 应用中的 httpsession。这里当使用 session 这个 术语时,其实指的是 hibernate 中的 session,而以后会将 httpsesion 对象称为用户 session。 2.3.2.sessionfactory 接口接口 sessionfactory 接口负责初始化 hibernate。它充当数据存储源的代理,并负责创建 session 对象。这里用到了工厂模式。需要注意的是 sessionfactory 并不是轻量级的, 因为一般情况下,一个项目通常只需要一个 sessionfactory 就够,当需要操作多个数 据库时,可以为每个数据库指定一个 sessionfactory。 2.3.3.configuration 接口接口 configuration 接口负责配置并启动 hibernate,创建 sessionfactory 对象。在 hibernate 的启动的过程中,configuration 类的实例首先定位映射文档位置、读取配置,然后创 保定电力职业技术学院顶岗实习技术应用(论文) - 9 - 建 sessionfactory 对象。 2.3.4.transaction 接口接口 transaction 接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的 底层事务处理代码。 2.3.5.query 和和 criteria 接口接口 query 和 criteria 接口负责执行各种数据库查询。它可以使用 hql 语言或 sql 语句 两种表达方式。 3.阐述 ssh 整合框架 ssh 在 j2ee 项目中表示了 3 种框架。那么怎样将三者结合起来形成一个框架呢? 3.1集成集成 ssh 框架框架 集成 ssh 框架的系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块 层。其中使用 struts 作为系统的整体基础架构,负责 mvc 的分离,在 struts 框架的模 型部分,利用 hibernate 框架对持久层提供支持,业务层用 spring 支持。具体做法是: 用面向对象的分析方法根据需求提出一些模型,将这些模型实现为基本的 java 对象, 然后编写基本的 dao 接口,并给出 hibernate 的 dao 实现,采用 hibernate 架构实现 的 dao 类来实现 java 类与数据库之间的转换和访问,最后由 spring 完成业务逻辑。 系统的基本业务流程是: 在表示层中,首先通过 jsp 页面实现交互界面,负责传 送请求(request)和接收响应(response),然后 struts 根据配置文件(struts-config.xml) 将 actionservlet 接收到的 request 委派给相应的 action 处理。在业务层中,管理服务 组件的 spring ioc 容器负责向 action 提供业务模型(model)组件和该组件的协作对象 数据处理(dao)组件完成业务逻辑,并提供事务处理、缓冲池等容器组件以提升系统 保定电力职业技术学院顶岗实习技术应用(论文) - 10 - 性能和保证数据的完整性。而在持久层中,则依赖于 hibernate 的对象化映射和数据 库交互,处理 dao 组件请求的数据,并返回处理结果。 采用上述开发模型,不仅实现了视图、控制器与模型的彻底分离,而且还实现了业 务逻辑层与持久层的分离。这样无论前端如何变化,模型层只需很少的改动,并且数 据库的变化也不会对前端有所影响,大大提高了系统的可复用性。而且由于不同层之 间耦合度小,有利于团队成员并行工作,大大提高了开发效率。 4. 基于 ssh 框架的 web 应用系统的实现 下面将通过一个实际的系统来展示如何进行基于 ssh 框架的 web 应用开发。该 系统是为某通信公司运营部开发的一个问答式系统,功能类似于百度知道和新浪爱 问。由于系统的模块较多,下面就以一个用户管理模块为例来说明系统的开发实现过 程,并将按照数据持久层、业务逻辑层、表示层的顺序说明系统构建过程。 4.1 数据持久层 数据持久层由 java 对象持久化类和数据访问对象(dao)组成。每个数据库表都对 应着一个持久化对象,这样就给予了开发者使用 oo 思想设计和开发的便利,同时也 屏蔽了具体的数据库和具体的数据表、字段,消除了对数据库操作的硬编码在重用性 上的弊端。用户信息表的部分结构如表 1 所 hibernate 通过映射(mapping)文件将对象(object)与关系型数据(relational)相关联, 因此需要编写和数据库表相对应的 java 持久化类以及对应的映射文件。有了 java 持 久化类后就可以在此基础上实现数据访问类。在 spring 框架中,数据访问类可以从辅 保定电力职业技术学院顶岗实习技术应用(论文) - 11 - 助类 hibernatedaosupport 继承,这极大地方便了 hibernate 框架在 spring 中的使用, 相应的部分代码如下: public class userdao extends hibernatedaosupport public int add(user user) return integer.parseint(this.gethibernatetemplate().save(user).tostring(); public list findall() return this.gethibernatetemplate().loadall(user.class); 具体的 hibernate 数据源、session 工厂、事务管理、缓冲连接池等功能都由业务层的 spring 容器提供。 4.2 业务逻辑层 业务逻辑层由 spring 框架支持,提供了处理业务逻辑的服务组件。开发者需要对 业务对象建模,抽象出业务模型并封装在 model 组件中。由于数据持久层实现了 java 持久化类并且封装了数据访问对象(dao),因此可以在 model 组件中方便地调用 dao 组件来存取数据。spring 的 ioc 容器负责统一管理 model 组件和 dao 组件以 及 spring 所提供的事务处理、缓冲连接池等服务组件。 在用户管理模块中,通过业务建模创建了用户模型 userservice 类,封装了对用户 的权限管理以及积分管理等功能。userservice 类通过调用数据访问类 userdao 实现 对用户数据的操作。这些组件的关系将通过配置 spring 框架的 applicationcontext.xml 联系起来,配置文件的主要内容如下: com.uniwin.zwdc.base.model.region com/uniwin/model/*.class $hibernate.dialect org.hibernate.cache.ehcacheprovider true $hibernate.show_sql $hibernate.auto 保定电力职业技术学院顶岗实习技术应用(论文) - 13 - 4.3 表示层 表示层结合 jsp 和 struts 的 taglib 库处理显示功能,利用 actionservlet 将请求 (*.do)映射到相应的 action,并由 action 调用业务逻辑的服务组件,然后根据处理结 果跳转到 forword 对象指定的响应页面。 业务流程的部署由 struts-config.xml 完成。下面以一个显示所有用户信息的请求 (listuser.do)为例来说明配置文件的使用。 基于 j2ee 的 web 应用以其层次性、平台无关性的优势已经逐渐成为了电子商务、 电子政务主要的解决方案。本文针对传统的 j2ee web 应用开发的弊端,介绍了一种 利用轻量级框架来快速搭建 web 应用的解决方案,并且通过其在实际项目中的应用, 证明了采用此方案可以帮助开发人员在短时间内建立结构清晰、可重用性好、维护扩 展方便的 web 应用程序。 5 ssh 性能的优化 5.1 struts 优化优化 5.1.1 logging 和开和开发发模式模式 关闭 logging 和开发模式(devmode), devmode 是在 perties 中设置的, 关闭 logging 需要修改 web.xml 文件,加入以下参数 保定电力职业技术学院顶岗实习技术应用(论文) - 14 - debug 0 detail 0 5.1.2. 拦拦截器截器 除非需要,否则不要使用拦截器(interceptor). 如果一个 action 不需要全栈的拦截器的话,就使用 basicstack 拦截器或移除不 需要的拦截器。 5.1.3.缓缓存和存和过过期期时间时间 正确设置页面的 cache-control 和 expires 使用正确的 http 头(缓存控制和过期时间) 当返回一个 html 页面的时候,要保证 html 页面包含正确的 header,使得浏览器可 以知道怎样缓存该 html 页面。 5.1.4. ajax theme(dojo)或者或者 calendar 标签标签 struts2 提供的 ajax theme(dojo)或者 calendar 标签默认情况下保存在 struts.jar 包里 面, 把这些 js 文件或者 css 文件拷出来放到另外一个服务器上可以提高性能。 当使用 ajax theme(dojo)或日历 tag 时,从 struts2 的 jar 包复制静态内容到 http 服务器。 因为 http 服务器会对这些静态文件的请求进行优化 5.1.5. freemark 载载入模板入模板 保定电力职业技术学院顶岗实习技术应用(论文) - 15 - 如果使用 freemarker 的话,在 web-inf 下的 classes 文件夹下创建一个 perties 并且加入 template_update_delay=60000, 这个值是 freemarker 多久从硬盘重新载入模板,默认 情况下是 500ms, 因为没有必要检查是不是需要重新载入模板文件,所以最好把它设 置为一个很大的数字。 5.1.6.freemark 模板模板缓缓存存 启用 freemarker 模板缓存, 这是 struts.freemarker.templatescache 为 true, 默认情况下 这个是 false 的。 5.1.7. 模板路径模板路径 当覆盖一个 theme 时,copy 所有重要的模板到 theme 目录 当 template 在当前目录不能发现时,会有性能开销。因为在返回父模板前,struts2 必 须在当前目录进行 theme 检查. 晚先时候,这个缺陷将要通过一个 template 缓存解决。 5.1.8. session 在你需要的时候才创建 session 除非需要,struts2 不会创建 sessions(比如,在你的拦截 器 stack 中有 createsession 拦截器)。注意当使用 sitemesh 时, 一个 session 将总是被 创建(看看 /thread.jspa?messageid=5688 的描述). 5.1.9.标签标签的使用的使用 当使用 freemarker 时,尽量使用等价的 freemarker 元素,代替 jsp 的标签。 freemarker 支持 list 迭代, 显示属性,包含其他模版, macros 等等.使用等价的 freemarker 元素代替 struts2 的 tags 会有小的性能提升。 (例如: 将要被$foo代替). 1 struts.jar,xwork-core-2.3.4.jar,freemarker 升级为 2.3.19 保定电力职业技术学院顶岗实习技术应用(论文) - 16 - 2 ognl 升级为 3.0.5(+javassist-3.11.0.jar) 3 根包下增加 perties 文件,内容为 template_update_delay=60000 4 struts.xml 增加和 5 把 struts.xml 中的默认拦截器定义为 basicstack: 执行了这几步之后,网站性能从 5 req/s 提升至 70 req/s,请求处理时间从 22s/req 缩 减至 2s/req! 5.2 spring 优化优化 default-autowire=“no“ /自动装配设为否,当我们依赖注入的时候,用 set,get 方法,然后在 spring 配置文 件中手动装配 以上这是手动装配,还可以自动装配,这样就不用写属性了, 保定电力职业技术学院顶岗实习技术应用(论文) - 17 - 直接: 就可以, 自动装配有几个配置: byname : 试图在容器中寻找和需要自动装配的属性名相同的 bean 或 id,如果 没有找到相应的 bean,则这个属性未被装配上。 bytype : 试图在容器中寻找一个与需要自动装配的属性类型相同的 bean 或 id,如果没有找到,则该属性未被装配上。 constructor : 试图在容器中寻找与需要自动装配的 bean 的构造函数参数一致的 一个或多个 bean,如果没找到则抛出异常。 autodetect : 首先尝试使用 constructor 来自动装配,然后再使用 bytype 方式。 最常用的就是 default-autowire=“byname“,这样只写 就可 以,系统会自动查找和名字相关的来装配依赖注入的。 default-lazy-init=“true“ 延迟加载设为 true,这样当 spring 启动时就不会一次加载所有的 bean 了,当 getbean 的时候才会被加载 5.3 hibernate 优化优化 初用 hibernate 的人也许都遇到过性能问题,实现同一功能,用 hibernate 与用 jdbc 性能相差十几倍很正常,如果不及早调整,很可能影响整个项目的进度。 保定电力职业技术学院顶岗实习技术应用(论文) - 18 - 5.3.1、 数据库设计数据库设计 a) 降低关联的复杂性 b) 尽量不使用联合主键 c) id 的生成机制,不同的数据库所提供的机制并不完全一样 d) 适当的冗余数据,不过分追求高范式 5.3.2、 hql 优化 hql 如果抛开它同 hibernate 本身一些缓存机制的关联,hql 的优化技巧同 普通的 sql 优化技巧一样,可以很容易在网上找到一些经验之谈。 5.3.3、 主配置主配置 a) 查询缓存,同下面讲的缓存不太一样,它是针对 hql 语句的缓存,即完全一样 的语句再次执行时可以利用缓存数据。但是,查询缓存在一个交易系统(数据变更频 繁,查询条件相同的机率并不大)中可能会起反作用:它会白白耗费大量的系统资源但 却难以派上用场。 b) fetch_size,同 jdbc 的相关参数作用类似,参数并不是越大越好,而应根据业 务特征去设置 c) batch_size 同上。 d) 生产系统中,切记要关掉 sql 语句打印。 5.3.4、 缓存缓存 a) 数据库级缓存:这级缓存是最高效和安全的,但不同的数据库可管理的层次并 不一样,比如,在 oracle 中,可以在建表时指定将整个表置于缓存当中。 b) session 缓存:在一个 hibernate session 有效,这级缓存的可干预性不强, 保定电力职业技术学院顶岗实习技术应用(论文) - 19 - 大多于 hibernate 自动管理,但它提供清除缓存的方法,这在大批量增加/更新操 作是有效的。比如,同时增加十万条记录,按常规方式进行,很可能会发现 outofmemeroy 的异常,这时可能需要手动清除这一级缓存:session.evict 以及 session.clear c) 应用缓存:在一个 sessionfactory 中有效,因此也是优化的重中之重,因 此,各类策略也考虑的较多,在将数据放入这一级缓存之前,需要考虑一些前提条件: i. 数据不会被第三方修改(比如,是否有另一个应用也在修改这些数据?) ii. 数据不会太大 iii. 数据不会频繁更新(否则使用 cache 可能适得其反) iv. 数据会被频繁查询 v. 数据不是关键数据(如涉及钱,安全等方面的问题)。 缓存有几种形式,可以在映射文件中配置:read-only(只读,适用于很少变更的静态 数据/历史数据),nonstrict-read- write,read-write(比较普遍的形式,效率一般), transactional(jta 中,且支持的缓存产品较少) d) 分布式缓存:同 c)的配置一样,只是缓存产品的选用不同,在目前的 hibernate 中可供选择的不多,oscache, jboss cache,目前的大多数项目,对它们的 用于集群的使用(特别是关键交易系统)都持保守态度。在集群环境中,只利用数据库 级的缓存是最安全的。 5.3.5、 延迟加载延迟加载 a) 实体延迟加载:通过使用动态代理实现 b) 集合延迟加载:通过实现自有的 set/list,hibernate 提供了这方面的支持 c) 属性延迟加载: 保定电力职业技术学院顶岗实习技术应用(论文) - 20 - 5.3.6、 方法选用方法选用 a) 完成同样一件事,hibernate 提供了可供选择的一些方式,但具体使用什么 方式,可能用性能/代码都会有影响。显示,一次返回十万条记录 (list/set/bag/map 等)进 行处理,很可能导致内存不够的问题,而如果用基于游标(scrollableresults)或 iterator 的结果集,则不存在这样的问题。 b) session 的 load/get 方法,前者会使用二级缓存,而后者则不使用。 c) query 和 list/iterator,如果去仔细研究一下它们,你可能会发现很多有意思的情 况,二者主要区别(如果使用了 spring,在 hibernatetemplate 中对应 find,iterator 方法): i. list 只能利用查询缓存(但在交易系统中查询缓存作用不大),无法利用二级缓存 中的单个实体,但 list 查出的对象会写入二级缓存,但它一般只生成较少的执行 sql 语句,很多情况就是一条(无关联)。 ii. iterator 则可以利用二级缓存,对于一条查询语句,它会先从数据库中找出所 有符合条件的记录的 id,再通过 id 去缓存找,对于缓存中没有的记录,再构造语句 从数据库中查出,因此很容易知道,如果缓存中没有任何符合条件的记录,使用 iterator 会产生 n+1 条 sql 语句(n 为符合条件的记录数) iii. 通过 iterator,配合缓存管理 api,在海量数据查询中可以很好的解决内存问 题,如: while(it.hasnext() youobject object = (youobject)it.next(); session.evict(youobject); sessionfactory.evice(youobject.class, youobject.getid(); 如果用 list 方法,很可能就出 outofmemory 错误了。 iv. 通过上面的说明,我想你应该知道如何去使用这两个方法了。 保定电力职业技术学院顶岗实习技术应用(论文) - 21 - 5.3.7、 集合的选用集合的选用 在 hibernate 3.1 文档的“19.5. understanding collection performance”中有 详细的说明。 5.3.8、 事务控制事务控制 事务方面对性能有影响的主要包括:事务方式的选用,事务隔离级别以及锁的 选用 a) 事务方式选用:如果不涉及多个事务管理器事务的话,不需要使用 jta,只有 jdbc 的事务控制就可以。 b) 事务隔离级别:参见标准的 sql 事务隔离级别 c) 锁的选用:悲观锁(一般由具体的事务管理器实现),对于长事务效率低,但安全。 乐观锁(一般在应用级别实现),如在 hibernate 中可以定义 version 字段,显然, 如果有多个应用操作数据,且这些应用不是用同一种乐观锁机制,则乐观锁会失效。 因此,针对不同的数据应有不同的策略,同前面许多情况一样,很多时候我们是在效 率与安全/准确性上找一个平衡点,无论如何,优化都不是一个纯技术的问题,你应该 对你的应用和业务特征有足够的了解。 5.3.9、 批量操作批量操作 即使是使用 jdbc,在进行大批数据更新时,batch 与不使用 batch 有效率上 也有很大的差别。我们可以通过设置 batch_size 来让其支持批量操作。 举个例子,要批量删除某表中的对象,如“delete account”,打出来的语句,会发现 hibernate 找出了所有 account 的 id,再进行删除,这主要是为了维护二级缓 存,这样效率肯定高不了,在后续的版本中增加了 bulk delete/update,但这也无法解决 保定电力职业技术学院顶岗实习技术应用(论文) - 22 - 缓存的维护问题。也就是说,由于有了二级缓存的维护问题,hibernate 的批量操 作效率并不尽如人意! 从前面许多要点可以看出,很多时候我们是在效率与安全/准确性上找一个平衡 点,无论如何,优化都不是一个纯技术的问题,你应该对你的应用和业务特征有足够 的了解,一般的,优化方案应在架构设计期就基本确定,否则可能导致没必要的返工, 致使项目延期,而作为架构师和项目经理,还要面对开发人员可能的抱怨,必竟,我 们对用户需求更改的控制力不大,但技术/架构风险是应该在初期意识到并制定好相 关的对策。 还有一点要注意,应用层的缓存只是锦上添花,永远不要把它当救命稻草,应用 的根基(数据库设计,算法,高效的操作语句,恰当 api 的选择等)才是最重要的。 5.3.10、hibernate 的缓存的缓存 1、首先设置、首先设置 ehcache,建立配置文件,建立配置文件 ehcache.xml,默认的位置在,默认的位置在 class-path,可以放到你的,可以放到你的 src 目录下:目录下: ?xml version=“1.0“ encoding=“utf-8“? ehcache diskstore path=“java.io.tmpdir“/ defaultcache maxelementsinmemory=“10000“ !- 缓存最大数目 - eternal=“false“ !- 缓存是否持久 - overflowtodisk=“true“ !- 是否保存到磁盘,当系统当机时- timetoidleseconds=“300“ !- 当缓存闲置 n 秒后销毁 - timetoliveseconds=“180“ !- 当缓存存活 n 秒后销毁- diskpersistent=“false“ 保定电力职业技术学院顶岗实习技术应用(论文) - 23 - diskexpirythreadintervalseconds= “120“/ /ehcache 2、在、在 hibernate 配置文件中设置:配置文件中设置: !- 设置 hibernate 的缓存接口类,这个类在 hibernate 包中 - property name=“vider_class“org.hibernate.cache.ehcacheprovider/property !- 是否使用查询缓存 - property name=“hibernate.cache.use_query_cache“true/property 如果使用 spring 调用 hibernate 的 sessionfactory 的话,这样设置: !-hibernatesession 工厂管理 - bean id=“sessionfactory“ class=“org.springframework.orm.hibernate3.localsessionfactorybean“ property name=“datasource“ ref bean=“datasource“ / /property property name=“hibernateproperties“ props prop key=“hibernate.dialect“org.hibernate.dialect.oracle9dialect/prop prop key=“vider_class“org.hibernate.connection.c3p0connectionprovider/p rop prop key=“hibernate.show_sql“true/prop prop key=“hibernate.cache.use_query_cache“true/prop prop key=“vider_class“org.hibernate.cache.ehcacheprovider/prop /props /property property name=“mappingdirectorylocations“ list value/web-inf/classes/cn/rmic/manager/hibernate/value /list /property /bean 说明一下:如果不设置“查询缓存”,那么 hibernate 只会缓存使用 load()方法获得的 单个持久化对象,如果想缓存使用 findall ()、list()、iterator()、createcriteria()、 createquery()等方法获得的数据结果集的话,就需要设置 保定电力职业技术学院顶岗实习技术应用(论文) - 24 - hibernate.cache.use_query_cache true 才行 3、在、在 hbm 文件中添加文件中添加cache usage=“read-only“/ 4、如果需要、如果需要“查询缓存查询缓存”,还需要在使用,还需要在使用 query 或或 criteria()时设置其时设置其 setcacheable(true);属性属性 5.3.11hibernate 性能调优性能调优 一。一。 inverse = ? inverse=false(default) 用于单向 one-to-many 关联 parent.getchildren().add(child) / insert child parent.getchildren().delete(child) / delete child inverse=true 用于双向 one-to-many 关联 child.setparent(parent); session.save(child) / insert child session.delete(child) 在分层结构的体系中 parentdao, childdao 对于 crud 的封装导致往往直接通过 session 接口持 久化对象,而很少通过关联对象可达性 二。二。 one-to-many 关系关系 单向关系还是双向关系? parent.getchildren().add(child)对集合的触及操作会导致 lazy 的集合初始 化,在没有对集合配置二级缓存的情况下,应避免此类操作 select * from child where parent_id = xxx; 性能口诀: 1. 一般情况下避免使用单向关联,尽量使用双向关联 2. 使用双向关联,inverse=“true” 3. 在分层结构中通过 dao 接口用 session 直接持久化对象,避免通过 保定电力职业技术学院顶岗实习技术应用(论文) - 25 - 关联关系进行可达性持久化 三。三。many-to-one 关系关系 单向 many-to-one 表达了外键存储方 灵活运用 many-to-one 可以避免一些不必要的性能问题 many-to-one 表达的含义是:0n : 1,many 可以是 0,可以是 1,也可以是 n, 也就是说 many-to-one 可以表达一对多,一对一,多对一关系 因此可以配置双向 many-to-one 关系,例如: 1. 一桌四人打麻将,麻将席位和打麻将的人是什么关系?是双向 many-to-one 的关系 四。四。one-to-one 通过主键进行关联 相当于把大表拆分为多个小表 例如把大字段单独拆分出来,以提高数据库操作的性能 hibernate 的 one-to-one 似乎无法 lazy,必须通过 bytecode enhancement 五。集合五。集合 list/bag/set one-to-many 1. list 需要维护 index column,不能被用于双向关联,必须 inverse=“false”,被谨慎的使用在某些稀有的场合 2. bag/set 语义上没有区别 3. 我个人比较喜欢使用 bag many-to-many 1. bag 和 set 语义有区别 2。 建议使用 set 六。集合的过滤六。集合的过滤 保定电力职业技术学院顶岗实习技术应用(论文) - 26 - 1. children = session.createfilter(parent.getchildren(), “where this.age 5 and this.age 10”).list() 针对一对多关联当中的集合元素非常庞大的情况,特别适合于庞大集合的分页: session.createfilter(parent.getchildren(),“”).setfirstresult(0).setmaxresults(10).list(); 在 hibernate 中用 super.getsession().createfilter( , ) 七。继承关系当中的隐式多态七。继承关系当中的隐式多态 hql: from object 1. 把所有数据库表全部查询出来 2. polymorphism=“implicit”(default)将当前对象,和对象所有继承子类全部 一次性取出 3. polymorphism=“explicit”,只取出当前查询对象 八。八。hibernate 二级缓存二级缓存 著名的 n+1 问题:from child,然后在页面上面显示每个子类的父类信息, 就会导致 n 条对 parent 表的查询: select * from parent where id = ? . select * from parent where id = ? 解决方案 1. eager fetch 2. 二级缓存 九。九。inverse 和二级缓存的关系和二级缓存的关系 当使用集合缓存的情况下: 1. inverse=“false”,通过 parent.getchildren()来操作,hibernate 维护集合缓 存 2. inverse=“true”,直接对 child 进行操作,未能维护集合缓存!导致缓存 脏数据 3. 双向关联,inverse=“tr

温馨提示

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

最新文档

评论

0/150

提交评论