ssh重构
重构dao,利用泛型
ssh结合以后的执行流程
- 服务器启动的时候- web.xml的执行流程(项目jdk为1.7) - 启动spring容器 - 1 
 2
 3
 4
 5
 6
 7- <listener> 
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <context-param>可以不写 不写默认加载web-inf
 <param-name>contextConfigLocation</param-name>
 <param-value>classpath:spring/applicationContext.xml</param-value>
 </context-param>- 说明: - dao层和service层所有的类将实例化。代理对象是在spring容器启动时生成的,验证方法为:打断点,在构造函数输出一句话。 
- struts2内部 - 加载default.properties配置文件
- 加载struts-default.xml配置文件
- 加载struts-plugin.xml配置文件
- 加载struts.xml配置文件
 
 
- 当请求的时候- 执行OpenSessionInViewFilter中的除了finally之外的部分 - 从spring容器中把sessionFactory提取出来
- 有sessionFactory获取session
 
- 执行struts2核心过滤器中除了finally之外的部分 - 先执行拦截器
- 执行action
- 执行结果集
- 再次执行拦截器
 
- 执行struts2核心过滤器中的finally部分 - 清空actionContext 
- 执行OpenSessionInViewFilter中的finally部分 - 关闭session - 说明: - 有了OpenSessionInViewFilter的时候,提前开启session,延迟关闭session,从而解决了懒加载的问题。 - 延长了session的声明周期意味着session在一级缓存中的对象数据会过长时间停留在内存中。只适合小数据小并发。 
 
泛型
- 概念- 泛型是java中的一种类型 
- 在java中所有的类型都可以用Type来代替 
- ParameterizedType该类型就是泛型 - 1 
 2
 3
 4
 5
 6
 7
 8- public interface ParameterizedType extends Type { 
 //得到实际类型的参数
 Type[] getActualTypeArguments();
 //得到rawType
 Type getRawType();
 //得到自己的类型
 Type getOwnerType();
 }
- 理解ActualTypeArguments、RawType - 1 
 2
 3- public class Person<E>{ 
 
 }- 上述的class由两部分组成 - Person rawType - 代表形参 - getActualTypeArguments()该方法告诉程序员E的实际类型
 - 在编译阶段,把实参传递给形参 
- 在泛型中传递参数的方式 - 声明了一个泛型 - 1 
 2
 3- public class ArrayList<E>{ 
 
 }- 为ArrayList创建对象 - 1 - ArrayList<Person> pList = new ArrayList<Person>(); 
- 泛型具有传递性 - 1 
 2
 3
 4
 5
 6
 7
 8
 9- public interface PersonDao<E>{ 
 
 }
 public interface P<E> extends PersonDao<E>{
 
 }
 public class PersonDaoImpl implements P<Person>{
 
 }
- 例如ArrayList - 1 
 2
 3- ArrayList<Person> --> ArrayList<E> --> AbstractList<E> --> AbstractCollection<E> --> 
 Lise<E>
 Collection<E>
 
 
使用泛型重构DAO
- 在cn/itcast/shoa/dao/base目录下新建接口BeanDao- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24- package cn.itcast.shoa.dao.base; 
 import java.io.Serializable;
 import java.util.Collection;
 public interface BaseDao<E> {
 /**
 * 得到E代表的所有实体类对象
 * @return
 */
 public Collection<E> getAllEntry();
 /**
 * Serializable该类型可以接受所有的基本类型和String类型
 * @param id
 * @return
 */
 public E getEntryById(Serializable id);
 
 public void saveEntry(E e);
 
 public void deleteEntry(Serializable id);
 
 public void updateEntry(E e);
 }
- 实现类:cn/itcast/shoa/dao/base/impl/BaseDaoImpl- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72- package cn.itcast.shoa.dao.base.impl; 
 import java.io.Serializable;
 import java.lang.reflect.ParameterizedType;
 import java.util.Collection;
 import javax.annotation.Resource;
 import org.hibernate.metadata.ClassMetadata;
 import org.springframework.orm.hibernate3.HibernateTemplate;
 import cn.itcast.shoa.dao.base.BaseDao;
 public class BaseDaoImpl<E> implements BaseDao<E>{
 
 private Class classt;
 
 public BaseDaoImpl() {
 /**
 * 1.this可以代表子类或本类
 * 2.不能把BaseDaoImpl在spring容器中实例化,因为如果在Spring容器中实例化,就不是泛型了
 * 3.所以根据以上两点可以得出this应该代表子类
 * 4.this.getClass().getGenericSuperclass()代表当前类:就是泛型
 * 5.注意:不能把BaseDaoImpl让spring容器实例化
 */
 // TODO Auto-generated constructor stub
 ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
 //因为将来E代表的是某一个持久化类,而该类型是class
 this.classt = (Class)type.getActualTypeArguments()[0];
 }
 
 
 public HibernateTemplate hibernatetemplate;
 
 public Collection<E> getAllEntry() {
 // TODO Auto-generated method stub
 return this.hibernatetemplate.find( "from "+ this.classt.getName() );
 }
 
 public E getEntryById(Serializable id) {
 // TODO Auto-generated method stub
 /**
 * classMetadata是持久化类的数据字典
 */
 ClassMetadata classMetadata = this.hibernatetemplate.getSessionFactory().getClassMetadata(this.classt);
 return (E)this.hibernatetemplate.
 find("from "+this.classt.getName()
 +
 " where "
 +classMetadata.getIdentifierPropertyName()
 +"=?",
 id).get(0);
 }
 
 public void saveEntry(E e) {
 // TODO Auto-generated method stub
 this.hibernatetemplate.save(e);
 }
 
 public void deleteEntry(Serializable id) {
 // TODO Auto-generated method stub
 E e = this.getEntryById(id);
 this.hibernatetemplate.delete(e);
 }
 
 public void updateEntry(E e) {
 // TODO Auto-generated method stub
 this.hibernatetemplate.update(e);
 }
 }
- 更改PersonDaoImpl- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- package cn.itcast.shoa.dao.impl; 
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 import org.springframework.stereotype.Repository;
 import cn.itcast.shoa.dao.PersonDao;
 import cn.itcast.shoa.dao.base.impl.BaseDaoImpl;
 import cn.itcast.shoa.domain.Person;
 public class PersonDaoImpl extends BaseDaoImpl<Person> implements PersonDao{
 }
- 4.更改PersonDao- 1 
 2
 3
 4
 5
 6
 7
 8- package cn.itcast.shoa.dao; 
 import cn.itcast.shoa.dao.base.BaseDao;
 import cn.itcast.shoa.domain.Person;
 public interface PersonDao extends BaseDao<Person>{
 
 }
- 修改applicationContext.xml文件- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 <beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 <import resource="applicationContext-db.xml"/>
 <!--
 <import resource="applicationContext-person.xml"/>
 -->
 </beans>
- 修改applicationContext-db.xml文件- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 <beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
 <!--
 引入dataSource
 -->
 <bean
 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="locations">
 <value>classpath:jdbc.properties</value>
 </property>
 </bean>
 <bean id="dataSource" destroy-method="close"
 class="org.apache.commons.dbcp.BasicDataSource">
 <property name="driverClassName" value="${jdbc.driverClassName}" />
 <property name="url" value="${jdbc.url}" />
 <property name="username" value="${jdbc.username}" />
 <property name="password" value="${jdbc.password}" />
 </bean>
 <!--
 把hibernate的配置文件引入进来
 -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <property name="configLocation">
 <value>classpath:hibernate/hibernate.cfg.xml</value>
 </property>
 </bean>
 
 <bean id="sessionFactory2"
 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <property name="dataSource">
 <ref bean="dataSource"/>
 </property>
 
 <!--
 指明映射文件所在的路径
 -->
 
 <property name="mappingDirectoryLocations">
 
 <!--
 把指定路径下面的所有的映射文件全部加载完毕
 会加载指定路径下所有的映射文件
 -->
 
 <value>classpath:cn/itcast/shoa/domain</value>
 </property>
 <!--
 <property name="mappingJarLocations">
 <value>WEB-INF/lib/jbpm-4.4.jar</value>
 </property>
 -->
 <property name="hibernateProperties">
 <value>
 hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
 hibernate.show_sql=true
 hibernate.hbm2ddl.auto=update
 </value>
 </property>
 </bean>
 
 <!--
 事务管理器
 告诉spring容器开启事务用什么技术
 -->
 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
 <property name="sessionFactory">
 <ref bean="sessionFactory"/>
 </property>
 </bean>
 
 <!--
 引入hibernateTemplate
 -->
 <bean id="hibernatetemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
 <property name="sessionFactory">
 <ref bean="sessionFactory"/>
 </property>
 </bean>
 <!--
 <tx:advice id="tx" transaction-manager="transactionManager">
 <tx:attributes>
 <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
 </tx:attributes>
 </tx:advice>
 -->
 <!--
 <aop:config>
 <aop:pointcut expression="execution(* cn.itcast.shoa.service.impl.*.*(..))" id="perform"/>
 <aop:advisor advice-ref="tx" pointcut-ref="perform"/>
 </aop:config>
 -->
 <context:component-scan base-package="cn.itcast.shoa"></context:component-scan>
 <tx:annotation-driven transaction-manager="transactionManager"/>
 </beans>
- 修改PersonServiceImpl- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30- package cn.itcast.shoa.service.impl; 
 import javax.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import cn.itcast.shoa.dao.PersonDao;
 import cn.itcast.shoa.domain.Person;
 import cn.itcast.shoa.service.PersonService;
 public class PersonServiceImpl implements PersonService{
 
 private PersonDao personDao;
 public PersonDao getPersonDao() {
 return personDao;
 }
 public void setPersonDao(PersonDao personDao) {
 this.personDao = personDao;
 }
 
 public void savePerson(Person person) {
 // TODO Auto-generated method stub
 this.personDao.saveEntry(person);
 }
 }
- 新增BaseAction- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32- package cn.itcast.shoa.struts.action.base; 
 import java.lang.reflect.ParameterizedType;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.ModelDriven;
 public class BaseAction<E> extends ActionSupport implements ModelDriven<E>{
 
 private Class classt;
 private E e;
 
 public BaseAction(){
 ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
 this.classt = (Class)type.getActualTypeArguments()[0];
 try {
 this.e = (E)this.classt.newInstance();
 } catch (InstantiationException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (IllegalAccessException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
 
 public E getModel() {
 // TODO Auto-generated method stub
 return this.e;
 }
 }
- 修改PersonAction- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27- package cn.itcast.shoa.struts.action; 
 import javax.annotation.Resource;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Controller;
 import cn.itcast.shoa.domain.Person;
 import cn.itcast.shoa.service.PersonService;
 import cn.itcast.shoa.struts.action.base.BaseAction;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.ModelDriven;
 public class PersonAction extends BaseAction<Person>{
 
 private PersonService personService;
 
 public String savePerson(){
 Person person = new Person();
 person.setName("EVA");
 this.personService.savePerson(person);
 return null;
 }
 }
- 修改web.xml配置文件
| 1 | 
 | 
- 测试- 访问http://localhost:8080/shoa_maven/personAction_savePerson
- 查看数据库shoa 发现person表中新增记录就标识成功
 
过滤器doFilterInternal方法try和finally执行顺序
采用责任链模式
- a try
- b try
- a finally
- b finally

什么是懒加载
hibernate中最常用的有3种关系,单表、一对多、多对一。


