ssm2-Struts2+Spring+Mybatis整合

本篇主要講解Struts2與Spring+Mybatis的整合。

通過整合,由Spring管理Mybatis的mapper以及Struts2的Action。

項目分爲mapper(dao從層)、service層、Action層。

使用工具及框架版本:

eclipse neon

Struts2.3

Spring3.2

Mybatis3.2.7

Tomcat7.0

MySql5.6

jdk1.7

項目結構如下圖所示:



項目源碼下載點擊下載

項目war包下載點擊下載

在線演示:點擊觀看


在本項目中,主要通過一個用戶登錄的實例來進行講解。

數據庫字段如下:

id-int

username-varchar(50)

password-varchar(50)



Mybatis與Spring的結合

可參考之前講解過的一篇關於Mybatis與Spring整合的文章:點擊打開鏈接

一、Spring+Mybatis

1、編寫PO類

package com.sw.po;
/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:用戶表po對象
 *id:編號
 *username:用戶名
 *password:密碼
 */
public class User {
	private int id;
	private String username;
	private String password;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

2、編寫SqlMapConfig.xml文件

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

	<typeAliases>
		<package name="com.sw.po"/>
	</typeAliases>
	
</configuration>

3、編寫mapper接口

package com.sw.mapper;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:
 */
public interface UserMapper {
	
	/*用戶登錄:根據用戶名查找用戶密碼,檢查是否匹配進行登錄*/
	public String findPassByName(String username)throws Exception;
	
}

4、編寫mapper.xml文件

<?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.sw.mapper.UserMapper">
	
	<!-- 用戶登錄(根據用戶名查找返回密碼,校驗) -->
	<select id="findPassByName" parameterType="String" resultType="String">
		select password from user where username=#{username}
	</select>
	
</mapper>

5、編寫applicationContext.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:mvc="http://www.springframework.org/schema/mvc"
	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-3.2.xsd 
		http://www.springframework.org/schema/mvc 
		http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-3.2.xsd 
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">

	<!-- 加載配置文件 -->
	<context:property-placeholder location="classpath:db.properties"/>
	
	<!-- 數據庫連接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		<property name="maxActive" value="10"/>
		<property name="maxIdle" value="5"/>
	</bean>	
	
	<!-- 配置註解自動掃描範圍 -->
    <context:component-scan base-package="com.bs"></context:component-scan>
	
	<!-- 事務管理器 
	對mybatis操作數據庫事務控制,spring使用jdbc的事務控制類
	-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 數據源
		dataSource在applicationContext-dao.xml中配置了
		 -->
		<property name="dataSource" ref="dataSource"/>
	</bean>
		
	<!-- 管理mybatis -->
	
	<!-- mapper配置 -->
	<!-- 讓spring管理sqlsessionfactory 使用mybatis-spring.jar -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		
		<!-- 數據庫連接池 -->
		<property name="dataSource" ref="dataSource" />
		
		<!-- 加載mybatis的全局配置文件 -->
		<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
	</bean>
	
	<!-- mapper掃描(自動掃描) -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 掃描的包名 -->
		<property name="basePackage" value="com.sw.mapper"></property>
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
	</bean>

</beans>

6、db.properties配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1/xc?character=utf-8
jdbc.username=root
jdbc.password=****

7、到了這裏,Mybatis與Spring的整合已經完成,接下來我們測試一下。

package com.sw.test;


import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.sw.mapper.UserMapper;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:Spring與Mybatis整合測試
 */
public class UserDaoTest {
	private ApplicationContext applicationContext;
	@Before
	public void setUp() throws Exception {
		//spring
		applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	}

	@Test
	public void test() throws Exception {
		UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
		String pass=userMapper.findPassByName("bs");
		System.out.println(pass);
	}

}

結果如下:


現在Spring與Mybatis的整合已經成功,接下來編寫Service層代碼。


二、service層編寫

1、Service層接口編寫

package com.sw.service;
/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:Service層接口
 */
public interface UserService {
	public final static String SERVICE_NAME="UserServiceImpl";
	
	/*用戶登錄驗證*/
	public String findLoginCheck(String username)throws Exception;
}

2、applicationContext.xml編寫:在上面代碼的基礎上加入如下代碼:

        <!-- Service層 -->
	<!-- 通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 傳播行爲 -->
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
			<tx:method name="insert*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
			<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
			<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- aop -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.sw.service.impl.*.*(..))"/>
	</aop:config>
	
	<!-- 方法實現配置 -->
	 <bean id="UserServiceImpl" class="com.sw.service.impl.UserServiceImpl"></bean>

3、實現service層接口

package com.sw.service.impl;

import com.bs.container.ServiceProvider;
import com.sw.mapper.UserMapper;
import com.sw.service.UserService;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:Service層接口實現類
 */
public class UserServiceImpl implements UserService{

	@Override
	public String findLoginCheck(String username) throws Exception {
		UserMapper userMapper=(UserMapper) ServiceProvider.getService("userMapper");
		String pass = userMapper.findPassByName(username);
		return pass;
	}
	
}

4、編寫工具類,此工具類主要用於加載applicationContext.xml文件,以避免每次加載浪費資源

package com.bs.container;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:服務類,用用戶加載applicationContext.xml文件
 */
public class ServiceProvideCord {
	
	protected static ApplicationContext applicationContext;
	
	public static void load(String fileName){
		applicationContext = new ClassPathXmlApplicationContext(fileName);
	}
}

package com.bs.container;

import org.apache.commons.lang.StringUtils;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:服務類
 */
@SuppressWarnings("static-access")
public class ServiceProvider {
	private static ServiceProvideCord serviceProvideCord;
	
	//靜態加載
	static{
		serviceProvideCord = new ServiceProvideCord();
		serviceProvideCord.load("classpath:applicationContext.xml");
	}
	
	public  static Object getService(String serviceName){
		//服務名稱爲空
		if(StringUtils.isBlank(serviceName)){
			throw new RuntimeException("當前服務名稱不存在");
		}
		Object object = null;
		if(serviceProvideCord.applicationContext.containsBean(serviceName)){
			//獲取到
			object = serviceProvideCord.applicationContext.getBean(serviceName);
		}
		if(object==null){
			throw new RuntimeException("當前服務名稱【"+serviceName+"】下的服務節點不存在");
		}
		return object;
	}
}

5、接下來,我們可以對service層進行測試了,代碼如下:

package com.sw.test;


import org.junit.Test;

import com.bs.container.ServiceProvider;
import com.sw.service.UserService;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:Service層測試
 */
public class UserServiceTest {

	@Test
	public void test() throws Exception {
		UserService userService=(UserService) ServiceProvider.getService(UserService.SERVICE_NAME);
		String pass=userService.findLoginCheck("bs");
		System.out.println(pass);
	}

}

結果如下圖所示:


如上所示,Service層的編寫已經完成,並且不存在錯誤,接下來我們加入Struts2進行整合


三、Struts2整合

加入Struts,主要由Spring管理其Action,並且Struts2可以使用Spring的註解進行開發。

1、編寫VO對象,VO對象用於映射表單內提交的數據。

package com.sw.view.form;
/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:持久層bean-對應於數據庫表(user)--即表單提交的數據
 */
public class UserForm {
	private int id;
	private String username;
	private String password;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

2、編寫baseAction文件,該文件主要用於封裝Request於Response

package com.sw.view.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.opensymphony.xwork2.ActionSupport;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:封裝Request與Response
 */
public class BaseAction extends ActionSupport implements ServletRequestAware,ServletResponseAware{

	private static final long serialVersionUID = 1L;
	
	protected HttpServletRequest request;
	protected HttpServletResponse response;
	
	@Override
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

}

3、編寫Action文件,該文件主要用於處理登錄動作

package com.sw.view.action;

import com.bs.container.ServiceProvider;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.sw.service.UserService;
import com.sw.view.form.UserForm;

/*
 *@Author swxctx
 *@time 2017年5月11日
 *@Explain:登錄Action
 */
public class LoginAction extends BaseAction implements ModelDriven<UserForm>{

	private static final long serialVersionUID = 1L;
	/*創建vo對象*/
	UserForm userForm = new UserForm();
	
	/*加載applicationContext.xml*/
	private UserService userService = (UserService)ServiceProvider.getService(UserService.SERVICE_NAME);
	

	@Override
	public UserForm getModel() {
		// TODO Auto-generated method stub
		return userForm;
	}
	
	/*處理*/
	@Override
	public String execute() throws Exception {
		/*調用service層LoginCheck函數校驗*/
		String pass = userService.findLoginCheck(userForm.getUsername());
		
		if(userForm.getPassword().equals(pass)){
			return "success";
		}else{
			return "error";
		}
	}
}

4、編寫相關applicationContext.xml文件,該文件主要用於將Action放入Spring管理

在之前的.xml文件中加入如下代碼即可。

<!-- 管理struts2 action-->	
	<!-- 登錄action -->
	<bean id="loginAction" class="com.sw.view.action.LoginAction" scope="prototype"></bean>

5、編寫struts2.xml文件

<?xml version="1.0" encoding="UTF-8" ?>  
  <!DOCTYPE struts PUBLIC  
      "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
      "http://struts.apache.org/dtds/struts-2.0.dtd">  
  
  <struts> 
  
  <constant name="struts.objectFactory" value="spring"></constant> 
     <!-- struts的action配置文件 -->  
       
     <!-- 所有的action都應該放在對應的package下 -->  
     <package name="ssm-template" extends="struts-default">  
        
        <!-- 用戶登錄 -->
        <action name="login" class="loginAction">  
            <!-- 定義邏輯視圖和物理資源之間的映射 -->  
            <result name="success" >
            	<param name="location">/success.html</param>
            </result>  
            <result name="error">/err.html</result>  
        </action> 
       
     </package>  
</struts>  

6、編寫web.xml文件,用於處理監聽器等操作

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ssm-template</display-name>
 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/classes/applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <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-app>

7、編寫相關的html文件

login.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<form action="login.action" mephod="post">
		用戶:<input type="text" id="username" name="username" placeholder="用戶名"><br>
		密碼:<input type="password" id="password" name="password" placeholder="密碼" ><br>
		<input type="submit" value="提交">
	</form>

</body>
</html>

success.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>success</title>
</head>
<body>
	<p>登錄成功</p>
</body>
</html>

err.html文件:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>err</title>
</head>
<body>
	<p>登錄失敗</p>
</body>
</html>

至此,Struts2與Spring以及Mybatis的整合已經全部結束了,接下來啓動tomcat進行測試,如下圖所示:

登錄頁面:


成功頁面:


失敗頁面:


如上測試可看出,此項目可以運行了,也就是說在整合過程中沒有差錯。

總結:在此項目中,將ssm2進行整合,個人覺得對比ssh2好的一點就是思路比較清晰,不用很多dao接口

那麼亂,但是在此項目中,還是有一點缺陷,那就是spring的配置文件集合了三層的配置,其實在真正

項目開發中,我們應該將三層的配置分來,這樣總體架構會更加清晰。




發佈了436 篇原創文章 · 獲贊 106 · 訪問量 57萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章