java框架之Spring(4)-Spring整合Hibernate和Struts2

準備

導包

Struts2

導入 Struts2 zip 包解壓目錄下 'apps/struts-blank.war' 中全部 jar 包,以下:html

asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
commons-fileupload-1.4.jar
commons-io-2.2.jar
commons-lang3-3.2.jar
freemarker-2.3.28.jar
javassist-3.11.0.GA.jar
log4j-api-2.3.jar # 可選
log4j-core-2.3.jar # 可選
ognl-3.0.21.jar
struts2-core-2.3.37.jar
xwork-core-2.3.37.jar

另外導入 lib 下以下包:java

struts2-convention-plugin-2.3.37.jar # Struts2 註解開發包
struts2-json-plugin-2.3.37.jar # Struts2 內置 Json 序列化支持包
struts2-spring-plugin-2.3.37.jar # Struts2 整合 Spring 包

Hibernate

首先是 Hibernate 開發的必須包,即 Hibernate zip 包 解壓目錄下 'lib/required' 下全部的包,以下:mysql

antlr-2.7.7.jar
dom4j-1.6.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar

Strut2 和 Hibernate 都引入了一個相同的 jar 包 javassisit,整合時必須只保留一個。web

還需導入日誌記錄包spring

log4j-1.2.16.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.7.2.jar

若是使用這裏的日誌記錄包,那麼 Struts2 包中兩個可選日誌記錄包就不須要引入。sql

若是 Hibernate 要使用 C3P0 鏈接池,還需引入 'lib\optional\c3p0' 下全部包,以下:數據庫

c3p0-0.9.2.1.jar
hibernate-c3p0-5.0.7.Final.jar
mchange-commons-java-0.2.3.4.jar

固然,使用 Hibernate 還須要數據庫驅動包,這裏我使用 MySQL 驅動包express

mysql-connector-java-5.1.7-bin.jar

Spring

使用 IoC 需引入的包:apache

com.springsource.org.apache.commons.logging-1.1.1.jar
com.springsource.org.apache.log4j-1.2.15.jar
spring-beans-4.2.4.RELEASE.jar
spring-context-4.2.4.RELEASE.jar
spring-core-4.2.4.RELEASE.jar
spring-expression-4.2.4.RELEASE.jar

使用 AOP 需引入的包:json

com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aop-4.2.4.RELEASE.jar
spring-aspects-4.2.4.RELEASE.jar

使用 JDBC 模板需引入的包:

spring-jdbc-4.2.4.RELEASE.jar
spring-tx-4.2.4.RELEASE.jar

使用事務管理需引入的包:

spring-tx-4.2.4.RELEASE.jar

整合 web 項目需引入的包:

spring-web-4.2.4.RELEASE.jar

整合單元測試測試需引入的包:

spring-test-4.2.4.RELEASE.jar

整合 ORM 框架 Hibernate 需引入的包:

spring-orm-4.2.4.RELEASE.jar

上述完整 jar 包下載

配置

Struts2

配置 Struts2 的核心過濾器:

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
WEB-INF/web.xml

引入 Struts2 核心配置文件:

<?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>
    <package name="test" extends="struts-default" namespace="/">

    </package>
</struts>
struts.xml

Hibernate

引入核心配置文件:

<?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:///test</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <!-- 配置Hibernate的方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 可選配置================ -->
        
        <!-- 打印SQL -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL -->
        <property name="hibernate.format_sql">true</property>
        <!-- 自動建立表 -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 配置C3P0鏈接池 -->
        <property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
        <!--在鏈接池中可用的數據庫鏈接的最少數目 -->
        <property name="c3p0.min_size">5</property>
        <!--在鏈接池中全部數據庫鏈接的最大數目  -->
        <property name="c3p0.max_size">20</property>
        <!--設定數據庫鏈接的過時時間,以秒爲單位,
        若是鏈接池中的某個數據庫鏈接處於空閒狀態的時間超過了timeout時間,就會從鏈接池中清除 -->
        <property name="c3p0.timeout">120</property>
        <!--每3000秒檢查全部鏈接池中的空閒鏈接 以秒爲單位-->
        <property name="c3p0.idle_test_period">3000</property>
    </session-factory>
</hibernate-configuration>
hibernate.cfg.xml

Spring

配置 Spring 的核心監聽器:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--默認狀況下 Spring 會查找路徑爲 WEB-INF/applicationContext.xml 的配置文件,經過以下配置,讓 Spring 在 classpath 下查找-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
WEB-INF/web.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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    
    <!-- Spring整合Hibernate -->
    <!-- 引入Hibernate的配置的信息=============== -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- 引入hibernate的配置文件 -->
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    </bean>

    <!-- 配置事務管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <!-- 開啓註解事務 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
applicationContext.xml

Log4j 配置:

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###
# error warn info debug trace
log4j.rootLogger= info, stdout
log4j.properties

代碼

package com.zze.domain;

public class User {
    private Integer id;
    private String name;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
com.zze.domain.User
package com.zze.dao;

import com.zze.domain.User;

public interface UserDao {
    void save(User user);
}
com.zze.dao.UserDao
package com.zze.dao.impl;

import com.zze.dao.UserDao;
import com.zze.domain.User;

public class UserDaoImpl implements UserDao {
    @Override
    public void save(User user) {
    }
}
com.zze.dao.impl.UserDaoImpl
package com.zze.service;

import com.zze.domain.User;

public interface UserService {
    void save(User user);
}
com.zze.service.UserService
package com.zze.service.impl;

import com.zze.dao.UserDao;
import com.zze.domain.User;
import com.zze.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save(User user) {
        userDao.save(user);
    }
}
com.zze.service.impl.UserServiceImpl
package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }
}
com.zze.web.action.UserAction
<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean name="userService" class="com.zze.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl">
    </bean>
</beans>
applicationContext.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>
    <package name="test" extends="struts-default" namespace="/">
        <action name="customer_*" class="com.zze.web.action.UserAction" method="{1}">
        </action>
    </package>
</struts>
struts.xml

Spring整合Struts2

方式一:Action由Struts2自身建立

在 Action 中咱們會調用業務層代碼,若是按照傳統方式,咱們要獲取到業務類實例,須要經過 Spring 工廠來手動獲取,以下:

package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
import com.zze.service.UserService;
import org.apache.struts2.ServletActionContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    public String save() {
        //傳統方式獲取 Service
        WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
        UserService userService = (UserService) applicationContext.getBean("userService");
        System.out.println(userService);
        /*
        訪問 http://localhost:8080/customer_save,輸出結果以下:
            com.zze.service.impl.UserServiceImpl@4b65044b
         */
        return NONE;
    }
}
com.zze.web.action.UserAction

而這種方式的代碼顯然過於複雜,Struts2 在與 Spring 整合時 Struts2 還爲咱們提供了更簡易的方式哦。

Spring 整合 Struts2 須要引入一個 jar 包 struts2-spring-plugin.jar,這個 jar 包在上述準備工做中就已經引入,查看該 jar 中的 struts-plugin.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!--
/*
 * $Id$
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
-->
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
    
<struts>
    <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
    
    <!--  Make the Spring object factory the automatic default -->
    <constant name="struts.objectFactory" value="spring" />

    <constant name="struts.class.reloading.watchList" value="" />
    <constant name="struts.class.reloading.acceptClasses" value="" />
    <constant name="struts.class.reloading.reloadConfig" value="false" />
    <constant name="xwork.disallowProxyMemberAccess" value="true" />

    <package name="spring-default">
        <interceptors>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
        </interceptors>
    </package>    
</struts>
struts2-spring-plugin-2.3.37.jar!/struts-plugin.xml

能夠看到在該文件中配置了以下常量:

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

查看 Struts2 的默認配置:

  1 #
  2 # $Id$
  3 #
  4 # Licensed to the Apache Software Foundation (ASF) under one
  5 # or more contributor license agreements.  See the NOTICE file
  6 # distributed with this work for additional information
  7 # regarding copyright ownership.  The ASF licenses this file
  8 # to you under the Apache License, Version 2.0 (the
  9 # "License"); you may not use this file except in compliance
 10 # with the License.  You may obtain a copy of the License at
 11 #
 12 #  http://www.apache.org/licenses/LICENSE-2.0
 13 #
 14 # Unless required by applicable law or agreed to in writing,
 15 # software distributed under the License is distributed on an
 16 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17 # KIND, either express or implied.  See the License for the
 18 # specific language governing permissions and limitations
 19 # under the License.
 20 #
 21 ### START SNIPPET: complete_file
 22 
 23 ### Struts default properties
 24 ###(can be overridden by a struts.properties file in the root of the classpath)
 25 ###
 26 
 27 ### This can be used to set your default locale and encoding scheme
 28 # struts.locale=en_US
 29 struts.i18n.encoding=UTF-8
 30 
 31 ### if specified, the default object factory can be overridden here
 32 ### Note: short-hand notation is supported in some cases, such as "spring"
 33 ###       Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here
 34 # struts.objectFactory = spring
 35 
 36 ### specifies the autoWiring logic when using the SpringObjectFactory.
 37 ### valid values are: name, type, auto, and constructor (name is the default)
 38 struts.objectFactory.spring.autoWire = name
 39 
 40 ### indicates to the struts-spring integration if Class instances should be cached
 41 ### this should, until a future Spring release makes it possible, be left as true
 42 ### unless you know exactly what you are doing!
 43 ### valid values are: true, false (true is the default)
 44 struts.objectFactory.spring.useClassCache = true
 45 
 46 ### ensures the autowire strategy is always respected.
 47 ### valid values are: true, false (false is the default)
 48 struts.objectFactory.spring.autoWire.alwaysRespect = false
 49 
 50 ### By default SpringObjectFactory doesn't support AOP
 51 ### This flag was added just temporally to check if nothing is broken
 52 ### See https://issues.apache.org/jira/browse/WW-4110
 53 struts.objectFactory.spring.enableAopSupport = false
 54 
 55 ### if specified, the default object type determiner can be overridden here
 56 ### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger"
 57 ###       Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation name here
 58 ### Note: By default, com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer is used which handles type detection
 59 ###       using generics. com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer was deprecated since XWork 2, it's
 60 ###       functions are integrated in DefaultObjectTypeDeterminer now.
 61 ###       To disable tiger support use the "notiger" property value here.
 62 #struts.objectTypeDeterminer = tiger
 63 #struts.objectTypeDeterminer = notiger
 64 
 65 ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
 66 # struts.multipart.parser=cos
 67 # struts.multipart.parser=pell
 68 # struts.multipart.parser=jakarta-stream
 69 struts.multipart.parser=jakarta
 70 # uses javax.servlet.context.tempdir by default
 71 struts.multipart.saveDir=
 72 struts.multipart.maxSize=2097152
 73 
 74 ### Load custom property files (does not override struts.properties!)
 75 # struts.custom.properties=application,org/apache/struts2/extension/custom
 76 
 77 ### How request URLs are mapped to and from actions
 78 #struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper
 79 
 80 ### Used by the DefaultActionMapper
 81 ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do
 82 ### The blank extension allows you to match directory listings as well as pure action names
 83 ### without interfering with static resources, which can be specified as an empty string
 84 ### prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,,
 85 struts.action.extension=action,,
 86 
 87 ### Used by FilterDispatcher
 88 ### If true then Struts serves static content from inside its jar.
 89 ### If false then the static content must be available at <context_path>/struts
 90 struts.serve.static=true
 91 
 92 ### Used by FilterDispatcher
 93 ### This is good for development where one wants changes to the static content be
 94 ### fetch on each request.
 95 ### NOTE: This will only have effect if struts.serve.static=true
 96 ### If true -> Struts will write out header for static contents such that they will
 97 ###             be cached by web browsers (using Date, Cache-Content, Pragma, Expires)
 98 ###             headers).
 99 ### If false -> Struts will write out header for static contents such that they are
100 ###            NOT to be cached by web browser (using Cache-Content, Pragma, Expires
101 ###            headers)
102 struts.serve.static.browserCache=true
103 
104 ### Set this to false if you wish to disable implicit dynamic method invocation
105 ### via the URL request. This includes URLs like foo!bar.action, as well as params
106 ### like method:bar (but not action:foo).
107 ### An alternative to implicit dynamic method invocation is to use wildcard
108 ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}">
109 struts.enable.DynamicMethodInvocation = false
110 
111 ### Set this to true if you wish to allow slashes in your action names.  If false,
112 ### Actions names cannot have slashes, and will be accessible via any directory
113 ### prefix.  This is the traditional behavior expected of WebWork applications.
114 ### Setting to true is useful when you want to use wildcards and store values
115 ### in the URL, to be extracted by wildcard patterns, such as
116 ### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or
117 ### "/foo/save".
118 struts.enable.SlashesInActionNames = false
119 
120 ### Disables support for action: prefix
121 struts.mapper.action.prefix.enabled = false
122 
123 ### Blocks access to actions in other namespace than current with action: prefix
124 struts.mapper.action.prefix.crossNamespaces = false
125 
126 ### use alternative syntax that requires %{} in most places
127 ### to evaluate expressions for String attributes for tags
128 struts.tag.altSyntax=true
129 
130 ### when set to true, Struts will act much more friendly for developers. This
131 ### includes:
132 ### - struts.i18n.reload = true
133 ### - struts.configuration.xml.reload = true
134 ### - raising various debug or ignorable problems to errors
135 ###   For example: normally a request to foo.action?someUnknownField=true should
136 ###                be ignored (given that any value can come from the web and it
137 ###                should not be trusted). However, during development, it may be
138 ###                useful to know when these errors are happening and be told of
139 ###                them right away.
140 struts.devMode = false
141 
142 ### when set to true, resource bundles will be reloaded on _every_ request.
143 ### this is good during development, but should never be used in production
144 ### struts.i18n.reload=false
145 
146 ### Standard UI theme
147 ### Change this to reflect which path should be used for JSP control tag templates by default
148 struts.ui.theme=xhtml
149 struts.ui.templateDir=template
150 ### Change this to use a different token to indicate template theme expansion
151 struts.ui.theme.expansion.token=~~~
152 #sets the default template type. Either ftl, vm, or jsp
153 struts.ui.templateSuffix=ftl
154 
155 ### Configuration reloading
156 ### This will cause the configuration to reload struts.xml when it is changed
157 ### struts.configuration.xml.reload=false
158 
159 ### Location of velocity.properties file.  defaults to velocity.properties
160 struts.velocity.configfile = velocity.properties
161 
162 ### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext
163 struts.velocity.contexts =
164 
165 ### Location of the velocity toolbox
166 struts.velocity.toolboxlocation=
167 
168 ### used to build URLs, such as the UrlTag
169 struts.url.http.port = 80
170 struts.url.https.port = 443
171 ### possible values are: none, get or all
172 struts.url.includeParams = none
173 
174 ### Load custom default resource bundles
175 # struts.custom.i18n.resources=testmessages,testmessages2
176 
177 ### workaround for some app servers that don't handle HttpServletRequest.getParameterMap()
178 ### often used for WebLogic, Orion, and OC4J
179 struts.dispatcher.parametersWorkaround = false
180 
181 ### configure the Freemarker Manager class to be used
182 ### Allows user to plug-in customised Freemarker Manager if necessary
183 ### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager
184 #struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager
185 
186 ### Enables caching of FreeMarker templates
187 ### Has the same effect as copying the templates under WEB_APP/templates
188 ### struts.freemarker.templatesCache=false
189 
190 ### Enables caching of models on the BeanWrapper
191 struts.freemarker.beanwrapperCache=false
192 
193 ### See the StrutsBeanWrapper javadocs for more information
194 struts.freemarker.wrapper.altMap=true
195 
196 ### maxStrongSize for MruCacheStorage for freemarker, when set to 0 SoftCacheStorage which performs better in heavy loaded application
197 ### check WW-3766 for more details
198 struts.freemarker.mru.max.strong.size=0
199 
200 ### configure the XSLTResult class to use stylesheet caching.
201 ### Set to true for developers and false for production.
202 struts.xslt.nocache=false
203 
204 ### Whether to always select the namespace to be everything before the last slash or not
205 struts.mapper.alwaysSelectFullNamespace=false
206 
207 ### Whether to allow static method access in OGNL expressions or not
208 struts.ognl.allowStaticMethodAccess=false
209 
210 ### Whether to throw a RuntimeException when a property is not found
211 ### in an expression, or when the expression evaluation fails
212 struts.el.throwExceptionOnFailure=false
213 
214 ### Logs as Warnings properties that are not found (very verbose)
215 struts.ognl.logMissingProperties=false
216 
217 ### Caches parsed OGNL expressions, but can lead to memory leaks
218 ### if the application generates a lot of different expressions
219 struts.ognl.enableExpressionCache=true
220 
221 ### Indicates if Dispatcher should handle unexpected exceptions by calling sendError()
222 ### or simply rethrow it as a ServletException to allow future processing by other frameworks like Spring Security
223 struts.handle.exception=true
224 ### END SNIPPET: complete_file
struts2-core-2.3.37.jar!/org/apache/struts2/default.properties

在第 34 行能夠看到,該常量默認是關閉的,而該常量只要開啓,第 38 行的常量就會生效:

### specifies the autoWiring logic when using the SpringObjectFactory.
### valid values are: name, type, auto, and constructor (name is the default)
struts.objectFactory.spring.autoWire = name

而該配置的做用就是讓 Action 能夠按照變量名稱自動注入 Spring 工廠中管理的實例,因此業務類實例還可經過以下方式獲取:

package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
import com.zze.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public String save() {
        System.out.println(userService);
        /*
        訪問 http://localhost:8080/customer_save,輸出結果以下:
            com.zze.service.impl.UserServiceImpl@389b9f55
         */
        return NONE;
    }
}
com.zze.web.action.UserAction

方式二:Action由Spring建立

修改配置:

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

    <!--
    讓 Spring 來建立 Action 實例
        注意,Action 類要配置爲多例
    -->
    <bean name="userAction" class="com.zze.web.action.UserAction" scope="prototype">
        <property name="userService" ref="userService"/>
    </bean>

    <bean name="userService" class="com.zze.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl">
    </bean>
</beans>
applicationContext.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>
    <package name="test" extends="struts-default" namespace="/">
        <!--
        修改 class 對應 applicationContext.xml 中 bean 的名稱 (id/name)
        -->
        <action name="customer_*" class="userAction" method="{1}">
        </action>
    </package>
</struts>
struts.xml

測試:

package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
import com.zze.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public String save() {
        System.out.println(userService);
        /*
        訪問 http://localhost:8080/customer_save,輸出結果以下:
            com.zze.service.impl.UserServiceImpl@4f543a20
         */
        return NONE;
    }
}
com.zze.web.action.UserAction

Spring整合Hibernate

方式一:保留Hibernate配置文件

編寫實體映射文件:

<?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 name="com.zze.domain.User" table="user">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name" length="32"/>
        <property name="age" column="age"/>
    </class>
</hibernate-mapping>
com/zze/domain/User.hbm.xml

在 Hibernate 核心配置文件中引入實體映射文件:

<mapping resource="com/zze/domain/User.hbm.xml"/>
hibernate.cfg.xml

修改 Dao 代碼:

package com.zze.dao.impl;

import com.zze.dao.UserDao;
import com.zze.domain.User;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
// 使用 Hibernate 提供的 Dao 模板類
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

    @Override
    public void save(User user) {
        this.getHibernateTemplate().save(user);
    }
}
com.zze.dao.impl.UserDaoImpl

將 Hibernate 的核心工廠類實例交給 Spring 建立:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--Spring 整合 Hibernate-->
    <!--引入 Hibernate 配置信息-->
    <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    </bean>
    <!--
    <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    -->

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

    <!-- 開啓註解事務 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--Spring 整合 Struts2-->
    <!--
    讓 Spring 來建立 Action 實例
        注意,Action 類要配置爲多例
    -->
    <bean name="userAction" class="com.zze.web.action.UserAction" scope="prototype">
        <property name="userService" ref="userService"/>
    </bean>

    <bean name="userService" class="com.zze.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
        <!--
        <property name="hibernateTemplate" ref="hibernateTemplate"/>
        -->
    </bean>
</beans>
applicationContext.xml

測試:

package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
import com.zze.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public String save() {
        userService.save(user);
        return NONE;
    }
}

com.zze.web.action.UserAction

方式二:去除Hibernate配置文件

新建數據庫鏈接信息屬性文件:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test
jdbc.username=root
jdbc.password=root
jdbc.properties

刪除 Hibernate 配置文件 hibernate.cfg.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--配置 C3P0 數據源-->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--Spring 整合 Hibernate-->
    <!--引入 Hibernate 配置信息-->
    <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- 注入鏈接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置Hibernate的相關屬性 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>

        <!-- 設置映射文件 -->
        <property name="mappingResources">
            <list>
                <value>com/zze/domain/User.hbm.xml</value>
            </list>
        </property>
    </bean>
    <!--
    <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    -->

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

    <!-- 開啓註解事務 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--Spring 整合 Struts2-->
    <!--
    讓 Spring 來建立 Action 實例
        注意,Action 類要配置爲多例
    -->
    <bean name="userAction" class="com.zze.web.action.UserAction" scope="prototype">
        <property name="userService" ref="userService"/>
    </bean>

    <bean name="userService" class="com.zze.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
        <!--
        <property name="hibernateTemplate" ref="hibernateTemplate"/>
        -->
    </bean>
</beans>
applicationContext.xml

測試:

package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
import com.zze.service.UserService;

public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public String save() {
        userService.save(user);
        return NONE;
    }
}

com.zze.web.action.UserAction

補充

延遲加載問題

Hibernate 是有延遲加載策略的,Spring 整合 Hibernate 後,session 的是由 Spring 管理的。當咱們作一個有延遲加載的查詢操做時,默認狀況下在 service 層已經完成了 session 的開啓與關閉操做,因此若是咱們要在 web 層使用延遲加載,此時 session 是關閉的狀態,會拋出以下異常:

對於這個問題 Spring 也給咱們提供瞭解決方案,只須要配置上它提供的一個過濾器便可,以下:

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>openSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
WEB-INF/web.xml

抽取通用Dao

package com.zze.dao;

import org.hibernate.criterion.DetachedCriteria;

import java.io.Serializable;
import java.util.List;

public interface BaseDao<T> {
    /**
     * 保存操做
     *
     * @param model 要保存的模型
     */
    void save(T model);

    /**
     * 更新操做
     *
     * @param model 要更新的模型
     */
    void update(T model);

    /**
     * 刪除操做
     *
     * @param id 刪除的 id
     */
    void delete(Serializable id);

    /**
     * 經過 id 查詢單個對象
     *
     * @param id 要刪除數據主鍵
     * @return 返回 id 對應的單個對象
     */
    T findById(Serializable id);

    /**
     * 查詢全部數據
     *
     * @return 以 List 方式返回全部數據
     */
    List<T> findAll();

    /**
     * 查詢數據條數
     *
     * @param detachedCriteria 離線查詢對象
     * @return 數據條數
     */
    Serializable findCount(DetachedCriteria detachedCriteria);

    /**
     * 分頁查詢
     *
     * @param detachedCriteria 離線查詢對象
     * @param begin            數據起始索引
     * @param pageSize         每頁數據條數
     * @return 返回分頁的珊瑚橘
     */
    List<T> findPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize);

}
com.zze.dao.BaseDao
package com.zze.dao.impl;

import com.zze.dao.BaseDao;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

    private Class clazz;

    public BaseDaoImpl() {
        /*
         例: class UserDaoImpl extends BaseDaoImpl<User>
         */
        // 獲取到運行時實際類 UserDaoImpl
        Class<? extends BaseDaoImpl> actualClass = this.getClass();
        // 獲取到實際類父類 BaseDaoImpl<User>
        Type genericSuperclass = actualClass.getGenericSuperclass();
        // 轉爲參數化類型
        ParameterizedType type = (ParameterizedType) genericSuperclass;
        // 獲取類型化參數 User
        Type[] actualTypeArguments = type.getActualTypeArguments();
        this.clazz = (Class) actualTypeArguments[0];
    }

    @Override
    public void save(T model) {
        this.getHibernateTemplate().save(model);
    }

    @Override
    public void update(T model) {
        this.getHibernateTemplate().update(model);
    }

    @Override
    public void delete(Serializable id) {
        this.getHibernateTemplate().delete(id);
    }

    @Override
    public T findById(Serializable id) {
        return (T) this.getHibernateTemplate().get(clazz, id);
    }

    @Override
    public List<T> findAll() {
        return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());
    }

    @Override
    public Serializable findCount(DetachedCriteria detachedCriteria) {
        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
        return list.size() > 0 ? list.get(0).intValue() : null;
    }

    @Override
    public List<T> findPage(DetachedCriteria detachedCriteria,Integer begin,Integer pageSize) {
        detachedCriteria.setProjection(null);
        return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize);
    }
}
com.zze.dao.impl.BaseDaoImpl

SSH註解整合

一、導包,同上述準備工做中包。

二、配置:

<?xml version="1.0" encoding="UTF-8"?>
<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_4_0.xsd"
         version="4.0">
    <!--Struts2 過濾器-->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--Spring 核心監聽器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--配置 Spring 配置文件加載路徑,默認加載 WEB-INF/applicationContext.xml-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
</web-app>
WEB-INF/web.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--開啓組件掃描-->
    <context:component-scan base-package="com.zze"/>
    <!--配置 C3P0 數據源-->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--Spring 整合 Hibernate-->
    <!--引入 Hibernate 配置信息-->
    <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- 注入鏈接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置Hibernate的相關屬性 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <!--配置映射掃描-->
        <property name="packagesToScan" value="com.zze.domain"/>
    </bean>


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

    <!-- 開啓註解事務 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
</beans>
applicationContext.xml
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test
jdbc.username=root
jdbc.password=root
jdbc.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###
# error warn info debug trace
log4j.rootLogger= info, stdout
log4j.properties

三、使用註解:

package com.zze.domain;

import javax.persistence.*;

@Table(name = "user")
@Entity
public class User {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
com.zze.domain.User : Hibernate 實體映射註解
package com.zze.dao.impl;

import com.zze.dao.BaseDao;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

    /**
     * 注入 sessionFactory
     *
     * @param sessionFactory
     */
    @Autowired
    private void setSF(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
    }

    /*
    或
    @Resource(name = "hibernateTemplate")
    private HibernateTemplate hibernateTemplate;
    */
    private Class clazz;

    public BaseDaoImpl() {
        /*
         例: class UserDaoImpl extends BaseDaoImpl<User>
         */
        // 獲取到運行時實際類 UserDaoImpl
        Class<? extends BaseDaoImpl> actualClass = this.getClass();
        // 獲取到實際類父類 BaseDaoImpl<User>
        Type genericSuperclass = actualClass.getGenericSuperclass();
        // 轉爲參數化類型
        ParameterizedType type = (ParameterizedType) genericSuperclass;
        // 獲取類型化參數 User
        Type[] actualTypeArguments = type.getActualTypeArguments();
        this.clazz = (Class) actualTypeArguments[0];
    }

    @Override
    public void save(T model) {
        this.getHibernateTemplate().save(model);
    }

    @Override
    public void update(T model) {
        this.getHibernateTemplate().update(model);
    }

    @Override
    public void delete(Serializable id) {
        this.getHibernateTemplate().delete(id);
    }

    @Override
    public T findById(Serializable id) {
        return (T) this.getHibernateTemplate().get(clazz, id);
    }

    @Override
    public List<T> findAll() {
        return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName());
    }

    @Override
    public Serializable findCount(DetachedCriteria detachedCriteria) {
        detachedCriteria.setProjection(Projections.rowCount());
        List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
        return list.size() > 0 ? list.get(0).intValue() : null;
    }

    @Override
    public List<T> findPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) {
        detachedCriteria.setProjection(null);
        return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize);
    }
}
com.zze.dao.impl.BaseDaoImpl : dao 層注入 sessionFactory
package com.zze.dao.impl;

import com.zze.dao.UserDao;
import com.zze.domain.User;
import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {

}
com.zze.dao.impl.UserDaoImpl : dao 層實例化註解
package com.zze.service.impl;

import com.zze.dao.UserDao;
import com.zze.domain.User;
import com.zze.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public void save(User user) {
        userDao.save(user);
    }
}
com.zze.service.impl.UserServiceImpl : service 層實例化和事務註解
package com.zze.web.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.zze.domain.User;
import com.zze.service.UserService;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.stereotype.Controller;

@Controller("userAction")
@ParentPackage("struts-default")
@Namespace("/user")
public class UserAction extends ActionSupport implements ModelDriven<User> {
    private User user = new User();

    @Override
    public User getModel() {
        return user;
    }

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    // 訪問路徑 localhost:8080/user/save
    @Action(value = "save",results = {@Result(name = "success",location = "/index.jsp")})
    public String save() {
        userService.save(user);
        return NONE;
    }
}
com.zze.web.action.UserAction : web 層實例化和 Struts2 配置註解

屬性文件值注入

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///test
jdbc.username=root
jdbc.password=root
jdbc.properties
<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder location="classpath:jdbc.properties"/>
</beans>
applicationContext.xml
package com.zze.spring.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
    @Value("${jdbc.driverClass}")
    private String driverClass;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Test
    public void test() {
        System.out.println(driverClass);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);

        /*
        com.mysql.jdbc.Driver
        jdbc:mysql:///test
        root
        root
         */
    }
}
com.zze.spring.test.Demo
相關文章
相關標籤/搜索