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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章