`

mybatis编程事务管理参考一

阅读更多
 MyBatis与Spring集成示例续——MyBatis学习笔记之六
2012-08-06 23:53:25

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://legend2011.blog.51cto.com/3018495/956585

      限于篇幅,MyBatis与Spring集成的一些细节在上篇博文中并未提及,今天继续。

一、引子
      前面的博文介绍了如何查询一个具有has-a关系的实体,今天就来看看如何向数据库中插入这样的一个实体。仍以学生为例,现在的问题是:学生实体把教师对象作为自己的指导教师属性,然而在学生表中,却仅有指导教师的ID一列,这如何映射呢?
      解决的方法其实很简单(这个方法是笔者猜出来的,哈哈,得瑟中…),关键在于在StudentMapper.xml中如下编写insert语句:
 
  1. <insert id="add" parameterType="Student" 
  2.         useGeneratedKeys="true" keyProperty="id"> 
  3.           insert into student(name,gender,major,grade,supervisor_id)  
  4.           values(#{name},#{gender},#{major},#{grade},#{supervisor.id})  
  5.      </insert> 

       这里的关键是使用了supervisor.id这样的写法,这表明是把学生实体的supervisor属性的id属性值,作为插入的记录的supervisor_id字段的值。其他地方与之前的插入示例一致(MyBatis增删改示例)。

      当然在StudentMapper.java中插入实体的方法声明是少不了的,如下:
 
  1. public void add(Student student); 

       执行程序如下:

  1. package com.demo;  
  2.  
  3. import org.springframework.context.ApplicationContext;  
  4. import com.abc.mapper.StudentMapper;  
  5. import com.abc.domain.Student;  
  6. import com.abc.domain.Teacher;  
  7. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  8.  
  9. public class MyBatisSpringDemo  
  10. {  
  11.     private static ApplicationContext ctx;  
  12.       
  13.     static 
  14.     {  
  15.         //在类路径下寻找resources/beans.xml文件  
  16.         ctx = new ClassPathXmlApplicationContext("resources/beans.xml");  
  17.     }  
  18.       
  19.       
  20.     public static void main(String[] args)  
  21.     {  
  22.         StudentMapper mapper =   
  23.                (StudentMapper)ctx.getBean("studentMapper");  
  24.  
  25.         Student student = new Student();  
  26.  
  27.         student.setName("李林");  
  28.         student.setGender("男");  
  29.         student.setMajor("计算机科学与技术");  
  30.         student.setGrade("2011");  
  31.         Teacher supervisor = new Teacher();  
  32.         supervisor.setId(1);  
  33.         student.setSupervisor(supervisor);  
  34.           
  35.         mapper.add(student);  
  36.           
  37.     }  
  38.  

       执行后,登录MySQL查询。如下图所示:

 (注:第一个红框里的命令“set names gbk”是为了能够显示中文。)

      从第二个和第三个红框之间的对比可以看出,数据已被写入到数据库(点此进入无事务处理的源码下载页面)。
二、事务管理

     在上面的示例中,并没有为程序配置事务管理器,而在程序中也不像以前的示例那样调用了提交事务的方法,但数据却已实实在在地被写入到了数据库中。这是怎么回事呢?mybatis官方文档告诉我们,凡是在Spring事务之外执行的映射器方法,都会被自动提交(英文可参见http://www.mybatis.org/spring/transactions.html中的“Programmatic Transaction Management”部分,中文可参见http://www.mybatis.org/spring/zh/transactions.html中的“编程式事务管理”部分)。这样一来,就没有用上Spring强大的事务管理功能。Spring事务管理提供声明式(declarative)和编程式(programmatic)两种方式。今天就先给大家介绍一下编程式的基本用法(虽然声明式是最常用的方式,但是发现想把它说清楚不是那么容易滴,留待以后有机会再详述吧)。

      首先在Spring的配置文件(本例中为beans.xml)中配置MyBatis-Spring要用到的事务管理器,即org.springframework.jdbc.datasource.DataSourceTransactionManager。配置内容如下: 
 
  1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
  2.   <property name="dataSource" ref="dataSource" /> 
  3. </bean> 

      在这里,事务管理器引用了在前面配置的数据源dataSource。显而易见,这个数据源必须是事务管理器所管理的事务将要操作的那个数据源。也就是说,应该与SqlSessionFactoryBean引用同一个数据源。因为我们正是由SqlSessionFactoryBean来获得映射器,进而调用映射器的方法来对数据库进行操作。

      需要注意的是,Spring对事务管理做了抽象,提供了统一的编程接口。例如上述的DataSourceTransactionManager事务管理器,实际上是实现了接口org.springframework.transaction.PlatformTransactionManager。针对不同的环境,Spring提供了不同的实现。例如,对于Hibernate,可使用事务管理器org.springframework.orm.hibernate3.HibernateTransactionManager。与此相关的接口还有org.springframework.transaction.TransactionDefinition和org.springframework.transaction.TransactionStatus,分别代表事务的定义和事务的状态。提供统一接口的好处是我们只需要针对这个接口编程,而无需考虑不同环境下事务处理的不同细节。

      编程式事务管理代码如下:

  1. package com.demo;  
  2.  
  3. import org.springframework.context.ApplicationContext;  
  4. import com.abc.mapper.StudentMapper;  
  5. import com.abc.domain.Student;  
  6. import com.abc.domain.Teacher;  
  7. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  8. import org.springframework.transaction.support.DefaultTransactionDefinition;  
  9. import org.springframework.transaction.TransactionDefinition;  
  10. import org.springframework.transaction.TransactionStatus;  
  11. import org.springframework.transaction.PlatformTransactionManager;  
  12. import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
  13.  
  14. public class MyBatisSpringDemo  
  15. {  
  16.     private static ApplicationContext ctx;  
  17.       
  18.     static 
  19.     {  
  20.         //在类路径下寻找resources/beans.xml文件  
  21.         ctx = new ClassPathXmlApplicationContext("resources/beans.xml");  
  22.     }  
  23.       
  24.       
  25.     public static void main(String[] args)  
  26.     {  
  27.         //从Spring容器中请求映射器  
  28.         StudentMapper mapper =   
  29.                (StudentMapper)ctx.getBean("studentMapper");  
  30.  
  31.         //从Spring容器中请求事务管理器,用PlatformTransactionManager  
  32.         //类型的引用指向它  
  33.         PlatformTransactionManager tm =  
  34.                (PlatformTransactionManager)ctx.getBean("transactionManager");  
  35.  
  36.         Student student = new Student();  
  37.         student.setName("王芳");  
  38.         student.setGender("女");  
  39.         student.setMajor("计算机科学与技术");  
  40.         student.setGrade("2011");  
  41.         Teacher supervisor = new Teacher();  
  42.         supervisor.setId(1);  
  43.         student.setSupervisor(supervisor);  
  44.           
  45.         //TransactionDefinition对象代表着事务的定义,即事务的传播行为,  
  46.         //隔离级别和是否可读等属性。DefaultTransactionDefinition是此  
  47.         //接口的默认实现,给上述属性指定了默认值。如传播行为是PROPAGATION_REQUIRED,  
  48.         //只读为false等(可参见Spring api文档)  
  49.         TransactionDefinition def = new DefaultTransactionDefinition();  
  50.           
  51.         //TransactionStatus对象代表着事务的状态。以下代码根据传入的事务定义  
  52.         //对象返回事务并启动事务  
  53.         TransactionStatus status = (TransactionStatus)tm.getTransaction(def);  
  54.  
  55.         try {  
  56.            mapper.add(student);  
  57.            //若执行下述语句,则事务回滚。  
  58.            //读者可自行验证  
  59.            //int a = 1/0;  
  60.             }  
  61.         catch (Exception e) {  
  62.            //回滚事务  
  63.            tm.rollback(status);  
  64.            e.printStackTrace();  
  65.         }  
  66.  
  67.         //提交事务  
  68.         tm.commit(status);  
  69.           
  70.     }  
  71.  

      执行结果如下:

       查询数据库如下图所示:

       显然,数据已被写入。

三、使用bean继承配置映射器

      当我们需要在beans.xml中配置多个映射器时,它们的class和sqlSessionFactory属性都是一样的(也许还有其它一样的属性)。显然,我们需要消除这种冗余信息。借助于bean继承机制,我们可以达到这个目的。如下所示:
  1. <bean id="parentMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" 
  2.    abstract="true"> 
  3.      <!--sqlSessionFactory属性指定要用到的SqlSessionFactory实例--> 
  4.      <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 
  5.   </bean> 
  6.  
  7.   <bean id="studentMapper" parent="parentMapper"> 
  8.      <!--mapperInterface属性指定映射器接口,用于实现此接口并生成映射器对象--> 
  9.      <property name="mapperInterface" value="com.abc.mapper.StudentMapper" /> 
  10. </bean> 

      这里的关键是把父bean parentMapper的abstract属性指定为true。这样,Spring就不会创建这个bean实例。它存在的意义是配置好class和sqlSessionFactory这两个属性,供其他子bean继承。而子bean通过把parent属性设置为parentMapper,即可继承这两个属性(点此进入有编程式事务处理和bean继承的源码)。


【MyBatis学习笔记】系列之预备篇一:ant的下载与安装

【MyBatis学习笔记】系列之预备篇二:ant入门示例

【MyBatis学习笔记】系列之一:MyBatis入门示例

【MyBatis学习笔记】系列之二:MyBatis增删改示例

【MyBatis学习笔记】系列之三:MyBatis的association示例

【MyBatis学习笔记】系列之四:MyBatis association的两种形式

【MyBatis学习笔记】系列之五:MyBatis与Spring集成示例

【MyBatis学习笔记】系列之六:MyBatis与Spring集成示例续

【MyBatis学习笔记】系列之七:MyBatis一对多双向关联

【MyBatis学习笔记】系列之八:MyBatis MapperScannerConfigurer配置

【MyBatis学习笔记】系列之九:MyBatis collection的两种形式

【MyBatis学习笔记】系列之十:MyBatis日志之Log4j示例

【MyBatis学习笔记】系列之十一:MyBatis多参数传递之注解方式示例

【MyBatis学习笔记】系列之十二:MyBatis多参数传递之默认命名方式示例

【MyBatis学习笔记】系列之十三:MyBatis多参数传递之Map方式示例

【MyBatis学习笔记】系列之十四:MyBatis中的N+1问题

【MyBatis学习笔记】系列之十五:MyBatis多参数传递之混合方式

本文出自 “肖凡的专栏” 博客,请务必保留此出处http://legend2011.blog.51cto.com/3018495/956585

分享到:
评论

相关推荐

    mybatis中文参考手册

    同时,MyBatis也支持编程式事务管理,允许开发者手动控制事务的提交和回滚。 在MyBatis中,SqlSession是执行SQL操作的主要接口,它提供了插入、更新、删除和查询等方法。而SqlSessionFactory则负责创建SqlSession...

    mybatis-3.4.5官方参考文档(中文版)

    MyBatis的配置一般从一个XML文件开始,其中配置了数据库连接信息、事务管理器等核心设置。MyBatis使用SqlSessionFactory作为SQL会话的工厂,可以从中获取SqlSession实例,而SqlSessionFactory则可以通过...

    MyBatis_3.4.6中文参考

    - **示例配置**:一个典型的配置文件包括数据源(DataSource)和事务管理器(TransactionManager)的配置,以及 mapper 映射器的定义。 ```xml &lt;!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//...

    springMVC+Mybatis 参考资料(一)

    Spring框架提供了SpringMVC和Mybatis的整合方式,如使用Spring的声明式事务管理,可以在Spring配置中统一管理事务的开始、提交、回滚。同时,Spring还可以通过@Autowired注解自动注入Mybatis的Mapper接口,简化了...

    mybatis3.4官方中文文档

    MyBatis的事务管理可以通过编程式和声明式两种方式实现,声明式通常结合Spring框架进行配置。 12. **插件机制** MyBatis允许用户自定义插件,通过拦截器模式对SqlSession的方法进行增强,如性能分析、日志记录等...

    spring+struts+mybatis的一个demo,酒店客房管理系统

    这是一个基于Spring、Struts和MyBatis(SSI框架)整合的酒店客房管理系统的演示项目。这个系统展示了如何在实际开发中运用这三个主流的Java Web框架,以实现一个完整的业务流程。下面将详细介绍其中涉及的关键知识点...

    管理系统系列--SSM(Spring+SpringMVC+Mybatis)新闻管理系统.zip

    总的来说,"管理系统系列--SSM(Spring+SpringMVC+Mybatis)新闻管理系统"是一个全面展示SSM集成的实例,对于学习和理解Java Web开发具有很高的参考价值。通过研究和实践这个项目,开发者可以深入理解如何将这三个强大...

    myBatis官方文档

    myBatis支持编程式事务管理和声明式事务管理。编程式事务管理通过SqlSession对象手动提交或回滚事务,声明式事务管理则依赖于Spring等容器来管理事务的开始、提交和回滚。 **9. 缓存机制** myBatis内置了两级缓存,...

    spring+mybatis 简单实例图书管理系统

    Spring是一个全面的后端开发框架,提供了依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)等核心功能,同时也支持事务管理、数据访问、Web MVC等。Spring框架简化了Java...

    01_mybatis.rar

    MyBatis支持编程式和声明式事务管理。编程式事务管理需要在代码中显式控制事务的开始、提交和回滚;声明式事务管理则依赖于容器如Spring,可以在配置文件中声明事务边界。 9. **缓存机制**: MyBatis提供了本地...

    Mybatis3.5.2参考文档.pdf

    - MyBatis-3-config.xml:MyBatis的全局配置文件,包含系统运行环境的配置、数据库连接池、事务管理器、映射器等配置信息。 5. 不使用XML配置MyBatis MyBatis同样允许开发者通过Java代码直接创建配置,创建自己的...

    JAVA SpringMVC+mybatis

    综上所述,该案例不仅涵盖了SpringMVC、MyBatis等核心框架的应用,还涉及了数据库连接池、事务管理以及一系列实用工具和技术点的使用,对于希望快速搭建高性能Web应用的开发者来说具有很高的参考价值。

    SpringBoot+Thymeleaf+MyBatis制作的校园事务管理系统.zip

    标题 "SpringBoot+Thymeleaf+MyBatis制作的校园事务管理系统.zip" 提供了我们正在探讨的是一个使用特定技术栈开发的校园事务管理系统的源码。这个系统利用了SpringBoot作为主要的后端框架,Thymeleaf作为前端模板...

    mybatis 中文参考手册

    首先,MyBatis的中文参考手册是一份详细的学习文档,旨在帮助开发者学习如何使用MyBatis进行数据库操作。手册内容清晰,讲解详细,覆盖了从基础到高级的各种用法,包括XML映射配置、注解配置以及动态SQL等重要知识点...

    mybatis-3.4.6.jar

    此外,提供的PDF参考文档是MyBatis的官方文档,对于开发者来说非常宝贵,可以帮助他们理解和使用MyBatis的各种特性,包括SQL映射文件的编写、动态SQL、事务管理、缓存机制等。 在MyBatis中,SQL映射文件通常以XML...

    MyBatis3.4.1 jar包全

    7. **事务管理**:MyBatis支持编程式和声明式事务管理。编程式事务管理需要在代码中手动控制事务的开始、提交和回滚,而声明式事务管理可以通过Spring等框架进行配置。 8. **插件支持**:MyBatis允许开发自定义插件...

    mybatis-3.2.8 java api

    MyBatis支持编程式和声明式事务管理。编程式事务管理需要在代码中显式调用开始、提交或回滚事务;声明式事务管理则可以通过Spring等框架进行配置,更加简洁。 **7. MyBatis-Spring集成** MyBatis可以与Spring框架...

    MyBatis 3 用户指南中文英文

    MyBatis支持编程式事务管理和声明式事务管理,可以根据实际需求选择合适的事务控制方式。 九、MyBatis与Spring集成 MyBatis可以无缝集成Spring框架,通过Spring的TransactionManager进行事务管理,简化了事务处理。...

    Mybatis通用增删改查

    在Mybatis中,事务管理可以通过编程式或声明式两种方式实现。编程式事务管理需要在代码中显式地开启、提交或回滚事务,而声明式事务管理则可以借助Spring等框架进行配置,让事务管理更加简洁和易于维护。 6. **...

Global site tag (gtag.js) - Google Analytics