Struts2+Spring+MyBatis环境整合开发案例(MVC架构)

来源:互联网 发布:c语言嵌入式汇编 编辑:程序博客网 时间:2024/06/09 23:32

最近公司一个项目开发环境要求Struts2+Spring+MyBatis 框架,之前都是用Struts2+Spring+Hibernate 的。个人觉得MyBatis和Hibernate的最大区别,就是MyBatis是一个不完全的ORM框架,可自定义很多比较复杂的sql语句,比如调用 sql自定义函数和存储过程,很适合金融和门户之类的项目。而Hibernate是完全的ORM,有些时候写自定义的sql还是不太方便。好了,废话不多说,今天凭着对Hibernate的经验搭建了MyBatis,过程还挺顺利的。

1.下载和导入jar包

当然在之前得建立一个web项目或maven生成,导入的jar包可到官方下载,也可以到http://download.csdn.net/detail/u012131769/8779655下载。

2.web.xml配置 利用监听器整合spring,让应用启动时首先加载beans.xml

web.xml添加一下代码:

[html] view plain copy
  1. <context-param>  
  2.         <param-name>contextConfigLocation</param-name>  
  3.         <param-value>  
  4.             classpath:beans.xml  
  5.         </param-value>  
  6.     </context-param>  
  7.     <listener>  
  8.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  9. </listener>  


 

3.Spring配置文件beans.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans  xmlns="http://www.springframework.org/schema/beans"  
  3.         xmlns:context="http://www.springframework.org/schema/context"  
  4.         xmlns:aop="http://www.springframework.org/schema/aop"  
  5.         xmlns:tx="http://www.springframework.org/schema/tx"  
  6.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  7.         xsi:schemaLocation="http://www.springframework.org/schema/beans   
  8.                             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  9.                             http://www.springframework.org/schema/context   
  10.                             http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  11.                             http://www.springframework.org/schema/tx   
  12.                             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  13.                             http://www.springframework.org/schema/aop   
  14.                             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" default-autowire="byName">  
  15. <!-- 1、注解的自动扫描,表示组件(如:@controler,@Service,@Repository,@Resource等)的扫描 -->   
  16. <context:component-scan base-package="com.huaxun.ssmtest"></context:component-scan>  
  17.   
  18. <!-- 2、配置C3P0数据源 -->  
  19. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
  20.     <property name="driverClass" value="com.mysql.jdbc.Driver" />  
  21.     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mysite?useUnicode=true&characterEncoding=UTF8"/>  
  22.     <property name="user" value="root" />  
  23.     <property name="password" value="123" />  
  24.     <!--连接池中保留的最小连接数。-->  
  25.     <property name="minPoolSize" value="5" />  
  26.     <!--连接池中保留的最大连接数。Default: 15 -->  
  27.     <property name="maxPoolSize" value="30" />  
  28.     <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->  
  29.     <property name="initialPoolSize" value="10"/>  
  30.     <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->  
  31.     <property name="maxIdleTime" value="60"/>  
  32.     <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->  
  33.     <property name="acquireIncrement" value="5" />  
  34.     <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements    
  35.         属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。    
  36.         如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->  
  37.     <property name="maxStatements" value="0" />  
  38.     <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->  
  39.     <property name="idleConnectionTestPeriod" value="60" />  
  40.     <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->  
  41.     <property name="acquireRetryAttempts" value="30" />  
  42.     <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效    
  43.         保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试    
  44.         获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->  
  45.     <property name="breakAfterAcquireFailure" value="true" />  
  46. </bean>  
  47.   
  48. <!-- 3、MyBatis -->  
  49. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  50.      <property name="dataSource" ref="dataSource" />    
  51.      <property name="configLocation" value="classpath:Mybatis_Configuration.xml"/>    
  52. </bean>    
  53. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">    
  54.     <property name="basePackage" value="com.huaxun.ssmtest.*" />    
  55. </bean>  
  56.   
  57.   
  58. <!--4、创建事务管理器,由spring负责创建  -->  
  59. <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  60.     <property name="dataSource" ref="dataSource"/>  
  61. </bean>  
  62.   
  63. <!-- 5、使用注解的形式管理事务 -->  
  64. <tx:annotation-driven transaction-manager="txManager"/>  
  65. </beans>  


 

4.MyBatis配置文件(和Hibernate的有点类似,当然这步可以注解方式实现,不过我觉得xml还是比较直观和简洁一些)Mybatis_Configuration.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE configuration  
  3.     PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  4.     "http://mybatis.org/dtd/mybatis-3-config.dtd">  
  5. <configuration>  
  6.     <mappers>  
  7.         <mapper resource="com/huaxun/ssmtest/domain/mapper/NoteMapper.xml"/>  
  8.     </mappers>  
  9. </configuration>  


 

5.实体对象实体(随便建立来测试的)

[java] view plain copy
  1. package com.huaxun.ssmtest.domain;  
  2. import java.util.Date;  
  3. /** 
  4.  *  Class Name: Note.java 
  5.  *  Function: 
  6.  *  @author Yang Ji. 
  7.  *  @DateTime 2015年6月6日 下午1:47:52     
  8.  *  @version 1.0  
  9.  */  
  10. public class Note {  
  11.     private Integer note_id;  
  12.     private String name;  
  13.     private String telephone;  
  14.     private String email;  
  15.     private String content;  
  16.     private Date create_time = new Date();  
  17.   
  18. // Getter and Setter...  
  19. }  


 

6.Mapper配置内容,先写一个方法试试,所谓大道至简,简单的能实现,以后扩展就不难了。

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper  
  3.     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
  4.     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  5. <mapper namespace="note">  
  6.     <select id="selectNote" resultMap="noteRM"   
  7.         parameterType="com.huaxun.ssmtest.domain.Note">  
  8.         select * from note where note_id = #{note_id}  
  9.     </select>  
  10.       
  11.     <resultMap type="com.huaxun.ssmtest.domain.Note" id="noteRM"></resultMap>  
  12. </mapper>  


 

7.好了,MVCModel层实体和配置都完成了,接下来进入Daoservice的管理。spring项目应尽力面向接口编程,aop才好管理。下面贴出实现类吧,Interface就不重复了。

[java] view plain copy
  1. package com.huaxun.ssmtest.dao.impl;  
  2. import java.util.List;  
  3. import javax.annotation.Resource;  
  4. import org.apache.ibatis.session.SqlSessionFactory;  
  5. import com.huaxun.ssmtest.dao.IBaseDao;  
  6.   
  7. /** 
  8.  *  Class Name: BaseDaoImpl.java 
  9.  *  Function: 
  10.  *  @author Yang Ji. 
  11.  *  @DateTime 2015年6月6日 下午2:28:14     
  12.  *  @version 1.0  
  13.  */  
  14. public class BaseDaoImpl<T> implements IBaseDao<T> {  
  15.     private Class entityClass = getActualTypeClass(this.getClass());  
  16.     public Class getActualTypeClass(Class entity) {  
  17.         ParameterizedType type = (ParameterizedType) entity.getGenericSuperclass();  
  18.         Class entityClass = (Class) type.getActualTypeArguments()[0];  
  19.         return entityClass;  
  20.     }  
  21.       
  22.     @Resource(name="sqlSessionFactory")  
  23.     private SqlSessionFactory sessionFactory;  
  24.     public final void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {  
  25.         this.sessionFactory = sqlSessionFactory;  
  26.     }  
  27.       
  28.     @Override  
  29.     public void insert(String stateName, T t) {  
  30.          this.sessionFactory.openSession().insert(stateName,t);  
  31.     }  
  32.   
  33.     @Override  
  34.     public void delete(String stateName, T t) {  
  35.         this.sessionFactory.openSession().delete(stateName,t);  
  36.     }  
  37.   
  38.     @Override  
  39.     public void update(String stateName, T t) {  
  40.         this.sessionFactory.openSession().delete(stateName,t);  
  41.     }  
  42.   
  43.     @Override  
  44.     public List<T> queryForParam(String stateName, T param) {  
  45.         return this.sessionFactory.openSession().selectList(stateName, param);  
  46.     }  
  47.   
  48.     @Override  
  49.     public List<T> query(String stateName) {  
  50.          return this.sessionFactory.openSession().selectList(stateName);   
  51.     }  
  52. }  


 

8.Note实体的Dao实现

[java] view plain copy
  1. package com.huaxun.ssmtest.dao.impl;  
  2. import org.springframework.stereotype.Repository;  
  3. import com.huaxun.ssmtest.dao.INoteDao;  
  4. import com.huaxun.ssmtest.domain.Note;  
  5.   
  6. /** 
  7.  *  Class Name: NoteDaoImpl.java 
  8.  *  Function: 
  9.  *  @author Yang Ji. 
  10.  *  @DateTime 2015年6月6日 下午2:49:17     
  11.  *  @version 1.0  
  12.  */  
  13. @Repository(INoteDao.SERVICE_NAME)  
  14. public class NoteDaoImpl extends BaseDaoImpl<Note> implements INoteDao {  
  15. }  


 

9.Note实体的Service实现

[java] view plain copy
  1. package com.huaxun.ssmtest.service.impl;  
  2. import java.util.List;  
  3. import javax.annotation.Resource;  
  4. import org.springframework.stereotype.Service;  
  5. import org.springframework.transaction.annotation.Transactional;  
  6. import com.huaxun.ssmtest.dao.INoteDao;  
  7. import com.huaxun.ssmtest.dao.impl.BaseDaoImpl;  
  8. import com.huaxun.ssmtest.domain.Note;  
  9. import com.huaxun.ssmtest.service.NoteService;  
  10.   
  11. /** 
  12.  *  Class Name: NoteServiceImpl.java 
  13.  *  Function: 
  14.  *  @author Yang Ji. 
  15.  *  @DateTime 2015年6月6日 下午2:44:05     
  16.  *  @version 1.0  
  17.  */  
  18. @Service(NoteService.SERVICE_NAME)  
  19. @Transactional(readOnly=true)   // Remove Transaction  
  20. public class NoteServiceImpl extends BaseDaoImpl<Note> implements NoteService {  
  21.     @Resource(name=INoteDao.SERVICE_NAME)  
  22.     private INoteDao noteDao;  
  23.       
  24.     @Override  
  25.     public List<Note> queryForParam(String stateName, Note param) {  
  26.         return noteDao.queryForParam(stateName, param);  
  27.     }  
  28. }  


 

10.所有的都准备好了,写个测试类测试一下吧。

[java] view plain copy
  1. package com.huaxun.ssmtest.test;  
  2. import java.util.List;  
  3. import org.junit.Test;  
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6. import com.huaxun.ssmtest.domain.Note;  
  7. import com.huaxun.ssmtest.service.NoteService;  
  8.   
  9. /** 
  10.  *  Class Name: NoteTest.java 
  11.  *  Function: 
  12.  *      Note实体方法测试 
  13.  *  @author Yang Ji. 
  14.  *  @DateTime 2015年6月6日 下午2:04:00     
  15.  *  @version 1.0  
  16.  */  
  17. public class NoteTest   
  18. {  
  19.     @Test  
  20.     public void selectTest(){  
  21.         ApplicationContext aContext = new ClassPathXmlApplicationContext("beans.xml");  
  22.         NoteService adminService = (NoteService) aContext.getBean(NoteService.SERVICE_NAME);  
  23.           
  24.         Note note = new Note();  
  25.         note.setNote_id(4);  
  26.         List<Note> notes = adminService.queryForParam("note.selectNote", note);  
  27.           
  28.         for(Note n : notes){  
  29.             System.out.println(n.toString()+"\n");  
  30.         }  
  31.     }  
  32. }  


11.测试成功,MVC架构ModelController已经完成,就差View,也就是Struts2了,最近Struts22.x-3.0.x出现的安全漏洞听起来挺恐怖的,建议使用3.0以后的版本,或者自己写拦截器拦截一下,不然到时候被攻击就悔不当初了。Struts2配置都是家常便饭,平时写得手都软了,就不再多说什么,上点struts配置和action的模板吧。

Web.xml中集成struts2,添加一下代码:

[html] view plain copy
  1. <filter>  
  2.         <filter-name>struts2</filter-name>  
  3.         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>struts2</filter-name>  
  7.         <url-pattern>/*</url-pattern>  
  8.     </filter-mapping>  


 

Struts.xml配置模板

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC    
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    
  4.     "http://struts.apache.org/dtds/struts-2.3.dtd">    
  5. <struts>  
  6.     <!-- 修改访问的后缀名   
  7.     <constant name="struts.action.extension" value=""></constant>  
  8.     -->  
  9.     <constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />  
  10.     <!-- 设置为开发模式,运行时输入更多错误信息 -->  
  11.     <constant name="struts.devMode" value="false"></constant>  
  12.     <!-- 设置为ui简单主题 -->  
  13.     <constant name="struts.yi.theme" value="simple"></constant>  
  14.     <!-- 设置上传文件最大值 -->  
  15.     <constant name="struts.multipart.maxSize" value="90000000"></constant>  
  16.       
  17.     <package name="front" namespace="/" extends="struts-default">  
  18.     <!-- 用户资料管理 -->  
  19.         <action name="muser_*" class="auserAction" method="{1}">  
  20.             <result name="index">/front/index.jsp</result>  
  21. </action>  
  22. </package>  
  23. </struts>  


 

Action模板

[java] view plain copy
  1. package net.hillsstudio.gmsite.view.front;  
  2. import java.io.IOException;  
  3. import java.io.PrintWriter;  
  4. import java.util.List;  
  5. import javax.annotation.Resource;  
  6. import net.hillsstudio.gmsite.domain.Area;  
  7. import net.hillsstudio.gmsite.service.IAreaService;  
  8. import net.hillsstudio.gmsite.view.BaseAction;  
  9. import net.hillsstudio.gmsite.view.model.AreaModel;  
  10. import org.springframework.context.annotation.Scope;  
  11. import org.springframework.stereotype.Controller;  
  12. import com.opensymphony.xwork2.ModelDriven;  
  13.   
  14. /** 
  15.  *  Class Name: FAreaAction.java 
  16.  *  Function: 
  17.  *      Front Area Entity Manage Action.   
  18.  *  @author Gym Yung.  
  19.  *  @DateTime 2015-4-11 下午8:26:52     
  20.  *  @version 1.0 
  21.  */  
  22. @SuppressWarnings("serial")  
  23. @Controller("fareaAction")  
  24. @Scope(value="prototype")  
  25. public class FAreaAction extends BaseAction implements ModelDriven<AreaModel>  
  26. {  
  27.     private AreaModel areaModel = new AreaModel();  
  28.     @Override  
  29.     public AreaModel getModel()  
  30.     {  
  31.         return areaModel;  
  32.     }  
  33.       
  34.     @Resource(name=IAreaService.SERVICE_NAME)  
  35.     private IAreaService areaService;  
  36.       
  37.     /** 
  38.      *  Function: 
  39.      *      Query Province Data And Skip The Page of Change City Page.  
  40.      *  @author Gym Yung. 
  41.      *  @DateTime 2015-4-11 下午8:33:58 
  42.      *  @return 
  43.      */  
  44.     public String ccp(){  
  45.         try  
  46.         {  
  47.             List<Area> areas = areaService.findAreasByType(Area.AREA_TYPE_PROVINCE);  
  48.             request.setAttribute("areas", areas);  
  49.         }  
  50.         catch (Exception e)  
  51.         {  
  52. //          e.printStackTrace();  
  53.         }  
  54.         return "cityChoice";  
  55.     }  
  56. }