spring之SSH

spring之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)
配置Base模块
4、配置struts.xml
5、做测试
配置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>

pom.xml配置依赖包:

<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.lzy</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>5.1.44</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>

  1. SSH集成
    2.1 导入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>

2.2 导入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>

2.3 导入db.properties

db.username=root
db.password=123
db.driverClass=com.mysql.jdbc.Driver
db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/demo?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

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

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

2.6 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="/book_*" class="bookAction" method="{1}">
          <result name="success">/index.jsp</result>
 </action>
 </package>
</struts>

2.7 集成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:task="http://www.springframework.org/schema/task"
 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/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
      <!-- hibernate.cfg.xml -->
     <!-- 1 . 注册数据库连接信息文件db.properties -->
     <context:property-placeholder location="classpath:db.properties" />
     <!-- 2 . 配置数据库连接池 (数据源) c3p0、dbcp2、druid -->
     <!-- 注册数据库连接文件db.properties -->
 <!-- 配置c3p0连接池 -->
 <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/lzy/book/entity/Book.hbm.xml</value>
   </list>
  </property>
 </bean>
     <!-- 4 . 获取session (hibernateTemplete)  -->
     <bean class="org.springframework.orm.hibernate5.HibernateTemplate" id="hibernateTemplate">
  <property name="sessionFactory" ref="sessionFactory"></property>
 </bean>
     <!-- 5 . 配置事务 -->
     <!-- 
            采取了动态代理
            静态代理与动态代理的区别
            静态代理 : 一个代理对象只能代理一个目标 (代理=目标+连接点+通知)
            动态代理 : 一个代理能够代理多个目标 (代理=目标+切面+通知)
                               切面是连接点的集合
      -->
      <!--声明式事务配置开始 -->
 <!-- 
  静态代理:
   一个代理对象->一个目标对象
   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>
 <!-- 声明式事务配置结束 -->
     <!-- 6 . 配置基础模块 -->
     <bean class="com.lzy.base.entity.BaseEntity" abstract="true" id="baseEntity"></bean>
 <bean class="com.lzy.base.dao.BaseDao" abstract="true" id="baseDao" >
  <property name="hibernateTemplate" ref="hibernateTemplate"></property>
 </bean>
 <bean class="com.lzy.base.biz.BaseBiz" abstract="true" id="baseBiz"></bean>
 <bean class="com.lzy.base.web.BaseAction" abstract="true" id="baseAction"></bean>
</beans>

2.8web.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>

SSH整合之增删改查
** 程序代码的分层(base模块)**
/base

/action

/biz

/dao

/entity

/book

/action

/biz

/dao

/entity
展示如下:

BaseBiz.java

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

BaseDao.java

package com.lzy.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.lzy.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;
  }
 }
}

BaseEntity.java

package com.lzy.base.entity;
import java.io.Serializable;
public class BaseEntity implements Serializable{
 private static final long serialVersionUID = -1996534913984010162L;
}

PageBean.java

package com.lzy.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 String url;  //保留上一次的请求地址
 private Map<String, String[]> pMap=new HashMap<>();  //保留上一次请求所携带的参数
 /**
  * PageBean 初始化方法
  */
 public void setRequest(HttpServletRequest req) {
  this.setPage(req.getParameter("page")); 
  this.setRows(req.getParameter("rows")); 
  this.setPagination(req.getParameter("pagination"));   
  // getRequestURL获取到浏览器请求的全路径  
  this.setUrl(req.getRequestURL().toString());   
  // getParameterMap可以获取到一次url请求所携带的所有参数   
  this.setpMap(req.getParameterMap());  
  }
 public void setPagination(String parameter) {
  if("false".equals(parameter)) {
   this.setPagination(false);
  }
 }
 /**
  * 改变数据
  * @param parameter
  */
 public void setRows(String rows) {
        if(StringUtils.isNotBlank(rows)) {
         this.setRows(Integer.valueOf(rows));
        }
 }
 /**
  * 改变它的第几页数据
  * @param parameter
  */
 public void setPage(String page) {
  if(StringUtils.isNotBlank(page)) {
   this.setPage(Integer.valueOf(page));
     }
 }
 public String getUrl() {
  return url;
 }
 public void setUrl(String url) {
  this.url = url;
 }
 public Map<String, String[]> getpMap() {
  return pMap;
 }
 public void setpMap(Map<String, String[]> pMap) {
  this.pMap = pMap;
 }
 private boolean pagination = true;// 是否分页
 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;
 }
 @Override
 public String toString() {
  return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
 }
 /**
  * 获取最大页码
  */
 public int getMaxPage() {
  return this.total%this.rows==0?this.total/this.rows:this.total/this.rows+1;
 }
 /**
  * 获取下一页页码
  * @return
  */
 public int getNextPage() {
  return this.page<this.getMaxPage()?this.page+1:this.page;
 }
 /**
  * 获取上一页码
  * @return
  */
 public int getPreviousPage() {
  return this.page>1?this.page-1:this.page;
 }
}

ResponseUtil.java

package com.lzy.base.util;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
public class ResponseUtil {
 public static void write(HttpServletResponse response,Object o)throws Exception{
  response.setContentType("text/html;charset=utf-8");
  PrintWriter out=response.getWriter();
  out.println(o.toString());
  out.flush();
  out.close();
 }
}

StringUtils.java

package com.lzy.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);
  }
}

BaseAction.java

package com.lzy.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{
 /**
  * 为了传值使用
  */
 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();
 }
}

BookBiz.java

package com.lzy.book.biz;
import java.util.List;
import com.lzy.base.util.PageBean;
import com.lzy.book.entity.Book;
public interface BookBiz {
 public void add(Book book);
 public void del(Book book);
 public void edit(Book book) ;
 public List<Book> list(Book book,PageBean pageBean) throws Exception;
}

BookBizImpl.java

package com.lzy.book.biz;
import java.util.List;
import com.lzy.base.util.PageBean;
import com.lzy.book.dao.BookDao;
import com.lzy.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) {
  this.bookDao.add(book);
 }
 @Override
 public void del(Book book) {
  this.bookDao.del(book);
 }
 @Override
 public void edit(Book book) {
  this.bookDao.edit(book);
 }
 @Override
 public List<Book> list(Book book, PageBean pageBean) throws Exception {
  return this.bookDao.list(book, pageBean);
 }
}

BookDao.java

package com.lzy.book.dao;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate5.HibernateCallback;
import com.lzy.base.dao.BaseDao;
import com.lzy.base.util.PageBean;
import com.lzy.book.entity.Book;
public class BookDao extends BaseDao{
 private static final long serialVersionUID = 1L;
 public void add(Book book) {
  this.getHibernateTemplate().save(book);
 }
 public void del(Book book) {
  this.getHibernateTemplate().delete(book);
 }
 public void edit(Book book) {
  this.getHibernateTemplate().update(book);
 }
 public List<Book> list(Book book,PageBean pageBean) throws Exception{
  BaseDao baDao=super.getClass().newInstance();
  return this.getHibernateTemplate().execute(new HibernateCallback<List<Book>>() {
   @Override
   public List<Book> doInHibernate(Session session) throws HibernateException {
    String hql="from Book";
    return baDao.executeQuery(session, hql, null, pageBean);
   }
  });
 }
}

Book.java

package com.lzy.book.entity;
import com.lzy.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 + "]";
 }
}

Book.hbm.xml

<?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_book" name="com.lzy.book.entity.Book">
  <id name="bid" type="java.lang.Integer" column="bid">
   <generator class="native"></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>

BookAction.java

package com.lzy.book.web;
import java.util.List;
import com.opensymphony.xwork2.ModelDriven;
import com.lzy.base.web.BaseAction;
import com.lzy.book.biz.BookBiz;
import com.lzy.book.entity.Book;
public class BookAction extends BaseAction implements ModelDriven<Book>{
 private static final long serialVersionUID = -6501568498112216443L;
 private BookBiz bookBiz;
 private Book book=new Book();
 public BookBiz getBookBiz() {
  return bookBiz;
 }
 public void setBookBiz(BookBiz bookBiz) {
  this.bookBiz = bookBiz;
 }
 public String list() {
  try {
   List<Book> bok= this.bookBiz.list(book, null);
   for (Book book : bok) {
    System.out.println(bok);
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  return SUCCESS;
 }
 public String add() {
  this.bookBiz.add(book);
  return SUCCESS;
 }
 public String del() {
  this.bookBiz.del(book);
  return SUCCESS;
 }
 public String edit() {
  this.bookBiz.edit(book);
  return SUCCESS;
 }
 @Override
 public Book getModel() {
  return book;
 }
}

spring-context.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:task="http://www.springframework.org/schema/task"
 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/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
     <!-- spring与hibernate整合的配置文件 -->
     <import resource="spring-hibernate.xml"/>
     <!-- 分模块开发的书籍模块  book模块 -->
     <import resource="spring-book.xml"/>
</beans>

分模块开发的书籍模块spring-book.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:task="http://www.springframework.org/schema/task"
 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/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
   <bean class="com.lzy.book.dao.BookDao" id="bookDao" parent="baseDao"></bean>
  <bean class="com.lzy.book.biz.BookBizImpl" id="bookBiz" parent="baseBiz">
             <property name="bookDao" ref="bookDao"></property>
  </bean>
  <bean class="com.lzy.book.web.BookAction" id="bookAction" parent="baseAction">
             <property name="bookBiz" ref="bookBiz"></property>
  </bean>
</beans>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值