1. 程式人生 > >Spring+Struts2+mybatis 整合(詳細解釋+完整流程)

Spring+Struts2+mybatis 整合(詳細解釋+完整流程)

一.新建maven專案 選擇 maven-archetype-webApp  

二.目錄結構規範

     

三.匯入JAR包.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.hyycinfo.testssm</groupId>
  <artifactId>ssm1</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>ssm1 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
  
  
   <dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.1.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.4</version>
		</dependency>
		<!-- spring-jdbc: 支援事務處理.. -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.1.4.RELEASE</version>
		</dependency>
		<!-- 資料聯接池 : 其它的還有 c3p0 -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>20030825.184428</version>
		</dependency>
		<dependency>
			<groupId>commons-pool</groupId>
			<artifactId>commons-pool</artifactId>
			<version>20030825.183949</version>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>20040616</version>
		</dependency>
		<!-- 資料庫驅動.. -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.34</version>
		</dependency>
		<!-- 因為使用了 javax.annotation包中的註解。 -->
		<dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>javax.annotation</artifactId>
			<version>1.1.0.v201105051105</version>
		</dependency>
    <!-- mybatis -->
    <dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.3.0</version>
</dependency>
    
    <dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>1.2.2</version>
</dependency>

<!-- Struts2核心 -->
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-core</artifactId>
  <version>2.3.20</version>
</dependency>

<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-json-plugin</artifactId>
  <version>2.3.20</version>
</dependency>
<!-- 釋出的時候不需要 -->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>3.0-alpha-1</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.2.1-b03</version>
   <scope>provided</scope>
</dependency>
<!-- spring整合struts2的包 -->
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-spring-plugin</artifactId>
  <version>2.3.20</version>
</dependency>
<!-- 提供一個a s r -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.1.4.RELEASE</version>
</dependency>

    
  </dependencies>
  <build>
    <finalName>ssm1</finalName>
  </build>
</project>

四.開始配置配置檔案

    web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- 配置一個全域性變數,指定spring配置檔案的位置 -->

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

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:beans*.xml</param-value>
	</context-param>
	
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

  <welcome-file-list>
    <welcome-file>add.jsp</welcome-file>
  </welcome-file-list>
  
</web-app>



ContextLoaderListener的作用就是啟動Web容器時,自動載入<context-param>裡配置的匹配beans*.xml的資訊,我這裡符合的有beans.xml(用於spring配置)和bean-web.xml(用於配置Action)。因為它實現了ServletContextListener這個介面,在web.xml配置這個監聽器,啟動容器時,就會預設執行它實現的方法。

加上啟動spring的監聽器,這樣配置在xml檔案中的bean才會初始化

然後開始讀取beans.xml配置資訊,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p" 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:annotation-config />

 <!-- 先配置掃描包,為了你的系統能夠識別相應的註解。該包下的子類也都可以被掃描,另外可以配置不包含的類,詳細請另外檢視。。
如果想使用@Autowired</span></strong>註解,需要在Spring容器中宣告AutowiredAnnotationBean
同理,註解越多,需要在spring容器其中宣告的...Bean越多,配置了這個以後,就能讓spring自動識別-->
       <context:component-scan base-package="com.hyycinfo" />

 <!--使用註解支援事務,即可以用@Transactional 該方法開啟事務 -->
	 <tx:annotation-driven transaction-manager="txManager"/>

<p><!-- 使用spring自帶的屬性檔案讀取類完成讀取db.properties配置檔案的操作 --></p><p><bean id="pphc"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"></p><p><property name="locations" value="classpath:db.properties" /></bean></p><p><!-- 配置dbcp資料來源... 資料庫聯接池 ( jndi-> tomcat的資料庫聯接池 ) / c3p0 --></p><p><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"></p><p>    <property name="driverClassName" value="${jdbc.driverClassName}" /></p><p>    <property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /></p><p>   <property name="password" value="${jdbc.password}" /></p><p>   <property name="maxActive" value="${jdbc.maxActive}" /></p><p>   <property name="minIdle" value="${jdbc.minIdle}" /></p><p>   <property name="maxIdle" value="${jdbc.maxIdle}" /></p><p></bean></p>
<pre name="code" class="java"><!--下面使針對mybatis的整合配置
	1.sqlsessionfactory
mybatis核心
spring將會在應用啟動時為你創 建SqlSessionFactory物件,然後將它以SqlSessionFactory為名來儲存
SqlSessionFactory有一個單獨的必須屬性,就是JDBC的DataSource。這可以是任意的DataSource。其配置應該和其它spring資料庫連線是一樣的。
一個通用的屬性是configLocation,它是用來指定MyBatis的xml配置檔案路徑的。
 -->
<bean id="SqlSessionFactory"  class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"></property>
	<!-- setmapperLocation -->
	<property name="mapperLocations" value="classpath*:com/hyycinfo/ssm1/dao/*.xml"></property>
</bean>

<!-- 配置掃描器,用於掃描所有的mapper檔案
如果你使 用了一個 以上的 DataSource ,那 麼自動 裝配可 能會失效 。
這種 情況下 ,你可 以使用 SqlSessionFactoryBeanName 屬性來設定正確的 bean 名 稱來使用
這是對spring註解機制的講解,特別有用
http://blog.163.com/
[email protected]
/blog/static/2292852520091128103316534/  --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 配置要掃描的對映檔案對應的介面的檔案 --> <property name="basePackage" value="com.hyycinfo.ssm1.dao"></property> <property name="SqlSessionFactoryBeanName" value="SqlSessionFactory"></property> </bean> <!-- 1.事物管理器 DataSourceTransactionManager: 此事務管理器是針對傳統的JDBC進行事務管理,在spring中是對JdbcTemplate進行事務管理 要 開 啟 Spring 的 事 務 處 理 , 在 Spring 的 XML 配 置 文 件 中 簡 單 創 建 一 個 DataSourceTransactionManager 物件:  --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">         <property name="dataSource" ref="dataSource"/>     </bean>       <!-- 配置增強 -->     <tx:advice id="txAdvice"  transaction-manager="txManager">         <!-- 事物語法,切入點,這裡加入的是切入點表示式-->         <tx:attributes>             <!-- all methods starting with 'get' are read-only -->             <tx:method name="get*" read-only="true"/>             <tx:method name="find*" read-only="true"/>             <tx:method name="retrieve*" read-only="true"/>                <tx:method name="load*" read-only="true"/>                <tx:method name="datagrid*" read-only="true"/>             <!-- 其它的方法加上事物-->               <tx:method name="add*"   propagation="REQUIRED"/>                <tx:method name="del*"   propagation="REQUIRED"/>                 <tx:method name="update*"   propagation="REQUIRED"/>                  <tx:method name="modify*"   propagation="REQUIRED"/>                   <tx:method name="save*"   propagation="REQUIRED"/>                    <tx:method name="remove*"   propagation="REQUIRED"/>                     <tx:method name="repair*"   propagation="REQUIRED"/>                      <tx:method name="insert*"   propagation="REQUIRED"/>                          <tx:method name="*"/>         </tx:attributes>     </tx:advice>     <!-- 配置切面 --> <!-- ensure that the above transactional advice runs for any execution         of an operation defined by the FooService interface -->     <aop:config>         <aop:pointcut id="service" expression="execution(* com.hyycinfo.ssm1.impl.*.*(..))"/>         <aop:advisor advice-ref="txAdvice" pointcut-ref="service"/>     </aop:config>      </beans>


這樣配置完畢以後,你可以根據配置檔案來知道你接下來要寫的類,從上往下:

(1)你需要寫一個db.properties資料庫連結配置檔案

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm1?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=a
jdbc.maxActive=150
jdbc.minIdle=5
jdbc.maxIdle=20

(2)要掃描的對映檔案對應的介面的檔案,以及對應的xml對映檔案

package com.hyycinfo.ssm1.dao;

import java.util.List;

import com.hyycinfo.ssm1.bean.Student;

public interface StudentDao {
	public int delete (String id);
	public int add(Student student);
	public Student findById(String id);
	public void update(Student student);
}

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.hyycinfo.ssm1.dao.StudentDao">
<resultMap type="com.hyycinfo.ssm1.bean.Student" id="BaseResultMap">
	<id column="id" property="id" jdbcType="CHAR"/>
	<result column="sname" property="sname" jdbcType="VARCHAR"/>
	<result column="age" property="age" />
</resultMap>


<delete id="delete" parameterType="java.lang.String">
	delete from student where id=#{id}
</delete>

<insert id="add" parameterType="com.hyycinfo.ssm1.bean.Student" >
	insert into student(id,sname,age)  values(#{id},#{sname},#{age})
</insert>


<update id="update" parameterType="com.hyycinfo.ssm1.bean.Student">
	update student set sname=#{sname},age=#{age} where id=#{id}
</update>

<select id="findById" resultMap="BaseResultMap" parameterType="java.lang.String">
	select * from student where id=#{id} 
</select>
</mapper>



 ( 3  ) 業務層

package com.hyycinfo.ssm1.biz;

import com.hyycinfo.ssm1.bean.Student;
import com.hyycinfo.ssm1.dao.StudentDao;

public interface StudentBiz {
	public int delete(String id);
	public int add(Student student);
	public Student  findById(String id);
	public void update(Student student);
	public void setStudentDao(StudentDao studentDao);
}

業務實現類
package com.hyycinfo.ssm1.impl;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hyycinfo.ssm1.bean.Student;
import com.hyycinfo.ssm1.biz.StudentBiz;
import com.hyycinfo.ssm1.dao.StudentDao;
@Service("studentBiz")
public class StudentBizImpl  implements StudentBiz{
	@Autowired
	public StudentDao studentDao;
	
		public int delete(String id){
			return studentDao.delete(id);
		}
		public int add(Student student){
			return studentDao.add(student);
		}
		
		public Student  findById(String id){
			return studentDao.findById(id);
		}
		
		public void update(Student student){
			studentDao.update(student);
			
		}
		public void setStudentDao(StudentDao studentDao){
			this.studentDao=studentDao;
		}
		
}

為了實現你的類,因此你還需要一個bean..
package com.hyycinfo.ssm1.bean;

public class Student {
	private String id;
	private String sname;
	private Integer age;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", sname=" + sname + ", age=" + age + "]";
	}
	public Student(String id, String sname, Integer age) {
		super();
		this.id = id;
		this.sname = sname;
		this.age = age;
	}
	public Student() {
		super();
	}
	
	
}

五.一開始的web.xml提到了我bean*.xml的檔案不僅僅只有beans.xml還有bean-web.xml,那麼現在載入完beans.xml自然就載入beans-web.xml

這裡的beans-web配置的是所有的action,當然你也可以全部配置在beans.xml裡面,這樣程式會顯的臃腫,不清晰

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p" 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
         ">
 <!-- 為了讓控制器Action訪問Spring的業務邏輯元件:
 scope="prototype"來保證每一個請求有一個單獨的Action來處理,        避免struts中Action的執行緒安全問題。
這裡的ref="studentBiz"由註解注入
 -->
<bean id="studentAction" class="com.hyycinfo.ssm1.web.actions.StudentAction" scope="prototype">
	<property name="studentBiz"  ref="studentBiz"></property>
</bean>
         
         </beans>

然後因為web.xml會自動載入
StrutsPrepareAndExecuteFilter類中
 private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
它會在自動搜尋本地的struts.xml檔案
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.objectFactory" value="spring" />
    <package name="default"  namespace="/" extends="struts-default">
    <!-- 注意:因為這是,由spring來生成action物件
      所以類名是寫由spring建立的bean的id,而不是寫全路徑
     -->
    	<action name="student_*" class="studentAction" method="{1}">
    	<result name="add_success">/add_success.jsp</result>
    	</action>
    </package>
    <!-- Add packages here -->
</struts>

struts.enable.DynamicMethodInvocation ,-動態方法呼叫,帶!感嘆號那個。。我也不太熟,但一般禁用
<pre name="code" class="java">devMode  true 開發模式下使用,這樣可以打印出更詳細的錯誤資訊。

<pre name="code" class="java">objectFactory   spring  該屬性指定Struts 2中的Action由Spring容器建立。


這樣整個流程就跑完了


為了方便大家,給大家提供了免費程式碼資源下載http://download.csdn.net/detail/ac_great/9000945

最後提醒大家,以我身邊的例子來看,有很多人都整合失敗的原因都跟自己的環境有關,比如jdk,tomcat,maven,eclipse平臺,還有jar包的原因

這就是最麻煩的地方,所以在做之前一定要確保好自己的環境....  

 補充一個mysql指令碼

create database ssm1;
use ssm1;
drop table if exists student;
create table student(
	id char(50) primary key,
	sname varchar(100) not null,
	age int 
	
)engine=innodb default charset=utf8;
show create table student;
insert into student values('1','張三',22);