MyBatis与Spring集成示例续——MyBatis学习笔记之六

简介:

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

一、引子

      前面的博文介绍了如何查询一个具有has-a关系的实体,今天就来看看如何向数据库中插入这样的一个实体。仍以学生为例,现在的问题是:学生实体把教师对象作为自己的指导教师属性,然而在学生表中,却仅有指导教师的ID一列,这如何映射呢?

      解决的方法其实很简单(这个方法是笔者猜出来的,哈哈,得瑟中…),关键在于在StudentMapper.xml中如下编写insert语句:

1
2
3
4
5
< insert  id = "add"  parameterType = "Student"
useGeneratedKeys = "true"  keyProperty = "id" >
insert into student(name,gender,major,grade,supervisor_id)
values(#{name},#{gender},#{major},#{grade},#{supervisor.id})
</ insert >

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

      当然在StudentMapper.java中插入实体的方法声明是少不了的,如下:

1
public  void  add(Student student);

      执行程序如下:

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

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

233948189.png

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

      执行结果如下:

234800981.png

       查询数据库如下图所示:

234845279.png

       显然,数据已被写入。

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

      当我们需要在beans.xml中配置多个映射器时,它们的class和sqlSessionFactory属性都是一样的(也许还有其它一样的属性)。显然,我们需要消除这种冗余信息。借助于bean继承机制,我们可以达到这个目的。如下所示:

1
2
3
4
5
6
7
8
9
< bean  id = "parentMapper"  class = "org.mybatis.spring.mapper.MapperFactoryBean"
abstract = "true" >
<!--sqlSessionFactory属性指定要用到的SqlSessionFactory实例-->
< property  name = "sqlSessionFactory"  ref = "sqlSessionFactory" />
</ bean >
< bean  id = "studentMapper"  parent = "parentMapper" >
<!--mapperInterface属性指定映射器接口,用于实现此接口并生成映射器对象-->
< property  name = "mapperInterface"  value = "com.abc.mapper.StudentMapper" />
</ bean >

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










本文转自 NashMaster2011 51CTO博客,原文链接:http://blog.51cto.com/legend2011/956585,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
295 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
2月前
|
Java 数据库连接 数据库
spring复习05,spring整合mybatis,声明式事务
这篇文章详细介绍了如何在Spring框架中整合MyBatis以及如何配置声明式事务。主要内容包括:在Maven项目中添加依赖、创建实体类和Mapper接口、配置MyBatis核心配置文件和映射文件、配置数据源、创建sqlSessionFactory和sqlSessionTemplate、实现Mapper接口、配置声明式事务以及测试使用。此外,还解释了声明式事务的传播行为、隔离级别、只读提示和事务超时期间等概念。
spring复习05,spring整合mybatis,声明式事务
|
1月前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
69 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
1月前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
|
1月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
43 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
1月前
|
Java 数据库连接 mybatis
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
该文档详细介绍了如何在Springboot Web项目中整合Mybatis,包括添加依赖、使用`@MapperScan`注解配置包扫描路径等步骤。若未使用`@MapperScan`,系统会自动扫描加了`@Mapper`注解的接口;若使用了`@MapperScan`,则按指定路径扫描。文档还深入分析了相关源码,解释了不同情况下的扫描逻辑与优先级,帮助理解Mybatis在Springboot项目中的自动配置机制。
127 0
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
|
2月前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
|
2月前
|
SQL XML Java
springboot整合mybatis-plus及mybatis-plus分页插件的使用
这篇文章介绍了如何在Spring Boot项目中整合MyBatis-Plus及其分页插件,包括依赖引入、配置文件编写、SQL表创建、Mapper层、Service层、Controller层的创建,以及分页插件的使用和数据展示HTML页面的编写。
springboot整合mybatis-plus及mybatis-plus分页插件的使用
|
2月前
|
XML Java 数据库连接
springboot中整合mybatis及简单使用
这篇文章介绍了如何在Spring Boot项目中整合MyBatis,包括依赖引入、配置数据源、创建测试表、编写Mapper接口和XML文件、以及创建Service和Controller层的步骤。
springboot中整合mybatis及简单使用
|
1月前
|
Java 数据库连接 Maven
Spring整合Mybatis
Spring整合Mybatis