深入浅出MyBatis:MyBatis与Spring集成及实用场景

本系列是「深入浅出MyBatis:技术原理与实践」书籍的总结笔记。

本篇是「深入浅出MyBatis」系列的最后一篇,主要介绍与Spring的集成,以及工作中的一些实用场景。

介绍之前,先整体总结下该系列的内容和写作思路。

MyBatis是一个框架,封装了数据库相关的操作,给我们开发人员带来了极大地便利,相对于Hibernate,有很大的灵活性和扩展性,在高并发高性能应用中,这点很重要。

首先介绍了JDBC的规范,了解我们最原始最熟悉的操作数据库的方式,MyBatis就是在此基础上进行封装和抽象。

然后,介绍了MyBatis的特性和核心组件,对其有个整体了解。

之后,详解介绍了MyBatis的配置、映射器,它们是平时使用、接触最多的,可以很好的使用MyBatis进行开发了。

最后,回顾了反射和动态代理基础,深入分析了MyBatis的解析和运行原理,插件及开发过程,一方面对MyBatis的核心组件有更深入的了解,一方面可以更好进行插件的开发,对sql进行统一处理。

实际使用中,往往会和Spring集成一起使用,可以减少我们的工作量,通过本篇的介绍,你会了解到:

  • Spring的基础知识:IOC、AOP、事务管理;
  • MyBatis-Spring应用:配置和集成
  • 实用场景介绍

Spring IOC和AOP

了解Spring的基础,有助于理解集成配置,Spring技术主要由IOC和AOP两个基础功能构成。

IOC

IOC称为控制反转,可以这样理解:以前我们获取一个类的对象,都是去new一个,必须确定实现类是哪个,有了IOC,所有配置为Spring管理的对象都由Spring管理,包括对象的创建和生命周期,这样,去获取类的对象时,不需要显示指定,由Spring去决定返回哪个对象。

这样,对象的创建,控制权由业务代码转向给了Spring,称为控制反转。

AOP

AOP称为面向切面编程,所谓切面,是说在正常逻辑中插入一些逻辑处理代码,比如插入日志记录、事务管理等代码,其中,日志记录和事务管理就是切面。Spring AOP可以在不修改原有方法逻辑的情况下,通过简单配置,对受影响的类方法统一插入切面处理代码。

Spring AOP是通过动态代理实现的,当Spring的服务包含接口描述时,采用JDK动态代理,否则采用CGLIB代理。

最后,简单说明下AOP相关的概念,便于理解它的配置:

  • 切入点:Spring生成代理对象后,当调用服务方法时,会调用InvitationHandler的invoke方法,需要拦截哪些方法,进行特殊处理呢,这就是切入点,Spring可以通过正则进行配置;
  • 切面:上面已经介绍了,日志记录、事务管理等需要处理的逻辑对象,就是切面;
  • 连接点:它是在程序运行中根据不同的通知来实现的程序段,通知包括,前置通知、后置通知、异常后通知、正常返回后通知、环绕通知;

Spring 事务管理

在编写业务代码时,一个业务方法可能涉及多张表或多条sql语句,同一条表数据可能会被同时访问,数据库的事务控制很重要,通过Spring AOP和Spring 事务管理,可以大量减少我们的代码,对各种场景的事务管理也很方便。

事务隔离级别
  • 读未提交:可能出现脏读问题,一个事务读取另一个事务未提交的数据;
  • 读已提交:可能出现不可重复读问题,针对同一条记录,同一个事务前后可能读取不同的数据;
  • 可重复读:可能出现幻读问题,针对删除和插入记录,同一个查询条件,同一个事务返回的记录数可能不同;
  • 序列化:所有操作会按顺序执行;

MySql默认隔离级别为可重复读。

传播行为

传播行为,是指方法之间的调用,事务如何传递,在Spring中定义了7种传播行为,可根据不同场景进行配置,不一一介绍了,举几个说明下:

  • PROPAGATION_REQUIRED:如果存在一个事务,则使用当前事务,否则开启一个事务;
  • PROPAGATION_SUPPORTS:如果存在一个事务,则支持当前事务,否则以非事务执行;
  • PROPAGATION_REQUIRES_NEW:总是开启一个新的事务,即使有一个事务存在;
  • PROPAGATION_NOT_SUPPORTED:总是以非事务执行,挂起已存在的事物;

Spring默认的传播行为为PROPAGATION_REQUIRED。

MyBatis-Spring集成配置

了解了Spring的IOC,进行集成配置就比较简单了,另外,除了业务SQL的编写,事务是很重要的一部分,Spring AOP和事务管理帮我们解决了。

MyBatis提供了和Spring无缝对接的功能,主要通过mybatis-spring-x.x.x.jar实现,下面说下集成配置的过程:

配置数据源

使用c3p0的实现,只要实现javax.sql.DataSource接口都可以。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${c3p0.driverClass}"></property>
        <property name="jdbcUrl" value="${c3p0.jdbcUrl}"></property>
        <property name="user" value="${c3p0.user}"></property>
        <property name="password" value="${c3p0.password}"></property>
        <property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
        <property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
        <property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
        <property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
</bean>
配置SqlSessionFactory

它是生成SqlSession的,组件提供了org.mybatis.spring.SqlSessionFactoryBean类给我们去配置。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 自动扫描entity目录以匹配别名 -->
        <property name="typeAliasesPackage" value="com.xiaomi.kfs.mcc.persistence, com.xiaomi.kfs.authority.core" />
        <!-- 显式指定Mapper文件位置 -->
        <property name="mapperLocations" value="classpath*:context/mybatis/*Mapper.xml" />
        <!-- 指定mybatis配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>

配置文件mybatis-config.xml前面文章介绍了,就不再次写了。

配置自动扫描mapper bean:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.xiaomi.kfs.mcc.persistence,com.xiaomi.kfs.mcc.workorder, com.xiaomi.kfs.authority.core" />
        <property name="annotationClass" value="com.xiaomi.common.annotation.MyBatisRepository" />
</bean>
配置事务

使用Spring AOP管理事务。

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- 使用annotation定义事务 @Transactional -->
<tx:annotation-driven transaction-manager="transactionManager" />

使用场景介绍

实际工作中,可能有很多使用场景,下面会简单介绍些这些场景,说明实现思路。

数据库BLOB字段读写

对于文件,在数据库中,一般通过BLOB字段存储,MyBatis提供了BlobTypeHandler进行类型映射,可以把byte[]类型和BLOB类型自动转换。

但更多的时候,我们会把文件专门存放在一个文件服务器中,数据库存储文件路径即可。

批量更新

批量更新有助于提高数据库性能,可以修改defaultExecutorType,设置为BATCH,这样一个事务如果有多条sql,只有在commit后才会发送SQL到数据库。

但要注意,如果程序上下文中,依赖插入的数据主键,可以通过调用sqlSession的flushStatements方法主动将当前缓存的sql发送给数据库执行。

调用存储过程

MyBatis支持存储过程,对其进行了封装,具体配置过程在此不做详细介绍了。

分表

如果系统数据库比较大,可通过分表减少单表的压力,MyBatis允许把表名作为参数传递到SQL中,很容易实现。

分页

MyBatis具有分页功能,通过RowBounds实现,但它有个问题,会在一条SQL中查询所有的结果,再根据从第几条到第几条取数据返回。可以通过编写一个插件,重写SQL进行分页,进行统一处理。

使用枚举类型

之前文章介绍过,通过自定义typeHandler可以很容易的实现。

后续开始阅读「RabbitMQ实战:高效部署分布式消息队列」,并进行总结和分享。

欢迎扫描下方二维码,关注我的个人微信公众号 ~

原文地址:http://blog.51cto.com/13714880/2113481

时间: 2024-10-08 09:09:20

深入浅出MyBatis:MyBatis与Spring集成及实用场景的相关文章

Spring集成MyBatis的使用-使用SqlSessionTemplate

Spring集成MyBatis的使用 Spring集成MyBatis,早期是使用SqlSessionTemplate,当时并没有用Mapper映射器,既然是早期,当然跟使用Mapper映射器是存在一些区别的,比如映射文件命名空间不需要跟接口名一样,接口中的方法不一定跟sql的id一样,通过它的SqlSessionTemplate的使用,在具体实现类中可以实现找到对应的sql Spring-Mybatis集成方式二-使用SqlSessionTemplate step1 导包:spring-webm

Java Persistence with MyBatis 3(中文版) 第五章 与Spring集成

MyBatis-Spring是MyBatis框架的子模块,用来提供与当前流行的依赖注入框架Spring的无缝集成. Spring框架是一个基于依赖注入(Dependency Injection)和面向切面编程(Aspect Oriented Programming,AOP)的Java框架,鼓励使用基于POJO的编程模型.另外,Spring提供了声明式和编程式的事务管理能力,可以很大程度上简化应用程序的数据访问层(data access layer)的实现.在本章中,我们将看到在基于Spring的

Spring集成MyBatis框架

Java在写数据库查询时,我接触过四种方式: 1.纯Java代码,引用对应的数据库驱动包,自己写连接与释放逻辑(可以用连接池) 这种模式实际上性能是非常不错的,但是使用起来并不是非常方便:一是要手工为Connection做获取与释放,大量的冗余代码也容易出错:另一个是,复杂的SQL用字符串写起来简直不可维护(换行.可视长度.参数都是问题). 2.使用Spring JdbcTemplate 这个其实还是挺不错的,配置比较简单,功能丰富上比手工管理Connection要舒服多了,而且代码也比较简洁.

Unit08: Spring集成mybatis

Unit08: Spring集成mybatis 1. Spring集成mybatis (1)方式一 step1. 导包. spring-webmvc,mybatis,mybatis-spring, ojdbc,dbcp,spring-jdbc,junit. step2. 添加spring的配置文件. 注:集成之后,不再需要mybatis的配置文件了,之前的配置信息 用一个bean(SqlSessionFactoryBean)来代替. step3.实体类. step4.映射文件. step5.Ma

Spring - 集成多数据源于MyBatis

其实一个工程多数据源比较常见. 比如我们将所有工程中使用到的定时任务都持久化到同一个数据库,或者我们为工作流框架单独提供一个数据源. 其实这些都好说,毕竟这些情况都是框架替我们做一些工作,我们几乎没有必要去访问这些数据:或者框架已经提供了方便的API去访问持久化数据,我们不用去考虑这方面的事情. 比较烦的情况是,一个工程必须有多个数据源,而且我们经常通过API访问. 无论是使用ORM框架还是JDBC或者SQLTemplate,对于多个数据源尽量保证相同的访问方式,毕竟这些代码到处都是,开发时谁都

Spring 集成mybatis 配置方法

<?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/sch

重构Mybatis与Spring集成的SqlSessionFactoryBean(上)

一般来说,修改框架的源代码是极其有风险的,除非万不得已,否则不要去修改.但是今天却小心翼翼的重构了Mybatis官方提供的与Spring集成的SqlSessionFactoryBean类,一来是抱着试错的心态,二来也的确是有现实需要. 先说明两点: 通常来讲,重构是指不改变功能的情况下优化代码,但本文所说的重构也包括了添加功能 本文使用的主要jar包(版本):spring-*-4.3.3.RELEASE.jar.mybatis-3.4.1.jar.mybatis-spring-1.3.0.jar

Java Persistence with MyBatis 3(中国版) 第五章 与Spring集成

MyBatis-Spring它是MyBatis子模块框.它用来提供流行的依赖注入框架Spring无缝集成. Spring框架是一个基于依赖注入(Dependency Injection)和面向切面编程(Aspect Oriented Programming,AOP)的Java框架,鼓舞使用基于POJO的编程模型. 另外,Spring提供了声明式和编程式的事务管理能力.能够非常大程度上简化应用程序的数据訪问层(data access layer)的实现.在本章中,我们将看到在基于Spring的应用

Mybatis-Generator插件的使用与Spring集成Mybatis的配置

Mybatis-Generator插件 Mybatis-Generator是一个用于自动生成dao层接口.pojo以及mapper xml的一个Mybatis插件,该插件有三种用法:命令行运行.Eclipse插件.maven插件.个人觉得maven插件最方便,可以在eclipse/intellij idea等ide上通用,本文也是介绍在maven中配置并使用这个插件. 现在我mysql中有一个school数据库,该数据库有student.cls两张表格,表结构如下: student表: cls表