MyBatis 快速整合 Spring

简介: 前言目前,关系型数据库已经成为 Java 应用的标配,由于 JDBC 操作数据库的复杂性,我们通常会选择一款持久层框架,而作为半自动化 ORM 框架的 MyBatis 则成了我们的首选,而 Spring 又成了 Java 事实上的标准,它让我们开发 Java 应用更快、更容易、更安全,因此我们通常会将 MyBatis 与 Spring 整合在一起使用。

前言


目前,关系型数据库已经成为 Java 应用的标配,由于 JDBC 操作数据库的复杂性,我们通常会选择一款持久层框架,而作为半自动化 ORM 框架的 MyBatis 则成了我们的首选,而 Spring 又成了 Java 事实上的标准,它让我们开发 Java 应用更快、更容易、更安全,因此我们通常会将 MyBatis 与 Spring 整合在一起使用。


MyBatis 脱离 Spring 环境已经可以使用了,那为什么又要将它与 Spring 整合在一起呢?这里我总结出两点。


配置简化,和 Spring 整合在一起后复杂的 xml 配置可以忽略或少量配置。

加入 Spring 事务管理,将 MyBatis 异常转换为 Spring 中的异常。

快速上手

MyBatis 与 Spring 的整合可以分为两块。一块是直接与 Spring Framework 整合,整合后我们就可以在 Spring 的事务管理下使用 MyBatis,此时还需要少量的配置。另一块是与 SpringBoot 整合,整合后几乎可以忽略所有的 MyBatis 配置,极个别配置在 application.properties 添加即可。


这里假定屏幕前的小伙伴对 MyBatis 具备一定的认识,如果你认为还不够熟悉 MyBatis,可以参考我前面的几篇文章先进行了解。


MyBatis 初探,使用 MyBatis 简化数据库操作(超详细)

MyBatis Mapper 接口方法执行原理分析

一条 SQL 是如何在 MyBatis 中执行的

谈谈 MyBatis 的插件,除了分页你可能还有这些使用场景

MyBatis 缓存机制分析,MyBatis 真的有二级缓存?

MyBatis 中的设计模式,这次我总结全了

MyBatis TypeHandler 泛型踩坑指南


Spring Framework 整合


在不考虑原理的情况下,我们先看如何在 Spring 环境中使用 MyBatis。


为了将 MyBatis 应用到 Spring,MyBatis 官方提出了一个子项目 mybatis-spring,需要先将其引入到项目中。


<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>2.0.6</version>
</dependency>


SqlSessionFactory 配置及使用


SqlSession 是 Mybatis 执行 SQL 的入口,它又非线程安全,因此我们可以在 Spring 环境下配置一个线程安全的 SqlSessionFactory 作为 bean。按照非 Spring 环境下的方式创建 SqlSessionFactory 也并无不可,然而为了简化配置及加入 Spring 的事务管理,mybatis-spring 项目中提供了一个 SqlSessionFactoryBean,这是一个 Spring 的 FactoryBean,最终 Spring 容器创建的是一个从 SqlSessionFactoryBean 获取到的 SqlSessionFactory,因此我们配置 SqlSessionFactoryBean 作为 bean 即可。


@Configuration
public class MyBatisConfiguration {
    @Bean
    public DataSource dataSource() {
        DataSource dataSource = new PooledDataSource();
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource());
        // 设置 mapper xml 文件路径
        Resource[] mapperResources = new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/*Mapper.xml");
        sqlSessionFactoryBean.setMapperLocations(mapperResources);
        // 设置配置
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 字段映射时先将数据库表字段下划线转驼峰
        configuration.setMapUnderscoreToCamelCase(true);
        // 关闭缓存
        configuration.setLocalCacheScope(LocalCacheScope.STATEMENT);
        configuration.setCacheEnabled(false);
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean;
    }
}


SqlSessionFactoryBean 只有一个必要的 dataSource 属性需要设置,除此之外,我们还配置了 mapper xml 配置文件的路径,以及常用的关闭缓存及下划线转驼峰的字段映射方式,此时我们已经可以使用如下的方式使用 MyBatis。


@Service
public class UserService {
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    public User getById(Integer id) {
        return sqlSessionFactory.openSession().selectOne("com.zzuhkp.blog.mybatis.mapper.UserMapper.getById", id);
    }
}


SqlSessionTemplate 配置及使用


通过上面对 SqlSessionFactoryBean 的配置我们已经可以获取到 SqlSession 来执行 SQL,但是这个 SqlSession 不是线程安全的,因此 MyBatis 又提供了一个线程安全的 SqlSession,为 SqlSessionTempalte,将其配置为 Spring 的 bean 即可方便的使用。


@Configuration
public class MyBatisConfiguration {
    @Bean
    public DataSource dataSource() {
        DataSource dataSource = new PooledDataSource();
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        ... 省略部分代码
        return sqlSessionFactoryBean;
    }
    @Bean
    public SqlSession sqlSession() throws Exception {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory().getObject());
        return sqlSessionTemplate;
    }
}

此时业务代码使用 MyBatis 方式如下。


@Service
public class UserService {
    @Autowired
    private SqlSession sqlSession;
    public User getById(Integer id) {
        return sqlSession.selectOne("com.zzuhkp.blog.mybatis.mapper.UserMapper.getById", id);
    }
}


Mapper 配置及使用


通过上面的配置虽然我们已经有了线程安全的 SqlSessionTemplate,但是通常情况我们更希望使用 Mapper 接口操作数据库,Spring 环境下就需要把 Mapper 接口注入为 bean 了,通过 SqlSession#getMapper 方法获取是一个不错的选择,但是 mybatis 还提供了不通过 SqlSession 获取 Mapper 的 MapperFactoryBean 类,这个类可以创建 Mapper 接口的实现作为 bean。


@Configuration
public class MyBatisConfiguration {
    @Bean
    public DataSource dataSource() {
        DataSource dataSource = new PooledDataSource();
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    ...省略部分代码
        return sqlSessionFactoryBean;
    }
    @Bean
    public MapperFactoryBean<UserMapper> userMapper() throws Exception {
        MapperFactoryBean<UserMapper> factoryBean = new MapperFactoryBean<>();
        factoryBean.setMapperInterface(UserMapper.class);
        factoryBean.setSqlSessionFactory(sqlSessionFactory().getObject());
        return factoryBean;
    }
}


通过上面的代码,我们就可以按照如下的方式使用 UserMapper 替代 SqlSession 了。

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public User getById(Integer id) {
        return userMapper.getById(id);
    }
}


Mapper 扫描配置


通过上面的方式我们直接将 Mapper 配置为 bean,如果项目中有几十甚至几百个 Mapper,那配置的工作量将大大增加,为了简化配置,MyBatis 提出了一个 @MpperScan 注解,这个注解会为扫描到的 Mapper 接口创建代理类,然后注入到 Spring 容器中,将这个注解添加到 Spring 配置类上即可。


@MapperScan("com.zzuhkp.blog.mybatis.mapper")
@Configuration
public class MyBatisConfiguration {
    @Bean
    public DataSource dataSource() {
        DataSource dataSource = new PooledDataSource();
        return dataSource;
    }
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        ... 省略部分代码
        return sqlSessionFactoryBean;
    }
}


使用方式和上面注入 UserMapper 的使用方式相同,从这里也可以看出,MyBatis 在不断简化配置以及降低使用的难度。


SpringBoot 整合


引入 mybatis-spring 依赖后,再加上少量的配置已经可以在 Spring 中使用 MyBatis 了,但是不满足是向上的车轮,当前我们使用更多的是 SpringBoot,它大大简化了使用 Spring 做出的大量配置,为了在 SpringBoot 环境下进一步简化 MyBatis 的使用,MyBatis 官网又提出了一个 starter,坐标如下。


<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>


是的,仅仅添加上面一个依赖即可,然后就可以直接注入 Mapper 执行 SQL 了。那它有何魔法呢?默认情况这个 starter 在背后会做如下的工作。


自动向 Spring 容器注册 SqlSessionFactory 作为 bean。

所需的部分配置项从 Spring 上下文中的环境变量获取,因此可以把配置添加到 application.perperties 文件中,参见 MybatisProperties 类。

所需的数据源为 Spring 上下文中的 DataSource bean。

Spring 上下文中的部分 MyBatis 组件 bean 将添加到配置中,包括 Interceptor、DatabaseIdProvider、TypeHandler、LanguageDriver。

此外实现了 MyBatis ConfigurationCustomizer 接口的 bean 将被回调用于通过代码自定义配置。

自动向 Spring 容器注册 SqlSessionTemplate 作为 bean。

自动扫描添加了 @Mapper 注解的 Mapper 并向 Spring 注册 bean。


总结

MyBatis 为了整合 Spring 提出了两个项目:mybatis-spring 用于向 springframework 整合,此时需要手动配置 SqlSessionFactory 及 Mapper,mybatis-spring-boot-starter 用于向 springboot 整合,提供了从 spring 上下文收集配置自动创建 MyBatis bean 的能力。


目录
相关文章
|
6天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
7天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
30天前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
11天前
|
前端开发 JavaScript Java
技术分享:使用Spring Boot3.3与MyBatis-Plus联合实现多层次树结构的异步加载策略
在现代Web开发中,处理多层次树形结构数据是一项常见且重要的任务。这些结构广泛应用于分类管理、组织结构、权限管理等场景。为了提升用户体验和系统性能,采用异步加载策略来动态加载树形结构的各个层级变得尤为重要。本文将详细介绍如何使用Spring Boot3.3与MyBatis-Plus联合实现这一功能。
44 2
|
21天前
|
Java 数据库连接 测试技术
SpringBoot 3.3.2 + ShardingSphere 5.5 + Mybatis-plus:轻松搞定数据加解密,支持字段级!
【8月更文挑战第30天】在数据驱动的时代,数据的安全性显得尤为重要。特别是在涉及用户隐私或敏感信息的应用中,如何确保数据在存储和传输过程中的安全性成为了开发者必须面对的问题。今天,我们将围绕SpringBoot 3.3.2、ShardingSphere 5.5以及Mybatis-plus的组合,探讨如何轻松实现数据的字段级加解密,为数据安全保驾护航。
72 1
|
30天前
|
Web App开发 前端开发 关系型数据库
基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】
这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。
|
30天前
|
SQL Java 关系型数据库
SpringBoot 系列之 MyBatis输出SQL日志
这篇文章介绍了如何在SpringBoot项目中通过MyBatis配置输出SQL日志,具体方法是在`application.yml`或`application.properties`中设置MyBatis的日志实现为`org.apache.ibatis.logging.stdout.StdOutImpl`来直接在控制台打印SQL日志。
SpringBoot 系列之 MyBatis输出SQL日志
|
1月前
|
前端开发 Java 数据库连接
一天十道Java面试题----第五天(spring的事务传播机制------>mybatis的优缺点)
这篇文章总结了Java面试中的十个问题,包括Spring事务传播机制、Spring事务失效条件、Bean自动装配方式、Spring、Spring MVC和Spring Boot的区别、Spring MVC的工作流程和主要组件、Spring Boot的自动配置原理和Starter概念、嵌入式服务器的使用原因,以及MyBatis的优缺点。
|
1月前
|
Java 数据库连接 mybatis
基于SpringBoot+MyBatis的餐饮点餐系统
本文介绍了一个基于SpringBoot和MyBatis开发的餐饮点餐系统,包括系统的主控制器`IndexController`的代码实现,该控制器负责处理首页、点餐、登录、注册、订单管理等功能,适用于毕业设计项目。
45 0
基于SpringBoot+MyBatis的餐饮点餐系统
|
1月前
|
XML SQL JavaScript
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
这篇文章介绍了如何在Vue页面中结合SpringBoot、MyBatis、ElementUI和ECharts,实现从数据库获取数据并展示为图表的过程,包括前端和后端的代码实现以及遇到的问题和解决方法。
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作