zoukankan      html  css  js  c++  java
  • SSH框架整合 spring struts2 hibernate


    引用其他配置文件(applicationContext.xml)<import resource="classpath:applicationContext.dao.xml"/>
    或者在web.xml里统一设置 配置文件要命名规范 也可以写很多个param-value 引入每个文件
                            (<param-value>classpath:applicationContext.dao.xml</>)
    <context-param>
        <param-name>contextConfigLocation"</>
        <param-value>classpath:applicationContext*.xml</>
    </context-param>
    =======================================================================================

    在配置文件中,连接数据库的方式

    1   -------------------------------------------------------------------------------------------
    <!--  spring配置文件中 通过hibernate配置文件连接数据库 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml">
    </bean>

    <!--  hibernate配置文件 -->
    <hibernate-configuration>
        <session-factory>
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/sql?useUnicode=true&amp;characterEncoding=utf8</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">123</property>
            
            <property name="hibernate.show_sql">true</property>
            <property name="hibernate.format_sql">true</property>
            <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
            <property name="hibernate.current_session_context_class">thread</property>
            
            <mapping resource="model/User.hbm.xml" />
            <mapping resource="model/House.hbm.xml" />
            
        </session-factory>
    </hibernate-configuration>
    2   -------------------------------------------------------------------------------------------

    <!-- 使用数据源连接数据库 -->
    数据源 jar: dbcp pool
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource">
        <!-- 辅助参数 -->
        <property name="hibernateProperties">
            <props>
                <prop key="dialect">org.hibernate.dialect.MySQLDialec</>
                <prop key="hibernate.show_sql">true</>
                <prop key="hibernate.format_sql">true</>
                <prop key="hibernate.current_session_context_class">thread</>
            </>
        </>
        <!-- mappingResource需要一个个指定
        <property name="mappingResources">
            <list>
                <value>model/User.hbm.xml</>
                <value>model/House.hbm.xml</>
            </>
        </>  -->
        <!-- mappingDirectoryLocations可以指定一个包 -->
        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath:model/</>
            </>
        </>
        
    </bean>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver">
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/sql">
        <property name="username" value="root">
        <property name="password" value="123">
        <property name="maxActive" value="100">
        <property name="maxIdle" value="10">
        <property name="maxWait" value="10000">
    </bean>


    3   -------------------------------------------------------------------------------------------
    使用c3p0连接数据库 需求jar包:c3p0-0.9.1.jar

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/sql"></property>
    <property name="user" value="root"></property>
    <property name="password" value="123"></property>
    <property name="initialPoolSize" value="6"></property>
    <property name="maxPoolSize" value="50"></property>
    <property name="maxIdleTime" value="1000"></property>
    </bean>


    4   -------------------------------------------------------------------------------------------
    如果写在单独的属性文件中 jdbc.properties(键值对的形式)

    jdbc.driverclass=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://127.0.0.1:3306/sql?useUnicode=true&characterEncoding=UTF-8
    jdbc.username=root
    jdbc.password=123


    那么在Spring配置文件中引入
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSource"></property><!--引用dataSource参数连接数据库-->
      <property name="hibernateProperties"> <!--配置方言等辅助参数-->
        <props>
          <prop key="dialect">org.hibernate.dialect.MySQLDialec</prop>
          <prop key="hibernate.show_sql">true</prop>
          <prop key="hibernate.format_sql">true</prop>
          <prop key="hibernate.current_session_context_class">thread</prop>
        </props>
      </property>
      <property name="mappingDirectoryLocations"><!--添加映射文件目录-->
        <list>
          <value>classpath:model/</value>
        </list>
      </property>
    </bean>
    <bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"><!--引入类 这个类会找到属性文件 -->
      <property name="locations" value="classpath:jdbc.properties"></property><!--引入属性文件 连接数据库参数-->
    </bean>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><!--用EL表达式从属性文件中取值 value放的是键-->
      <property name="driverClassName" value="${jdbc.driverclass}"></property>
      <property name="url" value="${jdbc.url}"></property>
      <property name="username" value="${jdbc.username}"></property>
      <property name="password" value="${jdbc.password}"></property>
      <property name="maxIdle" value="5" />
    </bean>


    5  --------------------------------------------------------------->

    dbcp读取属性文件的方式   连接数据库
    用context引入配置文件(连接数据库的参数) Spring配置文件中:
     xmlns:context="http://www.springframework.org/schema/context"
          http://www.springframework.org/schema/context/spring-context-3.1.xsd

    <!-- sessionFactory的bean,引入映射文件 及方言等辅助参数  去引用上面的配置,此处省略 -->
    <context:property-placeholder location="classpath:jdbc.properties" /><!--引入属性文件-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><!--引入这个类 BasicDataSource-->
        <property name="driverClassName" value="${driverclass}">
        <property name="url" value="${url}">  
        <property name="username" value="${username}">   //value 对应文件中的键}
    </bean>


    6-------------------------------------------------------->


    jndi数据源

    <!-- sessionFactory的bean,引入映射文件 及方言等辅助参数  去引用上面的配置,此处省略 -->
    tomcat/context.xml --- context标签中添加连接数据库的信息
    把数据库驱动jar包放进tomcat/lib/目录下
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="java:comp/env/xxx"></property>
    </bean>


    spring配置完  =========================================================================================

    在web.xml中需要配置
    //contextConfigLocation:spring配置文件的存放位置
    //ContextLoaderListener:当Web容器运行时会初始化spring容器,spring容器要加载就需要Listener
    //OpenSessionInViewFilter:把Session绑定到线程,不会访问完数据库就关闭会话 没有初始化参数,id=sessionFactory
    //OpenSessionInViewFilter的mapping越放上,会话范围越大
    //引入struts的配置文件

      <context-param> <!--通过 上下文参数 标签  引入spring配置文件-->
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:applicationContext.xml</param-value>
      </context-param>
     

         <!--  当Web容器运行时,会初始化spring容器, 容器加载需要引入ContextLoaderListener -->
      <listener> <!-- 引入上下文加载监听器  才能加载spring容器-->
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
     
        <filter>  <!-- 引入这个过滤器能 管理session  不用考虑开启和关闭会话,  ------开启和提交事务由spring的AOP切面来实现 或者通过注解方式在serviceImpl上方添加@Transactional    -->
            <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>        <!--引入加载struts配置文件的过滤器-->
            <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>

    =============

    struts.xml配置文件

    <?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">
    
    <struts>
    	
    <!--按照类型匹配
    	<constant name="struts.objectFactory.spring.autoWire" value="type"></constant>  -->	
    	
    	<package name="default" namespace="/" extends="struts-default">
    		<action name="login" class="action.UserAction" method="login">
    			<result>/index.jsp</result>		
    			<result name="input">/login.jsp</result>
    		</action>
    	
    	</package>
         
    </struts>
    

      

    =============

    hibernate.cfg.xml 配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
    	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    
    <hibernate-configuration>
    	<session-factory>
    		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    		<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/sql?useUnicode=true&characterEncoding=utf8</property>
    		<property name="hibernate.connection.username">root</property>
    		<property name="hibernate.connection.password">123</property>
    		
    		<property name="hibernate.show_sql">true</property>
    		<property name="hibernate.format_sql">true</property>
    		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    		<property name="hibernate.current_session_context_class">thread</property>
    		
    		<mapping resource="model/User.hbm.xml" />
    		<mapping resource="model/House.hbm.xml" />
    		
    	</session-factory>
    </hibernate-configuration>
    

      


    =========================================================================================

    使用HibernateTemplate模版
    需要在配置文件里 把sessionFacoty注入dao

    spring的api查询
    继承HibernateDaoSupport类
    this.getHibernateTemplate().save(class);
    this.getHibernateTemplate().delete(class);
    this.getHibernateTemplate().get(class);
    this.getHibernateTemplate().update(class);

    this.getHibernateTemplate().evict(null);//清除单个对象缓存
    this.getHibernateTemplate().clear();//清除所有对象缓存

    ----------------------------------------------------------------->
    //用自定义语句做分页查询 (回调)
    this.getHibernateTemplate().execute(new MyCallback(可以传入参数));

    实现HibernateCallback接口的doInHibernate方法
    //className:MyCallback
    Query q = session.createQuery("from..");

    或者写个内部类 new接口的实现类
    List<Object> obj = this.getHibernateTemplate().execute(
        new HibernateCallback<List<Object>>(){
            @Override
            public List<Object> doInHibernate(Session arg0){
                return arg0.createQuery("from ...")
                .setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize)
                .list();
            }
        }
    );

    内部类访问外部方法的参数时,参数需要被常量final修饰
    final int pageNo,final int pageSize


    =====================================================================

    propagation 事务传播行为

    考虑事务 增删改
    required默认值 会融入到第一个事务环境中共同提交事务 如果没有事物环境则会创建事务
    mandatory需要事物环境 没有事务则报异常
    requires_new 优先执行 暂时挂起当前事务 创建一个新事务开始执行
    nested 嵌套事务 事务A中开启事务B 需要数据库支持(在事务b结束后事务a报错 事务b该不该提交)
    不考虑事务 查询
    supports 默认值
    never 不需要事务环境 存在则报异常
    not_supported 优先执行
    -----------------------------
    isolation事务隔离级别
    default默认值 Oracle等同read_commited,Mysql等同repeatable_read
    read_uncommitted 未提交读 级别最低 并发性能最好 用于查询为主  如果有修改,不会提交,直接改数据库
    read_committed 提交读 级别最低要求 提交事务后再修改数据
    repeatable_read 不可重复读
    serializable 安全级别最高
    ------------------------------
    timeout 允许事务运行的最长时间 以秒为单位计算
    ------------------------------
    read-only 事务只读 默认false  
    --------------------------------
    回滚规则
    Throwable的子类:ERROR,EXCEPTION
    ERROR:通常程序导致的,和代码无关
    EXCEPTION的子类:runtimeException,checkedException
    runtimeException:运行时的异常,不会提示要捕捉异常.
    checkedException:受检查的异常,在Exception的子类中除了runtimeException以为的所有子类都是受检查异常,编译时会提示要捕捉的异常是检查异常

    rollback-for : 设定能触发回滚的异常类型
    spring默认在抛出runtimeException运行时异常才会标识事务回滚

    no-rollback-for : 设定不触发回滚的异常类型
    spring默认在抛出checkedException时不会触发事务回滚

    --------------
    Action的实例是由struts的组件创建
    Action会去访问spring的上下文得到它依赖的对象(spring创建的业务bean):

    在spring配置文件中配置action后要接受请求才能创建action 所以要在web.xml中配置如下:
    //这种配置方式不是首选 一般Action还是由Struts创建(即Action写在Struts的配置文件中)
      <listener>
        <listener-class>
              <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
        </listener-class>
      </listener>
      bean---scope="request"
    spring配置文件中--
      <bean id=userAction class="action.UserAction" scope="prototype">
    struts配置文件中action的class是spring配置文件中的beanId--
      <action name="login" class="userAction" method="login">
     
    采用这种配置方式时,Action的实例由spring创建,Struts2插件的工厂类只需根据Action Bean的id查找该组件使用
    这种方式可以为Action进行更灵活的配置,但代价是要在Spring配置文件中定义很多的Action Bean,增加配置工作量
    同样需要添加Struts2.Spring.plugin.xxx.jar文件
     -------------
     流程:
     dataSource->sessionFactory->Dao(HibernateTemplate模版,实现HibernateCallback接口类的doInHibernate方法完成回调)
     -->service(事务参数,传播机制/隔离级别/超时间隔/是否只读/回滚规则)
     -->action控制器(创建在struts配置文件/spring配置文件)

    <bean>的作用域
        (scope=singlton/prototype/request/session)
              singlton单例模式
           prototype多例模式使用一次创建一个bean
     Web作用域-session会和上次请求残余的数据混合
     Web作用域-request一次请求创建一个bean       @常用
               使用request作用域后需要web.xml配置请求上下文监听器RequestContextListener





    ========================================================

    注解实现事务处理

    <context:property-placeholder location="classpath:jdbc.properties">
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${属性文件中对应的键}"></>
        <property ...
    </>
    ----------------------
    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org...</>
            </>
        </>
    ----------------------
    <!--    <property name="annotatedClasses">
            <list>
                <value>model/user</>
                <value>model/house</>
            </>
        </>
    -->
        <property name="packagesToScan">
            <list>
                <value>model</>
            </>
        </>
    </bean>
    --------------------
    @Repository    //标记为数据访问层的组件
    daoimpl extends HibernateDaoSupport
            
    @AutoWired     //通过set方法注入会话工厂,两个相同方法名的set会重写父类set
    public void setSuperSessionFactory(SessionFactory sessionFactory){
        super.setSessionFactory(sessionFactory)
    }
    --------------------
    @Service    //标记为业务层的组件
    @Transactional  //添加事务
    serviceImpl
    private UserDao userDao;

    @AutoWired    //自动装配
    public void setUserDao(UserDao userDao){
        this.userDao=userdao;
    }

    /struts.xml  //不按名字,按类型匹配
    <constant name="struts.objectFactory.spring.autoWire" value="type"></>

    //不需要事务
    @Transactional
    serviceImpl

    @Transactional(propagation=Propagation.SUPPORTS)
    public User checkLogin(...)...

    applicationContext.xml
    <context:component-scan base-package="service,dao"> //Ioc扫描注解
    <aop:aspectj-autoproxy>        //Aop普通织入
    <tx:annotation-driven>        //特别的事务

    //可以把注解标记在接口上,但是只能用接口代理(jdk动态代理)
    //如果写在实现类上,可以用cglib代理(面向具体类型的代理,在运行中会创建子类,对子类用代理)








  • 相关阅读:
    seo课程教程笔记公布【网络转载】
    建立一个windows服务(可用于实现计划任务,事件监控..) .NET
    运行界面上,实现随意拖动控件 .NET
    定时关机的小程序 .NET
    服务 安装与删除 .NET
    模拟鼠标/键盘 .NET实现
    Google Code 创建开源项目
    一个批处理文件 启动停止服务.bat
    提升搜索引擎中网站排名的工具[持续更新中..]
    DateTime.Now.ToString()用法
  • 原文地址:https://www.cnblogs.com/m97i/p/7545942.html
Copyright © 2011-2022 走看看