购买

¥30.0

加入VIP
  • 专属下载券
  • 上传内容扩展
  • 资料优先审核
  • 免费资料无限下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 尚学堂-王勇-Struts.Hibernate.Spring

尚学堂-王勇-Struts.Hibernate.Spring.ppt

尚学堂-王勇-Struts.Hibernate.Spring

烟雨梦兮
2018-10-14 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《尚学堂-王勇-Struts.Hibernate.Springppt》,可适用于IT/计算机领域

尚学堂手把手教程授课:王勇版权所有:尚学堂科技StrutsHibernateSpringStrutsHibernateSpringWeb开发流行架构手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂课程总体目标我们的目标是:能够熟练运用当前流行的java开源框架:Struts、Hibernate以及Spring来构建灵活、易于扩展的多层Web应用程序。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂多层架构概述CS:以数据库为中心BS:多层架构才是真正的目的BS多层架构将显示、业务运算、数据库等功能完全分离杜绝彼此的耦合与影响从而实现松耦合和良好的可维护性。呈现层(UILayerPresentationLayer)struts业务逻辑层(BusinessLayer)spring持久化层(PersistenceLayer)hibernate尚学堂手把手教程授课:王勇版权所有:尚学堂科技StrutsHibernateSpringStruts开源MVC框架手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Struts课程目标深入理解MVC模式掌握Struts体系架构掌握Struts开发流程熟练掌握Struts的配置方法手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂从Servlet说开去什么是Servlet?如何编写Servlet?如何映射Servlet?相对路径与绝对路径的基本概念如何基于Servlet编程?JavaBeansJavaBean是一种java类JavaBean必须是具体的和公共的并且具备无参构造器JavaBean通过提供符合一致性设计模式的公共方法将内部域暴露称为属性JavaBean提供两种方法来访问Bean的内部状态:访问器(getters)用来读JavaBean状态–以小写get前缀开始后跟属性名属性名的第一个字母必须大写返回值必须匹配相应修改器的方法的参数如果访问器返回boolean值则使用is前缀开始后跟属性名属性名第一个字母必须大写。修改器(setters)用来改变JavaBean状态–以小写set前缀开始后跟属性名属性名的第一个字母必须大写修改器的返回值通常为void手把手教程版权所有:尚学堂科技StrutsHibernateS手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂多对多关联映射(manytomany)一般的设计中多对多关联映射需要一个中间表Hibernate会自动生成中间表Hibernate使用manytomany标签来表示多对多的关联多对多的关联映射在实体类中跟一对多一样也是用集合来表示的手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂manytomany<manytomanycolumn="columnname"()class="ClassName"()>()column(必需):中间映射表中关联目标表的关联字段()class(必需):类名关联目标类<keycolumn="columnname">()()column(必需):当前表的关联字段手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂例子(manytomany):studenttrainClass<classname="comtesthibernateStudent"><idname="id"column="userId"><generatorclass="native"><id><setname="trainClasses"lazy="true"cascade="saveupdate"><keycolumn="studentId"><manytomanyclass="comtesthibernateTrainClass"column="trainClassId"><set><class><classname="comtesthibernateTrainClass"table="TBLTRAINCLASS"><idname="id"column="trainClassId"><generatorclass="native"><id><class>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂继承继承实现的三种策略单表继承。每棵类继承树使用一个表(tableperclasshierarchy)具体表继承。每个子类一个表(tablepersubclass)类表继承。每个具体类一个表(tableperconcreteclass)(有一些限制)手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂每个类继承树对应一张表因为类继承树肯定是对应多个类要把多个类的信息存放在一张表中必须有某种机制来区分哪些记录是属于哪个类的。这种机制就是在表中添加一个字段用这个字段的值来进行区分。用hibernate实现这种策略的时候有如下步骤:父类用普通的<class>标签定义在父类中定义一个discriminator即指定这个区分的字段的名称和类型如:<discriminatorcolumn=”XXX”type=”string”>子类使用<subclass>标签定义在定义subclass的时候需要注意如下几点:Subclass标签的name属性是子类的全路径名在Subclass标签中用discriminatorvalue属性来标明本子类的discriminator字段(用来区分不同类的字段)的值Subclass标签既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系)也可以与class标签平行。当subclass标签的定义与class标签平行的时候需要在subclass标签中添加extends属性里面的值是父类的全路径名称。子类的其它属性像普通类一样定义在subclass标签的内部。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂每个子类一张表(除非将父类定义成抽象的否则父类也是一张表)这种策略是使用joinedsubclass标签来定义子类的。父类、子类每个类都对应一张数据库表。在父类对应的数据库表中实际上会存储所有的记录包括父类和子类的记录在子类对应的数据库表中这个表只定义了子类中所特有的属性映射的字段。子类与父类通过相同的主键值来关联。实现这种策略的时候有如下步骤:父类用普通的<class>标签定义即可父类不再需要定义discriminator字段子类用<joinedsubclass>标签定义在定义joinedsubclass的时候需要注意如下几点:Joinedsubclass标签的name属性是子类的全路径名Joinedsubclass标签需要包含一个key标签这个标签指定了子类和父类之间是通过哪个字段来关联的。如:<keycolumn=”PARENTKEYID”>这里的column实际上就是父类的主键对应的映射字段名称。Joinedsubclass标签既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系)也可以与class标签平行。当Joinedsubclass标签的定义与class标签平行的时候需要在Joinedsubclass标签中添加extends属性里面的值是父类的全路径名称。子类的其它属性像普通类一样定义在joinedsubclass标签的内部。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂每个具体子类一张表这种策略是使用unionsubclass标签来定义子类的。每个子类对应一张表而且这个表的信息是完备的即包含了所有从父类继承下来的属性映射的字段(这就是它跟joinedsubclass的不同之处joinedsubclass定义的子类的表只包含子类特有属性映射的字段)。实现这种策略的时候有如下步骤:父类用普通<class>标签定义即可子类用<unionsubclass>标签定义在定义unionsubclass的时候需要注意如下几点:Unionsubclass标签不再需要包含key标签(与joinedsubclass不同)Unionsubclass标签既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系)也可以与class标签平行。当Unionsubclass标签的定义与class标签平行的时候需要在Unionsubclass标签中添加extends属性里面的值是父类的全路径名称。子类的其它属性像普通类一样定义在Unionsubclass标签的内部。这个时候虽然在unionsubclass里面定义的只有子类的属性但是因为它继承了父类所以不需要定义其它的属性在映射到数据库表的时候依然包含了父类的所有属性的映射字段。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂双向关联概念:双向关联允许通过关联的任一端访问另外一端。在Hibernate中,支持两种类型的双向关联。一对多(onetomany)Set或者bag值在一端,单独值(非集合)在另外一端。多对多(manytomany)两端都是set或bag值。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂例子(双向关联):groupuser<classname="comtesthibernateGroup"table="TBLGROUP"><idname="id"column="groupId"><generatorclass="native“><id><setname="users"lazy="true"cascade="saveupdate"inverse="true"><keycolumn="groupId"><onetomanyclass="comtesthibernateUser"><set><class><classname="comtesthibernateUser"table="TBLUSER"><idname="id"column="userId"><generatorclass="native"><id><manytoonename="group"column="groupId"outerjoin="false"><class>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂例子:从Java代码看groupuser双向关联的inverse概念:inverse用来标识双向关联的关联关系由哪一端维护。默认inverse的值为false由主动方负责维护关联关系如果设为true则由反向一端维护关联关系。用例:我们假设已经有一个Group类的实例:adminGroup现在我们要新增一个用户并且将用户分配到adminGroup中。inverse=“false”由主动方Group负责维护groupuser的关联关系Useruser=newUser(“Jak”)adminGroupgetUsersadd(user)sessionsave(user)sessionupdate(group)inverse=“true”由Group的反向段User负责维护关联关系。Useruser=newUser(“Jak”)usersetGroup(adminGroup)sessionsave(user)手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Hibernate查询概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现而言Hibernate提供了灵活多样的查询机制。标准化对象查询(CriteriaQuery):以对象的方式进行查询将查询语句封装为对象操作。优点:可读性好符合Java程序员的编码习惯。缺点:不够成熟不支持投影(projection)或统计函数(aggregation)Hibernate语言查询(HibernateQueryLanguageHQL):它是完全面向对象的查询语句查询功能非常强大具备多态、关联等特性。Hibernate官方推荐使用HQL进行查询。NativeSQLQueries(原生SQL查询):直接使用标准SQL语言或跟特定数据库相关的SQL进行查询。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂例子:标准化对象查询(CriteriaQuery)简单例子:查询用户名以“J”开头的所有用户。Criteriacriteria=sessioncreateCriteria(Userclass)criteriaadd(Expressionlike("name","J"))Listusers=criterialist()手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Hibernate语言查询(HibernateQueryLanguageHQL)HQL用面向对象的方式生成SQL以类和属性来代替表和数据列支持多态支持各种关联减少了SQL的冗余HQL支持所有的关系数据库操作连接(joins,包括Innerouterfulljoins)笛卡尔积(cartesianproducts)投影(projection)聚合(Aggregationmax,avg)和分组(group)排序(Ordering)子查询(Subqueries)SQL函数(SQLfunctioncalls)手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂例子:Hibernate语言查询(HibernateQueryLanguageHQL)简单例子:查询用户名以“J”开头的所有用户。Queryquery=sessioncreateQuery("fromUseruserwhereusernamelike'J'")Listusers=querylist()复杂例子:从User和Group中查找属于“admin”组的所有用户。Queryquery=sessioncreateQuery(“fromUseruserwhereusergroupname=‘admin’”)如果用传统的SQL则查询语句如下:selectuseruserIdasuserId,usernameasname,usergroupIdasgroupId,useridCardIdasidCardIdfromTBLUSERuser,TBLGROUPgroupwhere(groupgroupName='admin'andusergroupId=groupgroupId)手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Hibernate性能优化策略Hibernate高级话题:性能优化策略的配置与使用本节包括如下主题:一级缓存二级缓存查询缓存批量抓取批量更新手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂一级缓存即session级别的缓存随着session的关闭而消失loaditerator操作会从一级缓存中查找数据如果找不到再到数据库里面查找。Querylist操作如果没有配置查询缓存将直接从数据库中获取数据。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂二级缓存()首先要打开二级缓存默认情况下二级缓存是打开的可以通过配置:<propertyname="hibernatecacheusesecondlevelcache">false<property>来关闭二级缓存。使用:<propertyname="hibernatecacheproviderclass">orghibernatecacheEhCacheProvider<property>来指定缓存提供商。即有谁来提供缓存的功能。Ehcache配置可以看例子里面有非常清楚的说明。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂二级缓存()要在映射文件中指定缓存策略在hbm文件中加入:<cacheusage="readonly">这个缓存策略的配置一定要加上否则便不会有缓存的作用Loadlistiterator等操作的结果将都不会缓存。注意在hbm的class配置中添加<cache>配置表示的是类缓存如果把这个配置删除将只缓存ID不缓存整个对象。(这个时候对list操作也可能有n查询问题)当然也可以选择在<sessionFactory>标签里面嵌套定义这样的标签:<classcacheclass="combjsxthibernateUser"usage="readonly">来代替直接将<cache>定义嵌套入<class>标签的内部。缓存策略缓存有几种形式可以在映射文件中配置:readonly(只读适用于很少变更的静态数据历史数据)nonstrictreadwrite(不严格读写缓存如果基本不会发生有两个事务同时修改一个数据的时候比readwrite的性能要好)readwrite(比较普遍的形式效率一般)transactional(JTA中且支持的缓存产品较少)手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂二级缓存()Session如何与二级缓存交互?Session接口通过CacheMode来定制与二级缓存之间的交互方法手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂查询缓存默认情况下关闭需要打开。查询缓存对listiterator这样的操作会起作用。。。。可以使用:<propertyname="hibernatecacheusequerycache">true<property>来打开查询缓存默认的情况下是关闭的。所谓查询缓存即让hibernate缓存list、iterator、createQuery等方法的查询结果集。如果没有打开查询缓存hibernate将只缓存load方法获得的单个持久化对象。在打开了查询缓存之后需要注意调用querylist()操作之前必须显式调用querysetCachable(true)来标识某个查询使用缓存。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂单端代理的批量抓取实例A引用实例BB如果是代理的话(比如多对一关联中):如果遍历A的查询结果集(假设有条记录)在遍历A的时候访问B变量将会导致n次查询语句的发出!这个时候如果在B一端的class上配置batchsizeHibernate将会减少SQL语句的数量。Hibernate可以充分有效的使用批量抓取也就是说如果仅一个访问代理(或集合)那么Hibernate将不载入其他未实例化的代理。批量抓取是延迟查询抓取的优化方案你可以在两种批量抓取方案之间进行选择:在类级别和集合级别。类实体级别的批量抓取很容易理解。假设你在运行时将需要面对下面的问题:你在一个Session中载入了个Cat实例每个Cat实例都拥有一个引用成员owner其指向Person而Person类是代理同时lazy="true"。如果你必须遍历整个cats集合对每个元素调用getOwner()方法Hibernate将会默认的执行次SELECT查询得到其owner的代理对象。这时你可以通过在映射文件的Person属性显式声明batchsize改变其行为:<classname="Person"batchsize=""><class>随之Hibernate将只需要执行三次查询分别为、、。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂集合代理的批量抓取你也可以在集合级别定义批量抓取。例如如果每个Person都拥有一个延迟载入的Cats集合现在Sesssion中载入了个person对象遍历person集合将会引起次SELECT查询每次查询都会调用getCats()方法。如果你在Person的映射定义部分允许对cats批量抓取,那么Hibernate将可以预先抓取整个集合。请看例子:<classname="Person"><setname="cats"batchsize=""><set><class>如果整个的batchsize是那么Hibernate将会分四次执行SELECT查询按照、、、的大小分别载入数据。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂批量更新Jdbcfetchsize:每次取多少条数据需要JDBC和底层数据库的支持。不会一次性把全部数据读入内存而是按照一定的数量来批量读取相应的数据。Fetchsize建议值是hibernatejdbcfetchsizeJdbcbatchsize批量更新建议取值hibernatejdbcbatchsize手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Hibernate最佳实践(BestPractices)、使用Configuration装载映射文件时不要使用绝对路径装载。最好的方式是通过getResourceAsStream()装载映射文件这样Hibernate会从classpath中寻找已配置的映射文件。、SessionFactory的创建非常消耗资源整个应用一般只要一个SessionFactory就够了只有多个数据库的时候才会使用多个SessionFactory。、在整个应用中Session和事务应该能够统一管理。(Spring为Hibernate提供了非常好的支持)、将所有的集合属性配置设置为懒加载(lazy=”true”)。在hibernatex版本中lazy默认值是“false”,但hibernatex已经将lazy的默认改为“true”了。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Hibernate最佳实践(BestPractices)、在定义关联关系时集合首选Set如果集合中的实体存在重复则选择List(在定义配置文件时可以将List定义为bag)数组的性能最差。、在一对多的双向关联中一般将集合的inverse属性设置为true让集合的对方维护关联关系。例如:GroupUser由User来维护Group和User的关联关系。、HQL子句本身大小写无关但是其中出现的类名和属性名必须注意大小写区分。、在非分布式架构中不需要使用DTO来向上层传输数据。直接使用POJO的Entity就可以了。、如果要精通Hibernate熟练掌握关系数据库理论和SQL是前提条件。手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Hibernate资源官方网站:http:wwwhibernateorg国内网站:http:wwwhibernateorgcnJava新视线论坛:http:forumhibernateorg《Hibernate中文开发指南》作者夏昕(http:wwwredsagacom)《深入浅出Hibernate》作者:夏昕曹晓钢唐勇(http:wwwchinapubcomcomputerscommoninfoaspid=)《HibernateinAction》作者:ChristianBauerandGavinKing(http:wwwjavafannet可下载)《Hibernate:ADeveloper'sNotebook》作者:JamesElliott尚学堂手把手教程授课:王勇版权所有:尚学堂科技StrutsHibernateSpringSpring轻量级容器架构手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring最常用的特性利用Spring来创建对象(JavaBean工厂)利用Spring构建业务逻辑层管理依赖关系适应需求变更利用Spring创建数据访问对象(DAO)利用Spring进行事务处理手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring的安装下载并解压http:wwwspringframeworkorg将相应的jar包加入类路径springjar配置SpringApplicationContextxml体验Spring的最基本特性-BeanFactory手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂创建Sample类及其Spring配置文件SamplejavapublicclassSample{publicintcompute(inti,intj){returnij}}ApplicationContextxml<xmlversion=""encoding=""><!DOCTYPEbeansPUBLIC"SPRINGDTDBEANEN""http:wwwspringframeworkorgdtdspringbeansdtd"><beans><beanid=“sample”class=“combjsxtspringSample”><beans>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂创建测试程序ClientTestjavapublicclassClientTest{***paramargs*publicstaticvoidmain(Stringargs){获取BeanFactoryBeanFactorybeanFactory=newClassPathXmlApplicationContext("applicationContextxml")从容器中获取Sample对象Samplesample=(Sample)beanFactorygetBean("sample")调用Sample对象的方法intresult=samplecompute(,)Systemoutprintln(result)}}手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂针对接口编程的原则重要的设计原则:针对接口编程而不要针对实现编程思考:compute方法功能需求变更?针对接口编程的目的:降低耦合度增强应用程序的稳定性让Sample类变成接口手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Sample接口及其实现接口定义publicinterfaceSample{publicintcompute(inti,intj)}接口的实现一publicclassSampleImplimplementsSample{publicintcompute(inti,intj){returnij}}接口的实现二publicclassSampleImplimplementsSample{publicintcompute(inti,intj){returni*j}}ClientTestjava无需改动只需改动ApplicationContextxml的配置即可实现实际功能的切换手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂第二个例子我们已经确定基于接口编程是OOD中的重要原则一个层次的实现代码不应该依赖于另外一个层次的实现代码下面是第二个例子:BookLister这个例子包括如下几个类:实体类:Book有名称、作者等属性BookFinder接口定义了findAll()方法BookLister接口定义了findBooks(Stringname)方法以书名作为参数并返回Book数组作为查找的结果以及一个测试客户端BookClient调用BookLister来获取所需要的数据手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂BookjavapublicclassBook{privateStringnameprivateStringauthor***returnReturnstheauthor*publicStringgetAuthor(){returnauthor}***paramauthorTheauthortoset*publicvoidsetAuthor(Stringauthor){thisauthor=author}othergetterssetters…}手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂BookFinderBookFinder接口publicinterfaceBookFinder{publicListfindAll()}SimpleBookFinderImplpublicclassSimpleBookFinderImplimplementsBookFinder{***seecombjsxtspringBookFinder#findAll()*publicListfindAll(){Listbooks=newArrayList()for(inti=i<i){Bookbook=newBook()booksetName("book"i)booksetAuthor("author"i)booksadd(book)}returnbooks}}手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂BookListerBookList接口publicinterfaceBookLister{publicBookfindBooks(Stringname)}BookListerImpl实现代码publicclassBookListerImplimplementsBookLister{BookFinderfinderpublicBookListerImpl(){finder=newSimpleBookFinderImpl()}publicBookfindBooks(Stringname){Listbooks=finderfindAll()for(Iteratoriter=booksiterator()iterhasNext()){Bookbook=(Book)iternext()if(!bookgetName()equals(name)){iterremove()}}return(Book)bookstoArray(newBookbookssize())}手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring配置:ApplicationContextxml及客户调用代码Spring配置:<beanid="bookLister"class="combjsxtspringBookListerImpl“>客户调用代码publicstaticvoidmain(Stringargs){BeanFactorybeanFactory=newClassPathXmlApplicationContext("applicationContextxml")BookListerbl=(BookLister)beanFactorygetBean("bookLister")Bookbooks=blfindBooks("book")if(books!=){for(inti=i<bookslengthi){Systemoutprintln("书《"booksigetName()"》的作者是:"booksigetAuthor())}}}手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂同样的问题:需求变更?现在我们需要的不再是一个简单的BookFinder我们需要的是一个能从本地文件系统中读取文件并分析其中所包含的Book的内容将其结果返回因为我们遵守了面向接口编程所以我们只需要提供第二个实现即可手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂FileBookFinderImpl–从文件系统读取Book的信息publicclassFileBookFinderImplimplementsBookFinder{publicListfindAll(){Stringfile=“d:testtxt”Listbooks=newArrayList()try{BufferedReaderin=newBufferedReader(newFileReader(file))Stringline=while((line=inreadLine())!=){Stringsp=linesplit("")if(splength==){…Bookbook=newBook()booksetName(sp)booksetAuthor(sp)booksadd(book)}}}catch(FileNotFoundExceptione){eprintStackTrace()}catch(IOExceptione){eprintStackTrace()}returnbooks}}手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂现在需要做什么?我们的客户代码调用BookListerBookLister如何调用BookFinder下面是以前初始化BookFinder的代码:publicBookListerImpl(){finder=newSimpleBookFinderImpl()}现在我们必须改动这段代码:publicBookListerImpl(){finder=newFileBookFinderImpl()}看出问题来了吗?手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂严重违反面向对象的设计原则BookLister接口的实现类严重依赖于BookFinder接口的实现类这就是问题所在!我们必须在BookLister的实现类和BookFinder的实现类之间进行解偶即解除它们之间的实现类耦合关系(依赖!)我们需实现以下目标:BookLister的实现类BookListerImpl不应该依赖于特定的BookFinder接口的实现类(比如SimpleBookFinderImpl或FileBookFinderImpl)BookLister的实现类应该仅仅依赖于BookFinder接口它不应该跟具体的功能需求实现相关(如是否是从文件读取Book的信息)总之我们不应该让BookLister和BookFinder的实现类之间互相耦合!手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring让一切变得轻而易举在BookListerImpl中定义一个setter方法publicvoidsetFinder(BookFinderfinder){thisfinder=finder}把BookListerImpl构造器中的new语句注释掉publicBookListerImpl(){finder=newFileBookFinderImpl()}让Spring去关心那些烦人的依赖关系吧!手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring配置文件:ApplicationContextxml添加BookFinder定义<beanid="fileBookFinder"class="combjsxtspringimplFileBookFinderImpl“>修改BookLister定义的配置<beanid="bookLister"class="combjsxtspringBookListerImpl"><propertyname="finder"ref=“fileBookFinder"><bean>以上配置即指定了BookListerImpl和FileBookFinderImpl之间的依赖关系这种依赖关系被放到了配置文件中这样只要需求有变更只需要修改这种依赖关系即可java代码本身不用任何变更手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂热门词汇:IOCDI控制反转(InversionofControlIoC)与依赖注入(DependencyInjection)由容器来管理对象之间的依赖关系(而不是对象本身来管理)就叫“控制反转”或“依赖注入”以上代码已清楚阐述IOCDI出现的原因以及IOC的基本原理Spring框架的基本思想就是IOCDISpring就是一个IOC容器IOC与DI说的是一回事但DI这个名词更能表达这种设计模式的思想手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂依赖注入的类型构造器注入通过类的构造方法注入依赖关系设值方法注入通过类的setter方法注入依赖关系第三种:接口注入(不常用)定义一个注入接口在需要注入的类中实现此接口由于这种方法具有侵入性所以不常用手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring的依赖注入Spring是一个JavaBean容器它维护着一系列JavaBean的示例通过Spring所提供的依赖注入的方法我们可以管理这些JavaBean之间的引用关系手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂更多的例子我们可以通过构造器来将实现依赖进行注入示例我们可以通过setter方法实现类的配置将易于变动的部分转移到配置文件中示例:给FileBookListerImpl加上path和name的配置手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂通过setter方法注入依赖(属性)类代码示例Spring配置示例手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring架构手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂DAO设计模式什么是DAO?DataAccessObject(数据访问对象)最重要的核心JEE模式之一为什么需要DAO?屏蔽业务逻辑对数据持久化的依赖一定需要DAO吗?如果业务逻辑比较简单(比如只有简单的数据存取操作)完全可以取消DAO是否需要DAO完全取决于业务需求没有固定的说法手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring与Hibernate的集成从例子入手安装Hibernate创建User实体类创建User映射文件创建Hibernate配置文件创建DAO对象创建Manager对象SessionFactory配置声明式事务配置DAO定义Manager定义手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂创建可以支持Hibernate的DAO对象HibernateDaoSupport这是Spring提供的集成Hibernate的基类所有的DAO均需要继承它从这个类中可以获取Hibernate的各种核心接口如Session、SessionFactory等HibernateTemplateHibernateTemplate是Spring封装的Hibernate操作接口类似于Session接口可以调用HibernateDaoSupport提供的getHibernateTemplate()方法获取HibernateTemplate对象手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂创建Manager对象Manager对象没有任何特殊之处它就是普通的接口和实现类手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂在Spring中声明SessionFactory一种简单的配置方式即指定Hibernate配置文件的路径所在即可<beanid="sessionFactory"class="orgspringframeworkormhibernateLocalSessionFactoryBean"><propertyname="configLocation"><value>classpath:hibernatecfgxml<value><property><bean>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂在Spring中配置事务管理大多数的应用程序事务管理被分配到业务逻辑方法上即每个业务逻辑方法是一个事务在Spring中所有的业务逻辑对象均是普通的POJOSpring最强大的功能在于它可以在普通的POJO上面实现声明式的事务管理(它使用AOP来完成这样的任务)可插入的事务策略步骤如下:定义一个事务管理器定义一个事务代理基类手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂事务管理器的定义<beanid="transactionManager"class="orgspringframeworkormhibernateHibernateTransactionManager"><propertyname="sessionFactory"><reflocal="sessionFactory"><property><bean>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂事务管理的AOP配置<tx:adviceid="txAdvice"transactionmanager="transactionManager"><tx:attributes><tx:methodname="add*"propagation="REQUIRED"><tx:methodname="*"readonly="true"><tx:attributes><tx:advice><!AOP配置><aop:config><aop:pointcutid="managersMethod"expression="execution(*combjsxtspringmanager**())"><aop:advisoradviceref="txAdvice"pointcutref="managersMethod"><aop:config>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂正确的配置DAODao的配置示例<beanid="baseDao"class="combjsxtdaoBaseDaoImpl"><propertyname="sessionFactory"ref="sessionFactory"><property><bean>必须注入sessionFactory的定义手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂简单配置Manager<beanid="userManager"class="combjsxtspringmanagerUserManagerImpl"><propertyname=“baseDao”ref=“baseDao”><bean>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂好了让我们来测试一下编写测试代码测试事务特性手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂Spring与Struts的集成修改webxml让Tomcat自动加载Spring,所以需要增加下面的配置<contextparam><paramname>contextConfigLocation<paramname><paramvalue>WEBINFapplicationContext*xml,classpath*:applicationContext*xml<paramvalue><contextparam><listener><listenerclass>orgspringframeworkwebcontextContextLoaderListener<listenerclass><listener>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂修改Struts的Action类我们在原来的Action配置中type属性直接指向我们的Action类(即Action类的全路径)现在我们需要将这些Action类的创建交给Spring去完成所以我们需要修改两个地方:Action配置中type属性由原来的Action类改为:orgspringframeworkwebstrutsDelegatingActionProxy在Spring配置文件中添加对Action类的定义如:<beanname="trade"class="combjsxtccswebactionTradeAction"singleton="false"><propertyname="tradeManager"ref="tradeManager"><property><propertyname="userManager"ref="userManager"><property><bean>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂建立测试JEE项目建立一个web项目在web项目中安装Struts安装Spring配置webxml配置Action配置Spring手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂StrutsHibernateSpringHibernate与Spring的集成Struts与Spring的集成StrutsHibernateSpring的集成没有更多的东西前面已经分别将它们集成起来了注意使用OpenSessionInView模式这是使用Hibernate的web项目最需要注意的一个问题Spring为此提供了专门的解决方案手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂OpenSessionInViewFilter这是为了避免Hibernate的懒加载异常而创建的解决方案它是一个过滤器能够让Session在请求解释完成之后再关闭(所以才能够避免懒加载异常)配置方式是在webxml中定义过滤器即可:<filter><filtername>hibernateFilter<filtername><filterclass>orgspringframeworkormhibernatesupportOpenSessionInViewFilter<filterclass><filter><filtermapping><filtername>hibernateFilter<filtername><urlpattern>*<urlpattern><filtermapping>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂CharacterEncodingFilter如何提交中文字符?配置webxml了Spring提供了专门的针对Encoding的过滤器配置方法如下:<filter><filtername>Springcharacterencodingfilter<filtername><filterclass>orgspringframeworkwebfilterCharacterEncodingFilter<filterclass><initparam><paramname>encoding<paramname><paramvalue>GBK<paramvalue><initparam><filter><filtermapping><filtername>Springcharacterencodingfilter<filtername><urlpattern>*<urlpattern><filtermapping>手把手教程版权所有:尚学堂科技StrutsHibernateSpring尚学堂更多的资料Spring官方网站http:wwwspringframeworkorgSpring中文网http:springjactiongroupnet(有中文参考手册下载

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/188

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利