一.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的变化很小。
1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,
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负责根据struts.xml中的配置找到对应的返回结果。
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、产生动态代理的类:
java.lang.refect.Proxy
2、装备必须实现InvocationHandler接口实现invoke方法
3、反射
什么是类的返射?
通过类说明可以得到类的父类、实现的接口、内部类、构造函数、方法、属性并可以根据构造器实例化一个对象,唤起一个方法,取属性值,改属性值。如何得到一个类说明:
Class cls=类.class;
Class cls=对象.getClass();
Class.forName("类路径");
如何得到一个方法并唤起它?
Class cls=类.class;
Constructor cons=cls.getConstructor(new Class[]{String.class});
Object obj=cons.newInstance(new Object[]{"aaa"});
Method method=cls.getMethod("方法名",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("applicationContext.xml");
Object obj=ac.getBean("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();读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息
3.通过config.buildSessionFactory();//创建SessionFactory
4.sessionFactory.openSession();//打开Sesssion
5.session.beginTransaction();//创建事务Transation
6.persistent operate持久化操作
7.session.getTransaction().commit();//提交事务
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,在hibernate.cfg.xml文件中加入
<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. 表字段要少,表关联不要怕多,有二级缓存撑腰
二,创建数据库并并设置编码。
1.create database dataname;注意:hibernate不会自己创建数据库;
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.配置web.xml文件:
1).配置默认首页等等其它的;
2).配置struts,struts就是一个过滤器,在客服端发送请求之后和响应客户端之前进行适当的处理;
3).配置spring,spring就是一个监听器,监听Context(上下文),它管理所有类的实例的创建,就像会计所有人要钱都要去找她;
4).配置classpath路径,因为默认路径是/WEB-INF/***.xml而src文件夹路径是/WEB-INF/classes/***.xml;
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>stuAciton</display-name>
<welcome-file-list>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list> <filter>
<filter-name>struts2</filter-name>
<!-- 2.3.3版本 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter> <filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <context-param>
20 <!-- XML文件src路径 -->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
注意:每个版本有相应的配置,可以去下载的jar包里的示例代码中找;
4.在src文件夹创建或拷贝SSH框架的配置文件:
1). struts.xml的文件配置:(可以拷贝一个struts.xml模版到src目录)
struts.xml是struts2核心的核心,它负责跳转,传递参数;可以用struts.properties代替;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- 上面的头,注意版本,从样例里复制过来 showcase.war\WEB-INF\src\java\struts.xml --> <!-- include文件用于分割,实现多人并发不冲突 -->
<struts>
<!-- 告知Struts2运行时使用Spring来创建对象 -->
<constant name="struts.objectFactory" value="spring"></constant> <!--指定Struts2默认的ObjectFactory Bean,该属性默认值是spring-->
<package name="mypkg" extends="struts-default">
<!-- StudentAction是请求地址、myStudentAction是Action类、execute2是Action类里的方法-->
<action name="StudentAction" class="myStudentAction" method="execute2">
<!-- Action类里return的字符串,这个必须要一致,有默认的 -->
<result name="success">/WEB-INF/jsp/student.jsp</result>
<result name="error">/WEB-INF/jsp/error.jsp</result>
</action>
</package>
</struts>
2).applicationContext.xml文件的配置:
applicationContext.xml是spring框架的入口点,是struts关联spring的桥梁也是spring关联hibernate的桥梁;
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/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>
<!-- org.springframework.orm.hibernate5.LocalSessionFactoryBean是hibernate的jar包 -->
<bean id="sessionfactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
scope="prototype">
<!-- 注入一个数据库连接池 -->
<property name="dataSource" ref="SQLServerDatasource"></property>
<!--配置hibernateproperties替换hibernate.cfg.xml文件 -->
<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="hibernate.connection.autocommit">false</prop>
<!-- 自动创建修改表 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 关联数据映射文件 -->
<property name="mappingResources">
<!-- 数据表映射配置文件 -->
<list>
<value>Student.hbm.xml</value>
</list>
</property>
</bean>
<!-- 同上 -->
<bean id="sessionfactory2" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" scope="prototype">
<!-- <property name="configLocation" value="/WEB-INF/classes/hibernate2.cfg.xml"></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="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="mappingResources">
<list><value>Student.hbm.xml</value></list>
</property>
</bean> <!--SQLServer连接池 -->
<bean id="SQLServerDatasource" class="org.apache.commons.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.apache.commons.dbcp.BasicDataSource是dbcp的jar包的类-->
<bean id="MySQLDatasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.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).类名.hbm.xml文件的配置:
这是数据表和实体类的映射,注意类型不匹配很容易出现异常;
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/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,实体类属性的类型要正确这很重要;
package entity; public class Student {
private int id;
private String name;
private String sex;
private int age;
private String addres; public Student(){} public Student(int id, String name, String sex, int age, String addres) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.addres = addres;
} public Student(String name, String sex, int age, String addres) {
super();
this.name = name;
this.sex = sex;
this.age = age;
this.addres = addres;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getAddres() {
return addres;
} public void setAddres(String addres) {
this.addres = addres;
} }
2).客服端发送请求到服务器被struts拦下让Action.java来处理:
package action; import java.util.List; import com.opensymphony.xwork2.ActionSupport; import entity.Student;
import serverce.StudentService; //Action类就是继承ActionSupport类的普通类
public class StudentAction extends ActionSupport { //设置私有属性用于向JSP传递数据
private List<Student> myStuList;
//或从外部注入实例到本类;
private StudentService ss;
//这里采用set注入方法,还可以用构造函数方法、接口的方法;
public void setSs(StudentService ss) {
this.ss = ss;
}
public List<Student> getMyStuList() {
return myStuList;
}
public void setMyStuList(List<Student> myStuList) {
this.myStuList = myStuList;
} //返回的类型必需是字符串类型,可以创建多个方法用于不同的跳转
public String execute1(){
myStuList=ss.getStuAll();
System.out.println("全部在:"+myStuList);
return "success";
}
public String execute2(){
return "error";
}
}
3).在Action处理业务逻辑的时候,struts会调用spring为所有类提供实例
package serverce; import java.util.List; import dao.StudentDao;
import entity.Student; public class StudentServiceImpl implements StudentService {
//set注入
private StudentDao sdd; /* (non-Javadoc)
* @see serverce.StudentService#setSdd(dao.StudentDao)
*/
@Override
public void setSdd(StudentDao sdd) {
this.sdd = sdd;
} /* (non-Javadoc)
* @see serverce.StudentService#getStuAll()
*/
@Override
public List<Student> getStuAll(){ //解耦合
List<Student> list=sdd.getStudentAll();
return list;
}
}
4).处理业务逻辑要用到数据,hibernate提供了sessionfactory类替代JDBC帮我们自动创建表
package dao; import java.util.List; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; import entity.Student;
import util.MyConnection; public class StudentDaoImpl implements StudentDao {
//注入sessionfactory工厂类
private SessionFactory sessionfactory;
private SessionFactory sessionfactory2; public void setSessionfactory(SessionFactory sessionfactory) {
this.sessionfactory = sessionfactory;
}
public void setSessionfactory2(SessionFactory sessionfactory2) {
this.sessionfactory2 = sessionfactory2;
}
/* (non-Javadoc)
* @see dao.StudentDao#getStudentAll()
*/
@Override
public List<Student> getStudentAll(){
System.out.println("获得一个非常重要的对象sessionFactory"+sessionfactory);
Session session=sessionfactory.openSession();
Session session2=sessionfactory2.openSession();
//读取全部数据打印
//创建事务,执行插入数据操作
session.beginTransaction();
session2.beginTransaction();
session.save(new Student("胡歌","男",30,"上海"));
session.save(new Student("胡兵","男",35,"深圳"));
//获得数据库结果集
List<Student> result=session.createQuery("from Student").getResultList();
for(Student stu:result){
System.out.println("ok");
session2.save(stu);
}
session.getTransaction().commit();
session2.getTransaction().commit();
sessionfactory.close();
sessionfactory2.close();
session.close();
session2.close(); return result;
}
}
5).这样我们就可以把结果集跳转传递到JSP页面去:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<td>全选</td>
<td>序号</td>
<td>编号</td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>住址</td>
</tr>
<s:iterator value="myStuList" status="bcs">
<tr>
<td></td>
<td><s:property value="#bcs.count" /></td>
<td><s:property value="id"></s:property></td>
<td><s:property value="name"></s:property></td>
<td><s:property value="sex"></s:property></td>
<td><s:property value="age"></s:property></td>
<td><s:property value="addres"></s:property></td>
</tr>
</s:iterator>
<s:if test="myStuList.size()==0">
<tr>
<td colspan="7">没有查找到数据</td>
</tr>
</s:if>
</table>
</body>
</html>
6).测试:http://localhost:8080/studentSys/StudentAction.action