SSM简单整合教程&测试事务

自打来了博客园就一直在看帖,学到了很多知识,打算开始记录的学习到的知识点

今天我来写个整合SpringMVC4 spring4 mybatis3&测试spring事务的教程,如果有误之处,还请批评指正。

 本文是原创文章,转载请注明出处


 

一、准备工作:

开发环境:

  1. idea(源码文章最后会给出,不下载也一样,下边都贴出来了)
  2. MySQL 5.7
  3. Tomcat 8.5
  4. Google chrome的插件postman(发送json数据)
  5. navicat for MySQL(用MySQL命令行也行)

        

  本教程用到的jar包如下(源码中本文中用到所有jar都已经给出):

  Spring以及springMVC的jar包:

  SSM简单整合教程&测试事务_第1张图片

   Mybatis的jar包&mybatis兼容spring的jar以及jdbc驱动:

  

  使用的数据源源为阿里巴巴的druid,和fastjson解析json

  

  Tomcat8.5,这个一般的IDE都不用管,配置好就可以

   

  文件上传下载的支持,本教程中没有写,如果有时间我会补上

  

  Mybatis-generator 自动生成Mapper和mapper.xml用的

  SSM简单整合教程&测试事务_第2张图片

 

 


 

二、文件结构

SSM简单整合教程&测试事务_第3张图片

SSM简单整合教程&测试事务_第4张图片


 

三、建表:

建表语句等已经存在了com.hellz.sql包中

 

create DATABASE mybatis;
use mybatis;
create table teacher
(
  tid int(10) primary key auto_increment,
  tname varchar(20),
  tusername varchar(20),
  tpassword varchar(15)
);
create table student
(
  sid int(6) primary key auto_increment,
  sname varchar(20),
  ssex int(1),#0代表未知,1代表男,2代表女
  sage int(3),
  steacherid int(10)
);
insert into teacher (tname,tusername,tpassword) VALUES ('小李','username','123456');#其实已经设置主键自增了就不用设置tid了,这条tid=1

 


 

四、代码

 

Controllor包中

DemoController代码:

 

 1 package com.hellxz.controller;
 2 
 3 import com.hellxz.entity.Student;
 4 import com.hellxz.entity.User;
 5 import com.hellxz.service.StudentService;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.stereotype.Controller;
 8 import org.springframework.ui.ModelMap;
 9 import org.springframework.web.bind.annotation.RequestBody;
10 import org.springframework.web.bind.annotation.RequestMapping;
11 import org.springframework.web.servlet.ModelAndView;
12 
13 import javax.servlet.http.HttpServletRequest;
14 
15 @Controller
16 @RequestMapping("user")
17 
18 public class DemoController {
19 
20 //  注入studentservice
21     @Autowired
22     private StudentService studentService;
23     @RequestMapping("/demo")//此处测试springmvc是否工作
24     public String demo(){
25         return "demo";
26     }
27     @RequestMapping("/mv")//此处测试modelAndView传参前端
28     public ModelAndView modelAndView(){
29         ModelAndView modelAndView = new ModelAndView();
30         modelAndView.addObject("id",1);
31         modelAndView.addObject("name","aini");
32         modelAndView.setViewName("demo");
33         return modelAndView;
34     }
35     @RequestMapping("/request")//此处测试request传参到服务端
36     public String request(HttpServletRequest request){
37         String id = request.getParameter("id");
38         String name = request.getParameter("name");
39         return "demo";//在此处打断点测试传参是否成功
40     }
41     @RequestMapping("/modelmap")//此处测试modelmap传参给页面
42     public String modelMap(ModelMap modelMap){
43         //给demo.jsp传参
44         User u = new User();
45         u.setId(1);
46         u.setName("xiaomingming");
47         modelMap.addAttribute("user",u);
48         return "demo";
49     }
50 
51     /**
52      * 此处用于测试json传值
53      * 我在studentServiceImpl中把这个方法插入了一个teacher
54      * 为了验证事务出错的回滚,如果之前teacher表中没有数据则不会回滚
55      */
56     @RequestMapping("/json")
57     public String json(@RequestBody Student student){
58         studentService.createStudent(student);//此处打断点debug查看student是否传入
59         return "demo";
60     }
61 
62 }

dao包里的使用mybatis-generator直接生成,一会讲。

 


 

Entity包中

Student类:

 1 package com.hellxz.entity;
 2 
 3 public class Student {
 4     private Integer sid;
 5 
 6     private String sname;
 7 
 8     private Integer ssex;
 9 
10     private Integer sage;
11 
12     private Integer steacherid;
13 
14     private Teacher teacher;
15 
16     public Teacher getTeacher() {
17         return teacher;
18     }
19 
20     public void setTeacher(Teacher teacher) {
21         this.teacher = teacher;
22     }
23 
24     public Integer getSid() {
25         return sid;
26     }
27 
28     public void setSid(Integer sid) {
29         this.sid = sid;
30     }
31 
32     public String getSname() {
33         return sname;
34     }
35 
36     public void setSname(String sname) {
37         this.sname = sname == null ? null : sname.trim();
38     }
39 
40     public Integer getSsex() {
41         return ssex;
42     }
43 
44     public void setSsex(Integer ssex) {
45         this.ssex = ssex;
46     }
47 
48     public Integer getSage() {
49         return sage;
50     }
51 
52     public void setSage(Integer sage) {
53         this.sage = sage;
54     }
55 
56     public Integer getSteacherid() {
57         return steacherid;
58     }
59 
60     public void setSteacherid(Integer steacherid) {
61         this.steacherid = steacherid;
62     }
63 }

teacher类:

 1 package com.hellxz.entity;
 2 
 3 import java.util.List;
 4 
 5 public class Teacher {
 6     private Integer tid;
 7 
 8     private String tname;
 9 
10     private String tusername;
11 
12     private String tpassword;
13 
14     private List student;
15 
16     public List getStudents() {
17         return student;
18     }
19 
20     public void setStudents(List students) {
21         this.student = students;
22     }
23 
24     public Integer getTid() {
25         return tid;
26     }
27 
28     public void setTid(Integer tid) {
29         this.tid = tid;
30     }
31 
32     public String getTname() {
33         return tname;
34     }
35 
36     public void setTname(String tname) {
37         this.tname = tname == null ? null : tname.trim();
38     }
39 
40     public String getTusername() {
41         return tusername;
42     }
43 
44     public void setTusername(String tusername) {
45         this.tusername = tusername == null ? null : tusername.trim();
46     }
47 
48     public String getTpassword() {
49         return tpassword;
50     }
51 
52     public void setTpassword(String tpassword) {
53         this.tpassword = tpassword == null ? null : tpassword.trim();
54     }
55 }
User类:

 1 package com.hellxz.entity;
 2 
 3 /**
 4  * Created by HELLXZ on 2017/8/2.
 5  */
 6 public class User {
 7     private int id;
 8     private String name;
 9 
10     public int getId() {
11         return id;
12     }
13 
14     public void setId(int id) {
15         this.id = id;
16     }
17 
18     public String getName() {
19         return name;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 }
 

 
 
Interceor包中
Interceptor类:
 1 package com.hellxz.interceptor;
 2 
 3 import org.springframework.web.servlet.HandlerInterceptor;
 4 import org.springframework.web.servlet.ModelAndView;
 5 
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 /**
10  * Created by HELLXZ on 2017/8/3.
11  */
12 public class Interceptor implements HandlerInterceptor{
13     @Override
14     public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
15         return true;
16     }
17 
18     @Override
19     public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
20         System.out.println("方法执行了");
21     }
22 
23     @Override
24     public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
25         System.out.println("方法结束了");
26     }
27 }
 


resource包中
jdbc.properties代码:

jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false
jdbc.username=root
jdbc.password=root
validationQuery=select 1

spring-config.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-4.0.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.0.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    
    <context:component-scan base-package="com.hellxz.*.**"/>
    
    <context:annotation-config/>
    
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    
    <context:property-placeholder location="classpath:com/hellxz/resource/jdbc.properties"/>
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:com/hellxz/dao/**.xml"/>
    bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.hellxz.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <property name="initialSize" value="5"/>
        <property name="minIdle" value="0"/>
        <property name="validationQuery" value="${validationQuery}"/>
        <property name="maxActive" value="20"/>
        <property name="maxWait" value="6000"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="1800"/>
    bean>



beans>

 

Spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation=" http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <context:component-scan base-package="com.hellxz.**"/>

    
    <context:component-scan base-package="com.hellxz.**">
        
        
        
        
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    context:component-scan>
    
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean id="jsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=utf-8value>
                        <value>application/json;charset=utf-8value>
                    list>
                property>
            bean>
        mvc:message-converters>
    mvc:annotation-driven>
    
    <mvc:annotation-driven/>
    
    <context:annotation-config/>
    
    <mvc:interceptors>
        
        <bean id="intercepter" class="com.hellxz.interceptor.Interceptor"/>
    mvc:interceptors>
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    bean>
    
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="500000"/>
        <property name="maxInMemorySize" value="1024000"/>
        <property name="defaultEncoding" value="utf-8"/>
    bean>
beans>

 


 

Service包:
StudentService接口:
 1 package com.hellxz.service;
 2 
 3 import com.hellxz.dao.StudentMapper;
 4 import com.hellxz.entity.Student;
 5 import org.springframework.stereotype.Service;
 6 
 7 /**
 8  * Created by HELLXZ on 2017/8/3.
 9  */
10 
11 public interface StudentService {
12 
13     int createStudent(Student student);
14 }
StudentServiceImpl类:

 1 package com.hellxz.service;
 2 
 3 import com.hellxz.dao.StudentMapper;
 4 import com.hellxz.dao.TeacherMapper;
 5 import com.hellxz.entity.Student;
 6 import com.hellxz.entity.Teacher;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.stereotype.Service;
 9 import org.springframework.transaction.annotation.Transactional;
10 import com.hellxz.service.StudentService;
11 /**
12  * Created by HELLXZ on 2017/8/3.
13  */
14 @Service("studentServiceImpl")
15 public class StudentServiceImpl  implements StudentService{
16     @Autowired
17     private StudentMapper studentMapper;
18     @Autowired
19     private TeacherMapper teacherMapper;
20     @Override
21     @Transactional
22     public int createStudent(Student student) {
23         studentMapper.insertSelective(student);
24         //后边的都是测试是否事务错误回滚,建议试一下,请先插入一条teacher数据,以确保出错!哈哈
25         Teacher teacher = new Teacher();
26         teacher.setTid(1);
27         teacher.setTname("小王");
28         teacher.setTusername("11111");
29         teacher.setTpassword("11111");
30         teacherMapper.insertSelective(teacher);
31         return 0;
32     }
33 }
TeacherService接口:

 1 package com.hellxz.service;
 2 
 3 import com.hellxz.entity.Teacher;
 4 
 5 /**
 6  * Created by HELLXZ on 2017/8/3.
 7  */
 8 public interface TeacherService {
 9     int createTeacher(Teacher teacher);
10 }
TeacherServiceImpl类:

 1 package com.hellxz.service;
 2 
 3 import com.hellxz.dao.TeacherMapper;
 4 import com.hellxz.entity.Teacher;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7 
 8 /**
 9  * Created by HELLXZ on 2017/8/3.
10  */
11 @Service("teacherServiceImpl")
12 public class TeacherServiceImpl implements TeacherService{
13     @Autowired
14     private TeacherMapper teacherMapper;
15     @Override
16     public int createTeacher(Teacher teacher) {
17         teacherMapper.insertSelective(teacher);
18         return 0;
19     }
20 }

 


 

web.xml:

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_3_1.xsd"
         version="3.1">
  
   <context-param>
       <param-name>contextConfigLocationparam-name>
       <param-value>classpath:com/hellxz/resource/spring-config.xmlparam-value>
   context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
    listener>
  
    <servlet>
        <servlet-name>ssmservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
      <init-param> <param-name>contextConfigLocationparam-name> <param-value>classpath:com/hellxz/resource/spring-mvc.xmlparam-value> init-param>
      <load-on-startup>1load-on-startup> servlet> <servlet-mapping> <servlet-name>ssmservlet-name> <url-pattern>/url-pattern> servlet-mapping> web-app>

 


 测试页面demo.jsp:

 1 <%--
 2   Created by IntelliJ IDEA.
 3   User: HELLXZ
 4   Date: 2017/8/2
 5   Time: 18:44
 6   To change this template use File | Settings | File Templates.
 7 --%>
 8 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 9 <html>
10 <head>
11     <title>Demotitle>
12 head>
13 <body>
14 Hello !! this page named Demo<br>
15 <%--接收modelmap--%>
16 ${user.id}<br>
17 ${user.name}<br>
18 <%--接收model and view--%>
19 ${id}<br>
20 ${name}<br>
21 body>
22 html>

 


 

下面说一下mybatis-generator的用法,我们来生成Mapper类和Mapperxml,请确保已经建表了!!!

SSM简单整合教程&测试事务_第5张图片

如图,随便找个地方新建个文件夹,把jdbc驱动还有mybatis-generator的jar包放进去
新建一个TXT,改名generatorConfig.xml,复制下面的代码,如果你要直接用在自己的项目里,请直接修改包的结构就好,很简单。
generatorConfig.xml:

 1 xml version="1.0" encoding="UTF-8" ?>
 2 DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
 3         "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
 4 <generatorConfiguration>
 5 
 6     
 7     <classPathEntry
 8             location="G:\mybatis-generator\mysql-connector-java-5.1.34.jar" />
 9 
10     <context id="MysqlTables" targetRuntime="MyBatis3">
11 
12         
13         
14 
15         
16         
17         <commentGenerator>
18             
19             <property name="suppressAllComments" value="true" />
20         commentGenerator>
21 
22         
23         
24         <jdbcConnection driverClass="com.mysql.jdbc.Driver"
25                         connectionURL="jdbc:mysql://localhost:3306/mybatis"
26                         userId="root" password="root">
27         jdbcConnection>
28 
29         
30         
31         
33         <javaTypeResolver>
34             <property name="forceBigDecimals" value="false" />
35         javaTypeResolver>
36 
37 
38         
39         
40         
41         <javaModelGenerator targetPackage="com.hellxz.entity"
42                             targetProject="src"
43                              >
44             
45             <property name="enableSubPackages" value="true" />
46             
47             <property name="trimStrings" value="true" />
48         javaModelGenerator>
49 
50         
51         
52         <sqlMapGenerator targetPackage="com.hellxz.dao"
53                          targetProject="src">
54             <property name="enableSubPackages" value="true" />
55         sqlMapGenerator>
56 
57         
58         
59         <javaClientGenerator targetPackage="com.hellxz.dao"
60                              targetProject="src"
61                              type="XMLMAPPER">
62             <property name="enableSubPackages" value="true" />
63         javaClientGenerator>
64 
65         
66         
67         
68         
69         <table  tableName="student" domainObjectName="Student"
70                 enableInsert="true" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"
71                 enableSelectByExample="false" selectByExampleQueryId="false">
72             
73             
74             
75             
76         table>
77         <table  tableName="teacher" domainObjectName="Teacher"
78                 enableInsert="true" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"
79                 enableSelectByExample="false" selectByExampleQueryId="false">
80             
81             
82             
83             
84         table>
85 
86 
87 
88 
89     context>
90 generatorConfiguration>

 

粘贴保存,然后运行—cmd   打开命令行,cd到此文件夹,执行如下代码:

java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml –overwrite
出现successful就已经成功了,把新生成的src文件加中的两个文件夹文件按照文章开头的文件结构放进去就好。
 

 
 
 配置完成,debug模式启动服务器,什么?你服务器不会配置?出门左转百度吧老兄!
 

SSM简单整合教程&测试事务_第6张图片

这样子就算成功了,下面进行测试

 
 
起一个浏览器输入localhost:8080/user/demo 回车,(elipse需要在/user前加项目名,这里用idea),如果进入此界面则说明springMVC正常
SSM简单整合教程&测试事务_第7张图片

 
 
下面只需要测试Spring的事务是否正常了
我们先捋一下流程(还不会画思维导图,谅解):
发送json —-> controller解析处理封装student —-> 找到RequestMapping(”/json”)
—-> 打断点查看student对象是否正确,继续,调用studentService的createStudent()—-> 找到studentServiceIml调用具体方法
—-> 方法中调用了mybatis的mapper的方法,同时我们加了条坏数据插入到teacher表 —-> 如果两条数据都没有插进去,则说明spring事务正常,同一事务中的只要有错误就会回滚了
 

 
 
好,我们开始:
使用postman向localhost:8080/user/json发送如下json语句,如图
SSM简单整合教程&测试事务_第8张图片
注意json用的是花括号!如果你已经给student插数据了,那么请找个没有使用的sid
SSM简单整合教程&测试事务_第9张图片
可以看见已经传了个student对象进来了,先别继续,查看数据库
 
我们看到student表中还是空的,这么说来,sid=1是可以插进来的,当然teacher里一定要有一条数据哦~

 


剩下的大家可以打断点继续跟踪,我这继续说就有点侮辱大家智商了,方法执行完毕后我们再来查看数据是否正常

 


不出所料,student表中并没有插入数据,事务回滚成功!
如果有疑问,比如说怀疑根本没连上mybatis,或者说本来就插不进去,那么请删除teacher表中的所有数据,再postman发一下json查看一下,囧,我已经做了,见下图
Student

 


Teacher

 


我们再捋一下流程:
我们使用postman发送一条json到localhost:8080/user/json,
这条数据会在DemoController中进行解析,封装成一个student对象,因为我们已经注入了StudentService对象,我们把student对象传给他,因为是接口,会传给StudentServiceImpl实现类,实现类中我们先使用StudentMapper对象通过mybatis向数据库插入刚才传过来的对象,自动解析成数据插值,在刚才的方法下边我们故意弄了一条错误的teacher数据。
如果看了我写的建表SQL语句可能会好奇:为什么我要插入一条teacher数据?其实原因很简单,teacher的主键是自增的,我插入已经占用的主键的值肯定是错误的,我们要测试的是spring的事务,如果同一个事务中有多条数据进行插值,如果有一条错误我们想让它们同时完成或者同时不完成,那么这就很有用了。正常来讲,查询数据库你会发现这两条都没有插入。
 
如果想试试事务失效是什么样子,请手动修改spring-mvc.xml中的代码

    <context:component-scan base-package="com.hellxz.**">
        
        
        
        
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    context:component-scan>

改为:

1 <context:component-scan base-package="com.hellxz.**"/>

好了,这就是我为大家准备的ssm教程。第一次写,写了好几个小时-_-||
controller中还有几个测试传参的有兴趣可以试验下
 
 
源码包就是我的项目直接拿出来的,不知道博客园有没有专门上传附件的地方,传到百度云了
源码是我之前输入法有问题写的注释,xml注释大多用的英文的,具体请参考本贴
链接:http://pan.baidu.com/s/1min414W
[hide]密码:6v6s[/hide]
 
 

 

                                                             第一次编辑2017-08-03 22:30:23

 

你可能感兴趣的:(SSM简单整合教程&测试事务)