SSH整合

web+spring+struts+hibernate+杂鱼  --(全部整合)
1、导入所需要的pom依赖
2、几大框架的配置文件(web.xml/struts.xml、hibernate的配置、spring的配置)
3、spring与hibernate整合桥接的配置文件替换掉了hibernate.cfg.xml
     spring-hibernate.xml(难点)
        注册数据库连接信息文件
        配置数据库连接池(新的知识点)
        配置sessionfactory
        配置声明式事务(aop)
            com.zking.base.xxxBiz
            com.zking.book.xxxBiz
            com.zking.book.yyyBiz
            com.zking.*.*Biz
        配置Base模块
4、配置struts.xml
5、做测试
1. pom
  1.1 hibernate相关(5.2.12.Final)
      hibernate-core
      hibernate-c3p0(数据库连接池)
      hibernate-ehcache
      mysql-connector-java(5.1.44)

  1.2 spring相关(5.0.1.RELEASE)
      spring-context
      spring-orm
      spring-web
      spring-aspects

      注:创建spring的XML文件时,需要添加beans/aop/tx/context标签支持

      各依赖说明:
      spring-context
        创建spring上下文

      spring-orm
        org.springframework.orm.hibernate5.LocalSessionFactoryBean
          dataSource:指定数据源
          hibernateProperties:指定hibernate相关属性,如:dialect/show_sql/format_sql 
          mappingResources:指定实体映射文件 
          注1:本章采用将hibernate配置全部交给spring管理,因此项目中不再有hibernate.cfg.xml文件
        org.springframework.orm.hibernate5.HibernateTemplate
        org.springframework.orm.hibernate5.support.HibernateDaoSupport
      测试一:运行测试类Test1,测试hibernate与spring的集成

      spring-web
        org.springframework.web.context.ContextLoaderListener
          contextConfigLocation:classpath:applicationContext-*.xml
        org.springframework.web.context.support.WebApplicationContextUtils
      测试二:访问test2.jsp,测试spring与WEB项目的集成

      spring-aspects
        spring的AspectJ依赖,解析事务切点

  1.3 struts2相关(2.5.13)
      struts2-core
      struts2-spring-plugin
        struts2与spring集成的插件
        将action配置到spring中,struts的action标签的class属性填写spring中bean的名字或id

  1.4 log配置
    1.4.1 log4j(1.X版)
          不建议使用

    1.4.2 log4j2(2.9.1)
          log4j-core
          log4j-api
          log4j-web
          不建议使用

    1.4.3 log4j2 + slf4j(使用ehcache开启hibernate二级缓存必须使用第二种方式配置日志)

    注1:本章使用第三种方式配置日志,即log4j2 + slf4j

  1.5 other
      junit(4.12)
      javax.servlet-api(4.0.0)
  1.6 jstl
      jstl(1.2)
      standard(1.1.2)
  1.7 jsp自定义标签依赖(必须与tomcat的版本一致)
      tomcat-jsp-api

      注1:如何解决项目中不支持EL表达式的问题?将web.xml的DTD的版本由2.3升级到3.0即可。因为web2.3是不支持EL表达式的
2. SSH集成
   2.1 导入ehcache.xml
   2.2 导入log4j2.xml
   2.3 集成hibernate
     2.3.1 注入数据库配置文件
     2.3.2 配置c3p0连接池
     2.3.3 注册LocalSessionFactoryBean
     2.3.4 spring声明式事物

        声明式事务配置
      1) 必须先修改spring配置文件的声明部分,添加对aop标签和tx标签的支持

      2) 配置SessionFactory(spring和hibernate集成时已完成)

      3) 配置事务管理器
          HibernateTransactionManager

      4) 配置事务的传播特性(tx)
              add
              edit
              del
              load|list
          事务传播特性(PROPAGATION_REQUIRED|readOnly)

      5) 配置自动代理
            a) 引用环绕通知txAdvice
            b) 定义一个切入点
              execution(* *..*Biz.*(..))
              a:返回值不限 b:包名不限 c:接口名以Biz结尾 d:方法名及参数不限
            c) 自动代理的原理
          在spring上下文初始化完成以后,自动代理会逐个检查spring上下文中JavaBean实现的接口是否满足自动代理的条件,如果满足条件,则将此bean和通知结合生成一个代理对象,并以此代理对象替换spring上下文中的bean,之后你访问的就是代理对象了

          注1:狸猫换太子

     2.3.5 注册HibernateTemplate
     2.3.6 注册Base模块

3. 程序代码的分层(base模块)
   /base 
      /action
      /biz
      /dao
      /entity
   /book
      /action
      /biz
      /dao
      /entity  

4. 整合案例演示

  4.1 entity
        *.hbm.xml

  4.2 dao
        IXxxDAO
         XxxDAOImpl(继承HibernateDaoSupport类,方便注入HibernateTemplate)
        applicationContext-Xxx.xml
        查询
            this.getHibernateTemplate().execute(

  4.3 biz
        IXxxBiz
         XxxBizImpl
        applicationContext-Xxx.xml

  4.4 test(junit4)

  4.5 action
        将action配置到applicationContext-Xxx.xml,
        注:必须为多例模式(重要)

  struts.xml配置注意事项:
  1)
  <!-- 将action创建交由spring容器来管理 -->
  <constant name="struts.objectFactory" value="spring"></constant>
  
  2)struts-Xxx.xml文件中的action的class属性类型填写spring中的id。

5. web.xml配置

  5.1 Spring上下文ApplicationContext.xml的加载
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

  5.2 启动Web容器时,自动装配ApplicationContext.xml的配置信息
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  5.3 中文乱码过滤器
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  5.4 其他配置
     5.4.1 防止内存泄露、缓存清除监听器
     <listener>
    <listener-class>
        org.springframework.web.util.IntrospectorCleanupListener
    </listener-class>
     </listener>

     5.4.2 用于支持3种Bean的作用域:request,session和globalSession
     <listener>
    <listener-class>            org.springframework.web.context.request.RequestContextListener
    </listener-class>
     </listener>

     5.4.3 把session的关闭延迟到jsp页面显示之后,请配在struts2上面
     <filter>
    <filter-name>OpenSessionInView</filter-name>
    <filter-class>        org.springframework.orm.hibernate5.support.OpenSessionInViewFilter
    </filter-class>
     </filter>
     <filter-mapping>
    <filter-name>OpenSessionInView</filter-name>
    <url-pattern>/*</url-pattern>
     </filter-mapping>
  5.5 Struts2核心过滤器

  (一)  、SSH整合

 

一、搭建SSH项目

建立maven项目

1、web.xml

修改为web3.1.xml配置

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <display-name>Archetype Created Web Application</display-name>
</web-app>

2、pom.xml

导入所需要的pom依赖;记得一步一步来,不要急

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mwy</groupId>
  <artifactId>SSH</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>SSH Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
		<hibernate.version>5.2.12.Final</hibernate.version>
		<mysql.version>8.0.19</mysql.version>
		<spring.version>5.0.1.RELEASE</spring.version>
		<struts2.version>2.5.13</struts2.version>
		<slf4j.version>1.7.7</slf4j.version>
		<log4j2.version>2.9.1</log4j2.version>
		<disruptor.version>3.2.0</disruptor.version>
		<junit.version>4.12</junit.version>
		<javax.servlet.version>4.0.0</javax.servlet.version>
		<jstl.version>1.2</jstl.version>
		<standard.version>1.1.2</standard.version>
		<tomcat-jsp-api.version>8.0.47</tomcat-jsp-api.version>
	</properties>
  
  <dependencies>
    <!-- 1、导入hibernate依赖 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-c3p0</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-ehcache</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		
		<!-- 2、导入spring依赖 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<!-- 3、导入struts2依赖 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>${struts2.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>${struts2.version}</version>
		</dependency>
		
		<!-- 4、导入日志系统依赖 -->
		<!-- log配置:Log4j2 + Slf4j -->
		<!-- slf4j核心包 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
			<scope>runtime</scope>
		</dependency>

		<!--用于与slf4j保持桥接 -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-slf4j-impl</artifactId>
			<version>${log4j2.version}</version>
		</dependency>

		<!--核心log4j2jar包 -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>${log4j2.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>${log4j2.version}</version>
		</dependency>

		<!--web工程需要包含log4j-web,非web工程不需要 -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-web</artifactId>
			<version>${log4j2.version}</version>
			<scope>runtime</scope>
		</dependency>
		<!--需要使用log4j2的AsyncLogger需要包含disruptor -->
		<dependency>
			<groupId>com.lmax</groupId>
			<artifactId>disruptor</artifactId>
			<version>${disruptor.version}</version>
		</dependency>
		
		<!-- 5、other -->
		<!-- 5.1、junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- 5.2、servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${javax.servlet.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 5.3、jstl、standard -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>${standard.version}</version>
		</dependency>

		<!-- 5.4、tomcat-jsp-api -->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jsp-api</artifactId>
			<version>${tomcat-jsp-api.version}</version>
		</dependency>
		
  </dependencies>
  <build>
    <finalName>SSH</finalName>
    
    <plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
    
  </build>
</project>

可以测试一下,是否出错(BUILD SUCCESS  即为成功,没有出错)

 3、导入ehcache.xml和log4j2.xml ...  ...(放在resources中)

①、ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <!--磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存-->
    <!--path:指定在硬盘上存储对象的路径-->
    <!--java.io.tmpdir 是默认的临时文件路径。 可以通过如下方式打印出具体的文件路径 System.out.println(System.getProperty("java.io.tmpdir"));-->
    <diskStore path="java.io.tmpdir"/>


    <!--defaultCache:默认的管理策略-->
    <!--eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断-->
    <!--maxElementsInMemory:在内存中缓存的element的最大数目-->
    <!--overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上-->
    <!--diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false-->
    <!--timeToIdleSeconds:对象空闲时间(单位:秒),指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问-->
    <!--timeToLiveSeconds:对象存活时间(单位:秒),指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问-->
    <!--memoryStoreEvictionPolicy:缓存的3 种清空策略-->
    <!--FIFO:first in first out (先进先出)-->
    <!--LFU:Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存-->
    <!--LRU:Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存-->
    <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
                  timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>


    <!--name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)-->
    <cache name="stuCache" eternal="false" maxElementsInMemory="100"
           overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
           timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/>
</ehcache>

②、导入log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- status : 指定log4j本身的打印日志的级别.ALL< Trace < DEBUG < INFO < WARN < ERROR 
	< FATAL < OFF。 monitorInterval : 用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s. -->
<Configuration status="WARN" monitorInterval="30">
	<Properties>
		<!-- 配置日志文件输出目录 ${sys:user.home} -->
		<Property name="LOG_HOME">/root/workspace/lucenedemo/logs</Property>
		<property name="ERROR_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/error</property>
		<property name="WARN_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/warn</property>
		<property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n</property>
	</Properties>

	<Appenders>
		<!--这个输出控制台的配置 -->
		<Console name="Console" target="SYSTEM_OUT">
			<!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
			<ThresholdFilter level="trace" onMatch="ACCEPT"
				onMismatch="DENY" />
			<!-- 输出日志的格式 -->
			<!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称 
				%m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M 
				: 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 -->
			<PatternLayout pattern="${PATTERN}" />
		</Console>

		<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 -->
		<!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->
		<File name="log" fileName="logs/test.log" append="false">
			<PatternLayout
				pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
		</File>
		<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size, 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
		<RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"
			filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
			<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
			<ThresholdFilter level="info" onMatch="ACCEPT"
				onMismatch="DENY" />
			<PatternLayout
				pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
			<Policies>
				<!-- 基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。 modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am. -->
				<!-- 关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval, 日期格式精确到哪一位,interval也精确到哪一个单位 -->
				<!-- log4j2的按天分日志文件 : info-%d{yyyy-MM-dd}-%i.log -->
				<TimeBasedTriggeringPolicy interval="1"
					modulate="true" />
				<!-- SizeBasedTriggeringPolicy:Policies子节点, 基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小. -->
				<!-- <SizeBasedTriggeringPolicy size="2 kB" /> -->
			</Policies>
		</RollingFile>

		<RollingFile name="RollingFileWarn" fileName="${WARN_LOG_FILE_NAME}/warn.log"
			filePattern="${WARN_LOG_FILE_NAME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
			<ThresholdFilter level="warn" onMatch="ACCEPT"
				onMismatch="DENY" />
			<PatternLayout
				pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
			<Policies>
				<TimeBasedTriggeringPolicy />
				<SizeBasedTriggeringPolicy size="2 kB" />
			</Policies>
			<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
			<DefaultRolloverStrategy max="20" />
		</RollingFile>

		<RollingFile name="RollingFileError" fileName="${ERROR_LOG_FILE_NAME}/error.log"
			filePattern="${ERROR_LOG_FILE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH-mm}-%i.log">
			<ThresholdFilter level="error" onMatch="ACCEPT"
				onMismatch="DENY" />
			<PatternLayout
				pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
			<Policies>
				<!-- log4j2的按分钟 分日志文件 : warn-%d{yyyy-MM-dd-HH-mm}-%i.log -->
				<TimeBasedTriggeringPolicy interval="1"
					modulate="true" />
				<!-- <SizeBasedTriggeringPolicy size="10 MB" /> -->
			</Policies>
		</RollingFile>

	</Appenders>

	<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->
	<Loggers>
		<!--过滤掉spring和mybatis的一些无用的DEBUG信息 -->
		<logger name="org.springframework" level="INFO"></logger>
		<logger name="org.mybatis" level="INFO"></logger>

		<!-- 第三方日志系统 -->
		<logger name="org.springframework" level="ERROR" />
		<logger name="org.hibernate" level="ERROR" />
		<logger name="org.apache.struts2" level="ERROR" />
		<logger name="com.opensymphony.xwork2" level="ERROR" />
		<logger name="org.jboss" level="ERROR" />


		<!-- 配置日志的根节点 -->
		<root level="all">
			<appender-ref ref="Console" />
			<appender-ref ref="RollingFileInfo" />
			<appender-ref ref="RollingFileWarn" />
			<appender-ref ref="RollingFileError" />
		</root>

	</Loggers>

</Configuration>

③、spring-context.xml

里面管理所有的javabean

<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 配置与hibernate整合相关的javabean -->
	<import resource="spring-hibernate.xml" />
<!-- 	关于书籍管理相关的javabean -->
	<import resource="spring-book.xml" />
</beans>

④、spring-hibernate.xml

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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<!-- 1、注册jdbc相关的配置文件 -->
	<context:property-placeholder location="classpath:db.properties" />
	<!-- 2、配置数据库连接池C3P0 -->
	<!-- 注册数据库连接文件db.properties -->
	<!-- <context:property-placeholder location="classpath:db.properties" /> -->
	

	<!-- 配置c3p0连接池 (别的连接池dbcp2、Druid)-->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${db.username}"></property>
		<property name="password" value="${db.password}"></property>
		<property name="driverClass" value="${db.driverClass}"></property>
		<property name="jdbcUrl" value="${db.jdbcUrl}"></property>

		<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
		<property name="initialPoolSize" value="${db.initialPoolSize}"></property>
		<!--连接池中保留的最大连接数。Default: 15 -->
		<property name="maxPoolSize" value="${db.maxPoolSize}"></property>
		<!--连接池中保留的最小连接数。 -->
		<property name="minPoolSize" value="${db.minPoolSize}" />
		<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
		<property name="maxIdleTime" value="${db.maxIdleTime}" />

		<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
		<property name="acquireIncrement" value="${db.acquireIncrement}" />

		<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。 
			所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 
			0 -->
		<property name="maxStatements" value="${db.maxStatements}" />

		<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
		<property name="idleConnectionTestPeriod" value="${db.idleConnectionTestPeriod}" />

		<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
		<property name="acquireRetryAttempts" value="${db.acquireRetryAttempts}" />

		<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。 
			如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
		<property name="breakAfterAcquireFailure" value="${db.breakAfterAcquireFailure}" />

		<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod 
			或automaticTestTable 等方法来提升连接测试的性能。Default: false -->
		<property name="testConnectionOnCheckout" value="${db.breakAfterAcquireFailure}" />
	</bean>

	<!-- 3、配置sessionfactory相关信息 -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<!-- 数据源 -->
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<!-- hibernate相关属性 -->
		<property name="hibernateProperties">
			<props>
				<prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!--spring与Hibernate集成无法显示sql语句问题,请见集成后hibernate无法显示sql语句.txt -->
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
			</props>
		</property>
		<!-- 实体映射文件 -->
		<property name="mappingResources">
			<list>
				<value>com/mwy/book/entity/Book.hbm.xml</value>
			</list>
		</property>
	</bean>

	<!-- 4、配置事务 -->
	<!--声明式事务配置开始 -->
	<!-- 
		静态代理:
			一个代理对象->一个目标对象
			BookProxy(BookBizImpl+myMethodBeforeAdvice)->bookBiz
			OrderProxy(OrderBizImpl+myMethodBeforeAdvice2)->	OrderBiz
		
		动态代理:
			一个代理对象->多个目标对象
	 -->
	
	<!--1) 开启自动代理 -->
	<aop:aspectj-autoproxy />

	<!--2) 事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<!--3) 定义事务特性 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />

			<tx:method name="edit*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />

			<tx:method name="del*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />

			<tx:method name="load*" propagation="REQUIRED" read-only="true" />
			<tx:method name="list*" propagation="REQUIRED" read-only="true" />
			<tx:method name="select*" propagation="REQUIRED" read-only="true" />
			<tx:method name="query*" propagation="REQUIRED" read-only="true" />

			<tx:method name="do*" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>

	<!--4) 定义切入点 -->
	<aop:config>
		<!-- pointcut属性用来定义一个切入点,分成四个部分理解 [* ][*..][*Biz][.*(..)] -->
		<!-- A: 返回类型,*表示返回类型不限 -->
		<!-- B: 包名,*..表示包名不限 -->
		<!-- C: 类或接口名,*Biz表示类或接口必须以Biz结尾 -->
		<!-- D: 方法名和参数,*(..)表示方法名不限,参数类型和个数不限 -->
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Biz.*(..))" />
	</aop:config>
	<!-- 声明式事务配置结束 -->

	<!-- 5、配置HibernateTemplate   相当于BaseDao-->
	<bean class="org.springframework.orm.hibernate5.HibernateTemplate" id="hibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	<!-- 6、分模块开发(只配置base模块) -->
	<bean class="com.mwy.base.entity.BaseEntity" abstract="true" id="baseEntity"></bean>
	<bean class="com.mwy.base.dao.BaseDao" abstract="true" id="baseDao" >
		<property name="hibernateTemplate" ref="hibernateTemplate"></property>
	</bean>
	<bean class="com.mwy.base.biz.BaseBiz" abstract="true" id="baseBiz"></bean>
	<bean class="com.mwy.base.web.BaseAction" abstract="true" id="baseAction"></bean>
</beans>

加入db.properties 

配置数据库连接池C3P0,数据库连接文件db.properties

db.username=root
db.password=123456
db.driverClass=com.mysql.cj.jdbc.Driver
db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=true
#db.username=root
#db.password=123456
#db.driverClass=com.mysql.jdbc.Driver
#db.jdbcUrl=jdbc:mysql://47.100.191.44:3308/lx?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
db.initialPoolSize=10
db.maxPoolSize=20
db.minPoolSize=5
db.maxIdleTime=60
db.acquireIncrement=5
db.maxStatements=0
db.idleConnectionTestPeriod=60
db.acquireRetryAttempts=30
db.breakAfterAcquireFailure=true
db.testConnectionOnCheckout=false

⑤、struts-base.xml、struts-sy.xml、struts.xml

配置注意事项:

 (1)<!-- 将action创建交由spring容器来管理 -->

  <constant name="struts.objectFactory" value="spring"></constant>

(2)struts-Xxx.xml文件中的action的class属性类型填写spring中的id。

struts-base.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<constant name="struts.i18n.encoding" value="UTF-8" />
	<constant name="struts.devMode" value="true" />
	<constant name="struts.configuration.xml.reload" value="true" />
	<constant name="struts.i18n.reload" value="true" />
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />

	<package name="base" extends="struts-default" abstract="true">
		<global-allowed-methods>regex:.*</global-allowed-methods>
	</package>
</struts>

struts-sy.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<package name="sy" extends="base" namespace="/sy">
		 <action name="bookAction_*" class="bookAction" method="{1}">
		 	 <result name="toAdd">/add.jsp</result>
		 	 <result name="add">/index.jsp</result>
		 </action>
	</package>
</struts>

struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<include file="struts-default.xml"></include>
	<include file="struts-base.xml"></include>
	<include file="struts-sy.xml"></include>
</struts>

4、web.xml配置

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <display-name>Archetype Created Web Application</display-name>
  
  <!-- 1、整合spring -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring-context.xml</param-value>
	</context-param>
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<!-- 2、整合struts2 -->
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>
			org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>

	<!-- 3、添加过滤器 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<async-supported>true</async-supported>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

5、 将所有包建好(Ctrl+Shift+o  导包)

①、BaseEntity 

package com.mwy.base.entity;
import java.io.Serializable;
public class BaseEntity implements Serializable{

	private static final long serialVersionUID = -5475556860252527343L;

}

②、BaseDao 

package com.mwy.base.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import com.mwy.base.util.PageBean;
public class BaseDao extends HibernateDaoSupport implements Serializable{

	private static final long serialVersionUID = 5427369434249665701L;
	
	public void setParam(Query query,Map<String, Object> map) {
		if(map == null || map.size() < 1) {
			return;
		}
		Object value = null;
		for(Map.Entry<String, Object> entry:map.entrySet()) {
			value = entry.getValue();
			if(value instanceof Collection) {
				query.setParameterList(entry.getKey(), (Collection) value);
			}else if(value instanceof Object[]) {
				query.setParameterList(entry.getKey(), (Object[]) value);
			}else {
				query.setParameter(entry.getKey(), value);
			}
		}
	}
	public String getCountHql(String hql) {
		int index = hql.toUpperCase().indexOf("FROM");
		return "select count(*) "+hql.substring(index);
	}
	
	/**
	 * 
	 * @param hql	已经拼装好的
	 * @param map
	 * @param pageBean
	 * @return
	 */
	public List executeQuery(Session session, String hql,Map<String, Object> map,PageBean pageBean) {
		if(pageBean !=null && pageBean.isPagination()) {
			String countHql = getCountHql(hql);
			Query countQuery = session.createQuery(countHql);
			this.setParam(countQuery, map);
			pageBean.setTotal(countQuery.getSingleResult().toString());
			
			Query query = session.createQuery(hql);
			this.setParam(query, map);
			query.setFirstResult(pageBean.getStartIndex());
			query.setMaxResults(pageBean.getRows());
			List list = query.list();
			
			return list;
		}else {
			Query query = session.createQuery(hql);
			this.setParam(query, map);
			List list = query.list();
			
			return list;
		}	
	}
}

③、PageBean 

package com.mwy.base.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 * 分页工具类
 *
 */
public class PageBean {

	private int page = 1;// 页码

	private int rows = 10;// 页大小

	private int total = 0;// 总记录数

	private boolean pagination = true;// 是否分页
	
	private String url; //保存上一次请求的URL
	
	private Map<String,String[]> paramMap = new HashMap<>();// 保存上一次请求的参数
	
	/**
	 * 初始化pagebean的,保存上一次请求的重要参数
	 * @param req
	 */
	public void setRequest(HttpServletRequest req) {
//		1.1	需要保存上一次请求的URL
		this.setUrl(req.getRequestURL().toString());
//		1.2	需要保存上一次请求的参数	bname、price
		this.setParamMap(req.getParameterMap());
//		1.3	需要保存上一次请求的分页设置	pagination
		this.setPagination(req.getParameter("pagination"));
//		1.4	需要保存上一次请求的展示条目数
		this.setRows(req.getParameter("rows"));
//		1.5  初始化请求的页码	page
		this.setPage(req.getParameter("page"));
	}
	
	public void setPage(String page) {
		if(StringUtils.isNotBlank(page))
			this.setPage(Integer.valueOf(page));
	}

	public void setRows(String rows) {
		if(StringUtils.isNotBlank(rows))
			this.setRows(Integer.valueOf(rows));
	}

	public void setPagination(String pagination) {
//		只有在前台jsp填写了pagination=false,才代表不分页
		if(StringUtils.isNotBlank(pagination))
			this.setPagination(!"false".equals(pagination));
	}


	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Map<String, String[]> getParamMap() {
		return paramMap;
	}

	public void setParamMap(Map<String, String[]> paramMap) {
		this.paramMap = paramMap;
	}



	public PageBean() {
		super();
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}

	public boolean isPagination() {
		return pagination;
	}

	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}

	/**
	 * 获得起始记录的下标
	 * 
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}
	
	/**
	 * 最大页
	 * @return
	 */
	public int maxPage() {
//		total % rows == 0 ? total / rows : total / rows +1
		return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows + 1;
	}
	
	/**
	 * 下一页
	 * @return
	 */
	public int nextPage() {
//		如果当前页小于最大页,那就下一页为当前页+1;如果不小于,说明当前页就是最大页,那就无需+1
		return this.page < this.maxPage() ? this.page + 1 : this.page;
	}
	
	/**
	 * 上一页
	 * @return
	 */
	public int previousPage() {
		return this.page > 1 ? this.page - 1 : this.page;
	}

	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
	}
}

④、StringUtils 

package com.mwy.base.util;
public class StringUtils {
	// 私有的构造方法,保护此类不能在外部实例化
	private StringUtils() {
	}
	/**
	 * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isBlank(String s) {
		boolean b = false;
		if (null == s || s.trim().equals("")) {
			b = true;
		}
		return b;
	}
	/**
	 * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isNotBlank(String s) {
		return !isBlank(s);
	}
}

⑤、BaseBiz 

package com.mwy.base.biz;
public interface BaseBiz {
}

⑥、BaseAction 

package com.mwy.base.web;
import java.io.Serializable;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
public class BaseAction implements ServletRequestAware, ServletResponseAware,Serializable{
	private static final long serialVersionUID = -7110462505161900879L;
	/**
	 * 为了传值使用
	 */
	protected HttpServletResponse response;
	protected HttpServletRequest request;
	protected HttpSession session;
	protected ServletContext application;
	
	/**
	 * 为了配置跳转页面所用
	 */
	protected final static String SUCCESS = "success";
	protected final static String FAIL = "fail";
	protected final static String LIST = "list";
	protected final static String ADD = "add";
	protected final static String EDIT = "edit";
	protected final static String DETAIL = "detail";
	
	/**
	 * 具体传值字段	后端向jsp页面传值所用字段
	 */
	protected Object result;
	protected Object msg;
	protected int code;

	public Object getResult() {
		return result;
	}

	public Object getMsg() {
		return msg;
	}

	public int getCode() {
		return code;
	}

	@Override
	public void setServletResponse(HttpServletResponse arg0) {
		this.response = arg0;
		
	}

	@Override
	public void setServletRequest(HttpServletRequest arg0) {
		this.request = arg0;
		this.session = arg0.getSession();
		this.application = arg0.getServletContext();
	}
}

配置环境到现在都已经构建好了

二、整合测试

使用书籍表举例

1、将表描述为实体类,配置相关的映射文件

①、实体类   Book 

package com.mwy.book.entity;
import com.mwy.base.entity.BaseEntity;
public class Book extends BaseEntity{
	private Integer bid;
	private String bname;
	private Float price;

	public Integer getBid() {
		return bid;
	}

	public void setBid(Integer bid) {
		this.bid = bid;
	}

	public String getBname() {
		return bname;
	}

	public void setBname(String bname) {
		this.bname = bname;
	}

	public Float getPrice() {
		return price;
	}

	public void setPrice(Float price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
	}

}

映射文件

<?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 table="t_mvc_book" name="com.mwy.book.entity.Book">
		<id name="bid" type="java.lang.Integer" column="bid">
			<generator class="increment"></generator>
		</id>
		
		<property name="bname" type="java.lang.String" column="bname"></property>
		<property name="price" type="java.lang.Float" column="price"></property>
	</class>
</hibernate-mapping>

2、dao层

增删改都可,查询有点复杂(没那么方便)

①、BookDao 

package com.mwy.book.dao;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate5.HibernateCallback;
import com.mwy.base.dao.BaseDao;
import com.mwy.book.entity.Book;

/**
 * 注意:
 * 	1、一定要继承BaseDao(是为了获取到hibernateTemplete)
 * 	2、方法命名有讲究(一定要符合声明式事务所定义的规则)
 * 		若是不遵循规则,那么数据是不会提交到数据库
 * 	3、hibernateTemplete模板在执行查询的时候比较特殊
 * @author Administrator
 *
 */
public class BookDao extends BaseDao {

	public int add(Book book) {
		return (int) getHibernateTemplate().save(book);
	}
	
	public void edit(Book book) {
		getHibernateTemplate().update(book);
	}
	
	public void del(Book book) {
		getHibernateTemplate().delete(book);
	}
	
	public List<Book> list(){
		return (List<Book>) getHibernateTemplate().execute(new HibernateCallback<List<Book>>() {
			@Override
			public List<Book> doInHibernate(Session session) throws HibernateException {
				return session.createQuery("from Book").list();
			}
		});
	}
}

3、service层

①、BookBiz 

package com.mwy.book.biz;
import java.util.List;
import com.mwy.book.dao.BookDao;
import com.mwy.book.entity.Book;
public interface BookBiz {
	public void add(Book book);
	public List<Book> list();
}

②、BookBizImpl 

package com.mwy.book.biz.impl;
import java.util.List;
import com.mwy.book.biz.BookBiz;
import com.mwy.book.dao.BookDao;
import com.mwy.book.entity.Book;
public class BookBizImpl implements BookBiz{
	private BookDao bookDao;
	public BookDao getBookDao() {
		return bookDao;
	}
	public void setBookDao(BookDao bookDao) {
		this.bookDao = bookDao;
	}
	@Override
	public void add(Book book) {
		bookDao.add(book);
	}
	@Override
	public List<Book> list() {
		return bookDao.list();
	}
}

4、Action层

①、BookAction 

package com.mwy.book.web;
import java.util.List;
import com.mwy.base.web.BaseAction;
import com.mwy.book.biz.BookBiz;
import com.mwy.book.entity.Book;
public class BookAction extends BaseAction {
	private Book book;

	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	private static final long serialVersionUID = 1L;
	private BookBiz bookBiz;

	public BookBiz getBookBiz() {
		return bookBiz;
	}

	public void setBookBiz(BookBiz bookBiz) {
		this.bookBiz = bookBiz;
	}

	public String add() {
//		http://localhost:8080/SSH/sy/bookAction_add.action?book.bid=131418&&book.bname=zs&&book.price=1
		this.bookBiz.add(book);
		return "success";
	}
	
	public String list() {
//		http://localhost:8080/SSH/sy/bookAction_list.action
		List<Book> list = this.bookBiz.list();
		for (Book b : list) {
			System.out.println(b);
		}
		return "success";
	}
}

3、struts配置 

①、struts-sy.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<package name="sy" extends="base" namespace="/sy">
		 <action name="bookAction_*" class="bookAction" method="{1}">
		 	 <result name="toAdd">/add.jsp</result>
		 	 <result name="add">/index.jsp</result>
		 </action>
	</package>
</struts>

6、配置(spring-hibernate.xml、spring-模块.xml)

<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<bean class="com.mwy.book.dao.BookDao" parent="baseDao" id="bookDao">
	</bean>
	<bean class="com.mwy.book.biz.impl.BookBizImpl" parent="baseBiz"
		id="bookBiz">
		<property name="bookDao" ref="bookDao"></property>
	</bean>
	<bean class="com.mwy.book.web.BookAction" id="bookAction"
		parent="baseAction">
		<property name="bookBiz" ref="bookBiz"></property>
	</bean>
</beans>

7、测试查询所有和增加的结果

①、查询链接

http://localhost:8080/SSH/sy/bookAction_list.action

结果

②、增加 

增加链接

http://localhost:8080/SSH/sy/bookAction_add.action?book.bid=11111&&book.bname=mwy&&book.price=199

结果:

未增加前数据:

 增加后

 结束!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值