重构dao,利用泛型

ssh结合以后的执行流程

  1. 服务器启动的时候

    web.xml的执行流程(项目jdk为1.7)

    1. 启动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容器启动时生成的,验证方法为:打断点,在构造函数输出一句话。

    2. struts2内部

      • 加载default.properties配置文件
      • 加载struts-default.xml配置文件
      • 加载struts-plugin.xml配置文件
      • 加载struts.xml配置文件
  2. 当请求的时候

    1. 执行OpenSessionInViewFilter中的除了finally之外的部分

      1. 从spring容器中把sessionFactory提取出来
      2. 有sessionFactory获取session
    2. 执行struts2核心过滤器中除了finally之外的部分

      1. 先执行拦截器
      2. 执行action
      3. 执行结果集
      4. 再次执行拦截器
    3. 执行struts2核心过滤器中的finally部分

      清空actionContext

    4. 执行OpenSessionInViewFilter中的finally部分

      关闭session

      说明:

      有了OpenSessionInViewFilter的时候,提前开启session,延迟关闭session,从而解决了懒加载的问题。

      延长了session的声明周期意味着session在一级缓存中的对象数据会过长时间停留在内存中。只适合小数据小并发。

泛型

  1. 概念

    1. 泛型是java中的一种类型

    2. 在java中所有的类型都可以用Type来代替

    3. ParameterizedType该类型就是泛型

      1
      2
      3
      4
      5
      6
      7
      8
      public interface ParameterizedType extends Type {
      //得到实际类型的参数
      Type[] getActualTypeArguments();
      //得到rawType
      Type getRawType();
      //得到自己的类型
      Type getOwnerType();
      }
    4. 理解ActualTypeArguments、RawType

      1
      2
      3
      public class Person<E>{

      }

      上述的class由两部分组成

      Person rawType

      代表形参

      • getActualTypeArguments()该方法告诉程序员E的实际类型

      在编译阶段,把实参传递给形参

    5. 在泛型中传递参数的方式

      1. 声明了一个泛型

        1
        2
        3
        public class ArrayList<E>{

        }

        为ArrayList创建对象

        1
        ArrayList<Person> pList = new ArrayList<Person>();
      2. 泛型具有传递性

        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>{

        }
      3. 例如ArrayList

        1
        2
        3
        ArrayList<Person> --> ArrayList<E> --> AbstractList<E> --> AbstractCollection<E> --> 
        Lise<E>
        Collection<E>

使用泛型重构DAO

  1. 在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);
    }
  2. 实现类: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];
    }

    @Resource(name="hibernatetemplate")
    public HibernateTemplate hibernatetemplate;

    @Override
    public Collection<E> getAllEntry() {
    // TODO Auto-generated method stub
    return this.hibernatetemplate.find( "from "+ this.classt.getName() );
    }
    @Override
    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);
    }
    @Override
    public void saveEntry(E e) {
    // TODO Auto-generated method stub
    this.hibernatetemplate.save(e);
    }
    @Override
    public void deleteEntry(Serializable id) {
    // TODO Auto-generated method stub
    E e = this.getEntryById(id);
    this.hibernatetemplate.delete(e);
    }
    @Override
    public void updateEntry(E e) {
    // TODO Auto-generated method stub
    this.hibernatetemplate.update(e);
    }
    }

  3. 更改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;
    @Repository("personDao")
    public class PersonDaoImpl extends BaseDaoImpl<Person> implements PersonDao{

    }
  4. 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>{

    }
  5. 修改applicationContext.xml文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?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: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>
  6. 修改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
    <?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: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>
  7. 修改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;

    @Service("personService")
    public class PersonServiceImpl implements PersonService{
    @Resource(name="personDao")
    private PersonDao personDao;

    public PersonDao getPersonDao() {
    return personDao;
    }

    public void setPersonDao(PersonDao personDao) {
    this.personDao = personDao;
    }

    @Transactional(readOnly=false)
    public void savePerson(Person person) {
    // TODO Auto-generated method stub
    this.personDao.saveEntry(person);
    }
    }
  8. 新增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();
    }
    }

    @Override
    public E getModel() {
    // TODO Auto-generated method stub
    return this.e;
    }
    }
  9. 修改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;

    @Controller("personAction")
    @Scope("prototype")
    public class PersonAction extends BaseAction<Person>{
    @Resource(name="personService")
    private PersonService personService;

    public String savePerson(){
    Person person = new Person();
    person.setName("EVA");
    this.personService.savePerson(person);
    return null;
    }
    }
  10. 修改web.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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>sh05oa_maven</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置读取spring文件的路径-->
<context-param>
<param-name>contextConfigLocation</param-name>

<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>


<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>

<filter>
<filter-name>struts2</filter-name>
<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>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
  1. 测试

过滤器doFilterInternal方法try和finally执行顺序

采用责任链模式

  • a try
  • b try
  • a finally
  • b finally

什么是懒加载

hibernate中最常用的有3种关系,单表、一对多、多对一。