Struts2+Spring+Hibernate框架整合总结详细教程
⼀.SSH三⼤框架知识总结
  Struts 2是Struts的下⼀代产品,是在 struts 1和WebWork的技术基础上进⾏了合并的全新的Struts 2。其全新的Struts 2的与Struts 1的体系结构差别巨⼤。Struts 2以WebWork为核⼼,采⽤的机制来处理⽤户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太⼤的,但是相对于WebWork,Struts 2的变化很⼩。
⼀ Struts2⼯作原理
  在Struts2框架中的处理⼤概分为以下⼏个步骤
  1 客户端初始化⼀个指向Servlet容器(例如Tomcat)的请求
  2 这个请求经过⼀系列的过滤器(Filter)(这些过滤器中有⼀个叫做ActionContextCleanUp的可选过滤器,
   这个过滤器对于Struts2和其他框架的集成很有帮助,例 如:SiteMesh Plugin)
  3 接着FilterDispatcher被调⽤,FilterDispatcher询问ActionMapper来决定这个请求是否需要调⽤某个Action
  4 如果ActionMapper决定需要调⽤某个Action,FilterDispatcher把请求的处理交给ActionProxy
  5 ActionProxy通过Configuration Manager询问框架的配置⽂件,到需要调⽤的Action类
  6 ActionProxy创建⼀个ActionInvocation的实例。
  7 ActionInvocation实例使⽤命名模式来调⽤,在调⽤Action的过程前后,涉及到相关(Intercepter)的调⽤。
  8 ⼀旦Action执⾏完毕,ActionInvocation负责根据l中的配置到对应的返回结果。
   返回结果通常是(但不总是,也可能是另外的⼀个Action链)⼀个需要被表⽰的JSP或者FreeMarker的模版。
   在表⽰的过程中可以使⽤Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
⼆ Struts2⼯作流程
  1、客户端浏览器发出HTTP请求.
  2、根据l配置,该请求被FilterDispatcher接收
  3、根据l配置,到需要调⽤的Action类和⽅法,并通过IoC⽅式,将值注⼊给Aciton
  4、Action调⽤业务逻辑组件处理业务逻辑,这⼀步包含表单验证。
  5、Action执⾏完毕,根据l中的配置到对应的返回结果result,并跳转到相应页⾯
  6、返回HTTP响应到客户端浏览器
  Spring框架是由于软件开发的复杂性⽽创建的。Spring使⽤的是基本的JavaBean来完成以前只可能由EJB完成的事情。然⽽,Spring的⽤途不仅仅限于服务器端的开发。从简单性、可测试性和松的⾓度⽽⾔,绝⼤部分Java应⽤都可以从Spring中受益。◆⽬的:解决企业应⽤开发的复杂性◆功能:使⽤基本的JavaBean代替EJB,并提供了更多的企业应⽤功能◆范围:任何Java应⽤Spring是⼀个(IoC)和⾯向切⾯(AOP)的容器框架。
Spring内部最核⼼的就是IOC了,动态注⼊,让⼀个对象的创建不⽤new了,可以⾃动的⽣产,这其实就是利⽤java⾥的反射,反射其实就是在运⾏时动态的去创建、调⽤对象,Spring就是在运⾏时,跟xml Spring的配置⽂件来动态的创建对象,和调⽤对象⾥的⽅法的。
Spring还有⼀个核⼼就是AOP这个就是⾯向切⾯编程,可以为某⼀类对象进⾏监督和控制(也就是在调⽤这类对象的具体⽅法的前后去调⽤你指定的模块)从⽽达到对⼀个模块扩充的功能。这些都是通过配置类达到的。
Spring⽬的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置内部通过反射去动态的组装对象)要记住:Spring是⼀个容器,凡是在容器⾥的对象才会有Spring所提供的这些服务和功能。
Spring⾥⽤的最经典的⼀个设计模式就是:模板⽅法模式。(这⾥我都不介绍了,是⼀个很常⽤的设计模式), Spring⾥的配置是很多的,很难都记住,但是Spring⾥的精华也⽆⾮就是以上的两点,把以上两点跟理解了也就基本上掌握了Spring.
⼀、 IoC(Inversion of control): 控制反转
1、IoC:
概念:控制权由对象本⾝转向容器;由容器根据配置⽂件去创建实例并创建各个实例之间的依赖关系
核⼼:bean⼯⼚;在Spring中,bean⼯⼚创建的各个实例称作bean
⼆、AOP(Aspect-Oriented Programming): ⾯向⽅⾯编程
1、代理的两种⽅式:
静态代理:
针对每个具体类分别编写代理类;
针对⼀个接⼝编写⼀个代理类;
动态代理:
针对⼀个⽅⾯编写⼀个InvocationHandler,然后借⽤JDK反射包中的Proxy类为各种接⼝动态⽣成相应的代理类
2、动态代理:
不⽤写代理类,虚拟机根据真实对象实现的接⼝产⽣⼀个类,通过类实例化⼀个动态代理,在实例化动态代理时将真实对象及装备注⼊到动态代理中,向客户端公开的是动态代理,当客户端调⽤动态代理⽅法时,动态代理根据类的反射得到真实对象的Method,调⽤装备的invoke⽅法,将动态代理、 Method、⽅法参数传与装备的invoke⽅法,invoke⽅法在唤起method⽅法前或后做⼀些处理。
1、产⽣动态代理的类:
fect.Proxy
2、装备必须实现InvocationHandler接⼝实现invoke⽅法
3、反射
什么是类的返射?
通过类说明可以得到类的⽗类、实现的接⼝、内部类、构造函数、⽅法、属性并可以根据构造器实例化⼀个对象,唤起⼀个⽅法,取属性值,改属性值。如何得到⼀个类说明:
Class cls=类.class;
Class cls=对象.getClass();
Class.forName("类路径");
如何得到⼀个⽅法并唤起它?
实例化bean的三种方式Class cls=类.class;
Constructor Constructor(new Class[]{String.class});
Object wInstance(new Object[]{"aaa"});
Method Method("⽅法名",new Class[]{String.class,Integer.class});
method.invoke(obj,new Object[]{"aa",new Integer(1)});
4、spring的三种注⼊⽅式是什么?
setter
interface
constructor
5、spring的核⼼接⼝及核类配置⽂件是什么?
FactoryBean:⼯⼚bean主要实现ioc/di
ApplicationContext ac=new FileXmlApplicationContext("l");
Object Bean("id值");
  Hibernate是⼀个的对象关系框架,它对JDBC进⾏了⾮常的对象封装,使得Java可以随⼼所欲的使⽤对象编程思维来操纵。 Hibernate可以应⽤在任何使⽤JDBC的场合,既可以在Java的客户端程序使⽤,也可以在Servlet/JSP的Web应⽤中使⽤,最具意义的是,Hibernate可以在应⽤EJB的J2EE架构中取代CMP,完成数据持久化的重任。Hibernate的接⼝⼀共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。
Hibernate⼯作原理和作⽤:
原理:
1.通过Configuration().configure();读取并解析l配置⽂件
2.由l中的<mapping resource="com/xx/l"/>读取并解析映射信息
3.通过config.buildSessionFactory();//创建SessionFactory
4.sessionFactory.openSession();//打开Sesssion
5.session.beginTransaction();//创建事务Transation
6.persistent operate持久化操作
Transaction()mit();//提交事务
8.关闭Session
9.关闭SesstionFactory
作⽤:
1. 对JDBC访问数据库的代码做了封装,⼤⼤简化了数据访问层繁琐的重复性代码。
2. Hibernate是⼀个基于JDBC的主流持久化框架,是⼀个优秀的ORM实现。他很⼤程度的简化DAO层的编码⼯作
3. hibernate使⽤Java反射机制,⽽不是字节码增强程序来实现透明性。
4. hibernate的性能⾮常好,因为它是个轻量级框架。映射的灵活性很出⾊。它⽀持各种关系数据库,从⼀对⼀到多对多的各种复杂关系。
2. Hibernate是如何延迟加载?
1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)
2. Hibernate3 提供了属性的延迟加载功能
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从⽽提⾼了服务器的性能。
3.Hibernate中怎样实现类之间的关系?(如:⼀对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进⾏操作,它们都市对对象进⾏操作,我们程序中把所有的表与类都映射在⼀起,它们通过配置⽂件中的many-to-one、one-to-many、many-to-many、
4.说下Hibernate的缓存机制
1. 内部缓存存在Hibernate中⼜叫⼀级缓存,属于应⽤事物级缓存
2. ⼆级缓存:
a) 应⽤及缓存
b) 分布式缓存
条件:数据不会被第三⽅修改、数据⼤⼩在可接受范围、数据更新频率低、同⼀数据被系统频繁使⽤、
⾮关键数据
c) 第三⽅缓存的实现
////////⼀级缓存:session级的缓存也叫事务级的缓存,只缓存实体,⽣命周期和session⼀致。不能对其进⾏管理。
不⽤显⽰的调⽤。
⼆级缓存:sessionFactory缓存,也叫进程级的缓存,使⽤第3⽅插件实现的,也值缓存实体,⽣命周期和sessionFactory⼀致,可以进⾏管理。
⾸先配置第3放插件,我们⽤的是EHCache,在l⽂件中加⼊
<property name="hibernate.cache.user_second_level_cache">true</property>
在映射中也要显⽰的调⽤,<cache usage="read-only"/>
⼆级缓存之查询缓存:对普通属性进⾏缓存。如果关联的表发⽣了修改,那么查询缓存的⽣命周期也结束了。
在程序中必须⼿动启⽤查询缓存:query.setCacheable(true);/////////
5. Hibernate的查询⽅式
Sql、Criteria,object comptosition
Hql:
1、属性查询
2、参数查询、命名参数查询
3、关联查询
4、分页查询
5、统计函数
6.如何优化Hibernate?
1.使⽤双向⼀对多关联,不使⽤单向⼀对多
2.灵活使⽤单向⼀对多关联
3.不⽤⼀对⼀,⽤多对⼀取代
4.配置对象缓存,不使⽤集合缓存
5.⼀对多集合使⽤Bag,多对多集合使⽤Set
6. 继承类使⽤显式多态
7. 表字段要少,表关联不要怕多,有⼆级缓存撑腰
⼆,创建数据库并并设置编码。
2.default character set utf8;原因:避免出现乱码;
三,Eclipse项⽬
1.在eclipse⾥创建web项⽬,并设置编码为utf-8;原因:避免出现乱码;
四.搭建SSH三⼤框架环境
1.到SSH各官⽹下载插件(注意版本!):struts-
2.
3.30、spring-framework-
4.2.2.RELEASE,hibernate-release-
5.2.2.Final;
2.把各⼤插件的jar包导⼊到项⽬的lib⽂件夹下:
1).Struts2必需的jar包(注意版本!)
2).spring必需的jar包(注意版本!):
注意:struts2-spring-plugin-2.3.30.jar,commons-logging-1.1.3.jar是struts的jar包
3).hibernate必需的jar包(注意版本!在required⽂件夹下):
还有在optional⽂件夹下的c3p0jar包(它既是数据库连接池包,类似的还有dbcp):
其它可选的到⽤到的时候再导⼊吧!注意:三⼤框架全部都导进来可能会产⽣包冲突!
3.配置l⽂件:
1).配置默认⾸页等等其它的;
2).配置struts,struts就是⼀个过滤器,在客服端发送请求之后和响应客户端之前进⾏适当的处理;
3).配置spring,spring就是⼀个,监听Context(上下⽂),它管理所有类的实例的创建,就像会计所有⼈要钱都要去她;
4).配置classpath路径,因为默认路径是/WEB-INF/***.xml⽽src⽂件夹路径是/WEB-INF/classes/***.xml;
1<?xml version="1.0" encoding="UTF-8"?>
2<web-app xmlns:xsi="/2001/XMLSchema-instance" xmlns="/xml/ns/javaee" xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" 3<display-name>stuAciton</display-name>
4<welcome-file-list>
5<welcome-file>default.jsp</welcome-file>
6</welcome-file-list>
7
8<filter>
9<filter-name>struts2</filter-name>
10    <!-- 2.3.3版本 -->
11<filter-class>org.apache.filter.StrutsPrepareAndExecuteFilter</filter-class>
12</filter>
13
14<filter-mapping>
15<filter-name>struts2</filter-name>
16<url-pattern>/*</url-pattern>
17</filter-mapping>
18
19<context-param>
20      <!-- XML⽂件src路径 -->
21<param-name>contextConfigLocation</param-name>
22<param-value>/WEB-INF/l</param-value>
23</context-param>
24
25<listener>
26<listener-class>org.t.ContextLoaderListener</listener-class>
27</listener>
28</web-app>
注意:每个版本有相应的配置,可以去下载的jar包⾥的⽰例代码中;
4.在src⽂件夹创建或拷贝SSH框架的配置⽂件:
1). l的⽂件配置:(可以拷贝⼀个l模版到src⽬录)
1<?xml version="1.0" encoding="UTF-8" ?>
2<!DOCTYPE struts PUBLIC
3    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
4    "/dtds/struts-2.3.dtd">
5<!-- 上⾯的头,注意版本,从样例⾥复制过来 showcase.war\WEB-INF\src\l -->
6
7<!-- include⽂件⽤于分割,实现多⼈并发不冲突 -->
8<struts>
9<!-- 告知Struts2运⾏时使⽤Spring来创建对象 -->
10<constant name="struts.objectFactory" value="spring"></constant>
11
12<!--指定Struts2默认的ObjectFactory Bean,该属性默认值是spring-->
13<package name="mypkg" extends="struts-default">
14<!-- StudentAction是请求地址、myStudentAction是Action类、execute2是Action类⾥的⽅法-->
15<action name="StudentAction"  class="myStudentAction" method="execute2">
16<!-- Action类⾥return的字符串,这个必须要⼀致,有默认的 -->
17<result name="success">/WEB-INF/jsp/student.jsp</result>
18<result name="error">/WEB-INF/jsp/error.jsp</result>
19</action>
20</package>
21</struts>
2).l⽂件的配置:
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:p="/schema/p"
xmlns:aop="/schema/aop"
xmlns:context="/schema/context"
xmlns:jee="/schema/jee"
xmlns:tx="/schema/tx"
xsi:schemaLocation="
/schema/aop /schema/aop/spring-aop-4.2.xsd
/schema/beans /schema/beans/spring-beans-4.2.xsd
/schema/context /schema/context/spring-context-4.2.xsd            /schema/jee /schema/jee/spring-jee-4.2.xsd
/schema/tx /schema/tx/spring-tx-4.2.xsd">
<!-- 类似于财务部门⼀样,类就是钱,所有需要类的实例都由srping去管理 -->
<!-- id属性的值是接⼝、class属性的值为id接⼝的⼀个实例、prototype属性值为⾮单例 -->
<bean id="myStudentAction" class="action.StudentAction" scope="prototype">
<!-- ss是class实例⾥的⼀个全局属性,给ss设置⼀个 StudentService实例的值-->
<property name="ss" ref="StudentService"></property><!-- Spring依赖注⼊ -->
</bean>
<!-- id属性的值是接⼝、class属性的值为id接⼝的⼀个实例、prototype属性值为⾮单例 -->
<bean id="StudentService" class="serverce.StudentServiceImpl" scope="prototype">
<!-- sdd是class实例⾥的⼀个全局属性,给sdd设置⼀个 StudentDao实例的值-->
<property name="sdd" ref="StudentDao"></property><!-- Spring依赖注⼊ -->
</bean>
<bean id="StudentDao" class="dao.StudentDaoImpl" scope="prototype">
<!-- 注⼊两个hibernate类⼀个⽤来查询⼀个⽤来插⼊-->
<property name="sessionfactory" ref="sessionfactory"></property><!-- Spring依赖注⼊ -->
<property name="sessionfactory2" ref="sessionfactory2"></property><!-- Spring依赖注⼊ -->
</bean>
<!-- hibernate5.LocalSessionFactoryBean是hibernate的jar包 -->
<bean id="sessionfactory"
class="hibernate5.LocalSessionFactoryBean"
scope="prototype">
<!-- 注⼊⼀个数据库连接池 -->
<property name="dataSource" ref="SQLServerDatasource"></property>
<!--配置hibernateproperties替换l⽂件  -->
<property name="hibernateProperties">
<props>
<!-- ⽅⾔是必需的 -->
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<!-- 显⽰SQL语句  -->
<prop key="hibernate.show_sql">true</prop>
<!-- 格式化SQL语句 -->
<prop key="hibernate.format_sql">true</prop>
<!-- 是否⾃动提交 -->
<prop key="tion.autocommit">false</prop>
<!-- ⾃动创建修改表 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 关联数据映射⽂件  -->
<property name="mappingResources">
<!-- 数据表映射配置⽂件 -->
<list>
<value>l</value>
</list>
</property>
</bean>
<!-- 同上  -->
<bean id="sessionfactory2" class="hibernate5.LocalSessionFactoryBean" scope="prototype"> <!-- <property name="configLocation" value="/WEB-INF/classes/l"></property> -->
<property name="dataSource" ref="MySQLDatasource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="tion.autocommit">false</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="mappingResources">
<list><value>l</value></list>
</property>
</bean>
<!--SQLServer连接池  -->
<bean id="SQLServerDatasource" class="org.apachemons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=StuSys"/>
<property name="username" value="sa"/>
<property name="password" value="123456"/>
<!--每300秒检查连接池中的空闲连接  -->
<property name="numTestsPerEvictionRun" value="300"></property>
<!-- 最⼤空闲时间,900秒未使⽤则丢弃,若是0则永远不丢弃 -->
<property name="minEvictableIdleTimeMillis" value="900"></property>
<!-- 最⼤连接数 -->
<property name="maxIdle" value="2"></property>
</bean>
<!--MySQL连接池  org.apachemons.dbcp.BasicDataSource是dbcp的jar包的类-->
<bean id="MySQLDatasource" class="org.apachemons.dbcp.BasicDataSource">
<property name="driverClassName" value="sql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/StuSys"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<!--每300秒检查连接池中的空闲连接  -->
<property name="numTestsPerEvictionRun" value="300"></property>
<!-- 最⼤空闲时间,900秒未使⽤则丢弃,若是0则永远不丢弃 -->
<property name="minEvictableIdleTimeMillis" value="900"></property>
<!-- 最⼤连接数 -->
<property name="maxIdle" value="2"></property>
</bean>
</beans>
3).类名.l⽂件的配置:
这是数据表和实体类的映射,注意类型不匹配很容易出现异常;<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- class代表实体类跟数据库表之间的映射 -->
<class name="entity.Student" table="student">
<id name="id" column="ID"><!-- ID的类型要注意对应,否则会出现异常 -->
<generator class="native"/><!-- class要根据不的数据库填写不同的值 --> </id>
<!--类的每个属性对应表⾥的每个字段,要注意类型的对应  -->
<property name="name" column="NAME"/>
<property name="sex" column="SEX"/>
<property name="age"  column="AGE"/>
<property name="addres" column="ADDRES"/>
</class>
</hibernate-mapping>
5.在src⽬录下构建项⽬的包和类:
1).在entity包⾥创建student.java,实体类属性的类型要正确这很重要;
1 package entity;
2
3 public class Student {
4    private int id;
5    private String name;
6    private String sex;
7    private int age;
8    private String addres;
9
10    public Student(){}
11
12    public Student(int id, String name, String sex, int age, String addres) {
13        super();
14        this.id = id;
15        this.name = name;
16        this.sex = sex;
17        this.age = age;
18        this.addres = addres;
19    }
20
21
22    public Student(String name, String sex, int age, String addres) {
23        super();
24        this.name = name;
25        this.sex = sex;
26        this.age = age;
27        this.addres = addres;
28    }
29
30    public int getId() {
31        return id;
32    }
33
34    public void setId(int id) {
35        this.id = id;
36    }
37
38    public String getName() {
39        return name;
40    }
41
42    public void setName(String name) {
43        this.name = name;
44    }
45
46    public String getSex() {
47        return sex;
48    }
49
50    public void setSex(String sex) {
51        this.sex = sex;
52    }
53
54    public int getAge() {
55        return age;
56    }
57
58    public void setAge(int age) {
59        this.age = age;
60    }
61
62    public String getAddres() {
63        return addres;
64    }
65
66    public void setAddres(String addres) {
67        this.addres = addres;
68    }
69
70 }
2).客服端发送请求到服务器被struts拦下让Action.java来处理:
1package action;
2
3import java.util.List;
4
5import com.opensymphony.xwork2.ActionSupport;
6
7import entity.Student;
8import serverce.StudentService;
9
10//Action类就是继承ActionSupport类的普通类
11public class StudentAction extends ActionSupport {
12
13//设置私有属性⽤于向JSP传递数据
14private List<Student> myStuList;
15//或从外部注⼊实例到本类;
16private StudentService ss;
17//这⾥采⽤set注⼊⽅法,还可以⽤构造函数⽅法、接⼝的⽅法;
18public void setSs(StudentService ss) {
19this.ss = ss;
20    }
21public List<Student> getMyStuList() {
22return myStuList;
23    }
24public void setMyStuList(List<Student> myStuList) {

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。