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
8public interface ParameterizedType extends Type {
//得到实际类型的参数
Type[] getActualTypeArguments();
//得到rawType
Type getRawType();
//得到自己的类型
Type getOwnerType();
}理解ActualTypeArguments、RawType
1
2
3public class Person<E>{
}上述的class由两部分组成
Person rawType
代表形参 - getActualTypeArguments()该方法告诉程序员E的实际类型
在编译阶段,把实参传递给形参
在泛型中传递参数的方式
声明了一个泛型
1
2
3public class ArrayList<E>{
}为ArrayList创建对象
1
ArrayList<Person> pList = new ArrayList<Person>();
泛型具有传递性
1
2
3
4
5
6
7
8
9public interface PersonDao<E>{
}
public interface P<E> extends PersonDao<E>{
}
public class PersonDaoImpl implements P<Person>{
}例如ArrayList
1
2
3ArrayList<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
24package 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
72package 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
12package 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
8package 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
30package 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
32package 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
27package 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种关系,单表、一对多、多对一。