SSM简单整合教程&测试事务
自打来了博客园就一直在看帖,学到了很多知识,打算开始记录的学习到的知识点
今天我来写个整合SpringMVC4 spring4 mybatis3&测试spring事务的教程,如果有误之处,还请批评指正。
本文是原创文章,转载请注明出处
一、准备工作:
开发环境:
- idea(源码文章最后会给出,不下载也一样,下边都贴出来了)
- MySQL 5.7
- Tomcat 8.5
- Google chrome的插件postman(发送json数据)
- navicat for MySQL(用MySQL命令行也行)
本教程用到的jar包如下(源码中本文中用到所有jar都已经给出):
Spring以及springMVC的jar包:
Mybatis的jar包&mybatis兼容spring的jar以及jdbc驱动:
使用的数据源源为阿里巴巴的druid,和fastjson解析json
Tomcat8.5,这个一般的IDE都不用管,配置好就可以
文件上传下载的支持,本教程中没有写,如果有时间我会补上
Mybatis-generator 自动生成Mapper和mapper.xml用的
二、文件结构
三、建表:
建表语句等已经存在了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> student; 15 16 public List<Student> getStudents() { 17 return student; 18 } 19 20 public void setStudents(List<Student> 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"/> <!--定位jdbc.properties 配置文件--> <context:property-placeholder location="classpath:com/hellxz/resource/jdbc.properties"/> <!--创建sqlSessionFactory并指定dataSource & *mapper.xml的路径--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:com/hellxz/dao/**.xml"/> </bean> <!--mybatis加载Mapper扫描配置器,指定Mapper类的包,不能用classpath:来指定!!--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.hellxz.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> <!--开启spring事务支持--> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--使用阿里巴巴的druid数据源, 别的数据源请另行参考--> <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.**"> <!--作为spring的子容器,springMVC不具有事务能力,即无法处理@service注解的事务rollback操作--> <!--如果在同一事务下的两个操作,其中有一条错误,那么理应受spring事务管理,一起rollback--> <!--如果仅仅写为<context:component-scan base-package="com.hellxz.**"/>--> <!--spring作为父容器会失去处理事务的能力,相当于被springMVC抢了--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan> <!--使用fastjson解析json数据,需要注意的是一定要写在<mvc:annotation-driven前,否则失去解析作用--> <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-8</value> <value>application/json;charset=utf-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!--开启MVC注解支持--> <mvc:annotation-driven/> <!--加载上下文注解配置--> <context:annotation-config/> <!--指明springmvc拦截器位置--> <mvc:interceptors> <!--全局拦截--> <bean id="intercepter" class="com.hellxz.interceptor.Interceptor"/> </mvc:interceptors> <!--视图解析器,controller返回的字符串在这里加上前缀&后缀,才能作为请求进入浏览器,最下方添加了jstl语句的支持--> <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"> <!--上下文配置定位,定位spring的配置文件,并加上监听器--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:com/hellxz/resource/spring-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--springMVC的分派servlet--> <servlet> <servlet-name>ssm</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--在servlet启动的时候加载springMVC的配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:com/hellxz/resource/spring-mvc.xml</param-value> </init-param>
<!--启动顺序1,表示优先加载--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ssm</servlet-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>Demo</title> 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,请确保已经建表了!!!
如图,随便找个地方新建个文件夹,把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 <!--classPathEntry:数据库的JDBC驱动 --> 7 <classPathEntry 8 location="G:\mybatis-generator\mysql-connector-java-5.1.34.jar" /> 9 10 <context id="MysqlTables" targetRuntime="MyBatis3"> 11 12 <!-- 注意这里面的顺序确定的,不能随变更改 --> 13 <!-- 自定义的分页插件 <plugin type="com.deppon.foss.module.helloworld.shared.PaginationPlugin"/> --> 14 15 <!-- 可选的(0 or 1) --> 16 <!-- 注释生成器 --> 17 <commentGenerator> 18 <!-- 是否去除自动生成的注释 true:是 : false:否 --> 19 <property name="suppressAllComments" value="true" /> 20 </commentGenerator> 21 22 <!-- 必须的(1 required) --> 23 <!--数据库连接的信息:驱动类、连接地址、用户名、密码 --> 24 <jdbcConnection driverClass="com.mysql.jdbc.Driver" 25 connectionURL="jdbc:mysql://localhost:3306/mybatis" 26 userId="root" password="root"> 27 </jdbcConnection> 28 29 <!-- 可选的(0 or 1) --> 30 <!-- 类型转换器或者加类型解析器 --> 31 <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把JDBC DECIMAL 和 32 NUMERIC 类型解析为java.math.BigDecimal --> 33 <javaTypeResolver> 34 <property name="forceBigDecimals" value="false" /> 35 </javaTypeResolver> 36 37 38 <!-- 必须的(1 required) --> 39 <!-- java模型生成器 --> 40 <!-- targetProject:自动生成代码的位置 --> 41 <javaModelGenerator targetPackage="com.hellxz.entity" 42 targetProject="src" 43 > 44 <!-- TODO enableSubPackages:是否让schema作为包的后缀 --> 45 <property name="enableSubPackages" value="true" /> 46 <!-- 从数据库返回的值被清理前后的空格 --> 47 <property name="trimStrings" value="true" /> 48 </javaModelGenerator> 49 50 <!-- 必须的(1 required) --> 51 <!-- map xml 生成器 --> 52 <sqlMapGenerator targetPackage="com.hellxz.dao" 53 targetProject="src"> 54 <property name="enableSubPackages" value="true" /> 55 </sqlMapGenerator> 56 57 <!-- 可选的(0 or 1) --> 58 <!-- mapper 或者就是dao接口生成器 --> 59 <javaClientGenerator targetPackage="com.hellxz.dao" 60 targetProject="src" 61 type="XMLMAPPER"> 62 <property name="enableSubPackages" value="true" /> 63 </javaClientGenerator> 64 65 <!-- 必须的(1...N) --> 66 <!-- pojo 实体生成器 --> 67 <!-- tableName:用于自动生成代码的数据库表;domainObjectName:对应于数据库表的javaBean类名 --> 68 <!-- schema即为数据库名 可不写 --> 69 <table tableName="student" domainObjectName="Student" 70 enableInsert="true" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" 71 enableSelectByExample="false" selectByExampleQueryId="false"> 72 <!-- 忽略字段 可选的(0 or 1) --> 73 <!-- <ignoreColumn column="is_use" /> --> 74 <!--//无论字段是什么类型,生成的类属性都是varchar。 可选的(0 or 1) 测试无效 --> 75 <!-- <columnOverride column="city_code" jdbcType="VARCHAR" /> --> 76 </table> 77 <table tableName="teacher" domainObjectName="Teacher" 78 enableInsert="true" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" 79 enableSelectByExample="false" selectByExampleQueryId="false"> 80 <!-- 忽略字段 可选的(0 or 1) --> 81 <!-- <ignoreColumn column="is_use" /> --> 82 <!--//无论字段是什么类型,生成的类属性都是varchar。 可选的(0 or 1) 测试无效 --> 83 <!-- <columnOverride column="city_code" jdbcType="VARCHAR" /> --> 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模式启动服务器,什么?你服务器不会配置?出门左转百度吧老兄!
这样子就算成功了,下面进行测试
起一个浏览器输入localhost:8080/user/demo 回车,(elipse需要在/user前加项目名,这里用idea),如果进入此界面则说明springMVC正常
下面只需要测试Spring的事务是否正常了
我们先捋一下流程(还不会画思维导图,谅解):
发送json —-> controller解析处理封装student —-> 找到RequestMapping(”/json”)
—-> 打断点查看student对象是否正确,继续,调用studentService的createStudent()—-> 找到studentServiceIml调用具体方法
—-> 方法中调用了mybatis的mapper的方法,同时我们加了条坏数据插入到teacher表 —-> 如果两条数据都没有插进去,则说明spring事务正常,同一事务中的只要有错误就会回滚了
好,我们开始:
使用postman向localhost:8080/user/json发送如下json语句,如图
注意json用的是花括号!如果你已经给student插数据了,那么请找个没有使用的sid
可以看见已经传了个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中的代码
<!--open package scanner--> <context:component-scan base-package="com.hellxz.**"> <!--if you do not set this data, when you insert two transaction together and one of them is error--> <!--and you want to if correct let them all succeed or false all rollback, you must set this--> <!--you do not set unless you want one data succeed and one false--> <!--it means springmvc has no transaction power of "@Service", but Spring has it.--> <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