上一篇文章我们介绍了SpringBoot集成JdbcTemplate.简单体验了一下JdbcTemplate框架的用法,
今天来介绍一下SpringBoot集成Mybatis。

一、 Mybatis 介绍

MyBatis最初是Apache的一个开源项目,名为iBatis。
2010年,该项目从Apache迁移到了Google Code,并改名为MyBatis。
2013年11月,MyBatis进一步迁移到Github。
最新版本是MyBatis 3.5.x(具体版本号可能随时间更新,请参考官方发布信息)。

特点与优势:

  1. 简化JDBC开发:MyBatis封装了JDBC的复杂操作,如注册驱动、创建连接、创建Statement、设置参数、获取结果集等,使开发者只需关注SQL语句本身。
  2. 灵活性强:MyBatis支持定制化SQL、存储过程以及高级映射,允许开发者通过XML或注解的方式灵活配置SQL语句。
  3. 解耦:通过提供DAO层,MyBatis将业务逻辑和数据访问逻辑分离,提高了系统的可维护性和可测试性。
  4. 易于学习:MyBatis简单易学,没有第三方依赖,安装和配置相对简单。

缺点

  1. 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
  2. SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
  3. 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

二、涉及常用的注解

在Spring Boot集成mybatis时,出现的常用注解主要来自于几个不同的源头,具体说明如下:

Mybatis 提供的注解

在Spring Boot集成MyBatis时,我们通常会使用到一些MyBatis自身提供的注解来简化数据库的操作,减少XML映射文件的使用。以下是一些常用的MyBatis注解及其提供者(自然都是MyBatis本身),以及它们的使用方式示例:

1. @Select
用途:用于标记在Mapper接口方法上,指定SQL查询语句。
示例

@Select("SELECT * FROM user WHERE id = #{id}")
User selectUserById(Integer id);

2. @Insert
用途:用于标记在Mapper接口方法上,指定SQL插入语句。
示例

@Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);

这里@Options注解的useGeneratedKeyskeyProperty用于处理自增主键的返回。

3. @Update
用途:用于标记在Mapper接口方法上,指定SQL更新语句。
示例

@Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
int updateUser(User user);

4. @Delete
用途:用于标记在Mapper接口方法上,指定SQL删除语句。
示例

@Delete("DELETE FROM user WHERE id = #{id}")
int deleteUserById(Integer id);

5. @Param
用途:用于给方法参数命名,尤其是当Mapper接口方法有多个参数时,MyBatis无法直接通过位置判断参数值,需要使用@Param注解来指定SQL语句中参数的名称。
示例

@Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}")
User findUserByNameAndAge(@Param("name") String name, @Param("age") int age);

6. @Results@Result
用途@Results用于定义结果集,@Result用于定义结果集中的列与Java对象的属性之间的映射关系。虽然这些注解常用于XML配置中,但在注解配置时也可以使用。
示例(较少在纯注解配置中使用,更常见于XML):

@Select("SELECT id, name AS userName FROM user")
@Results({
    @Result(property = "id", column = "id"),
    @Result(property = "userName", column = "userName")
})
User selectUser();

MyBatis-Spring-Boot-Starter提供的

@Mapper
用途:这是MyBatis-Spring-Boot-Starter提供的一个注解,用于标记Mapper接口,以便Spring Boot能够自动扫描并注册这些Mapper接口为Bean。
但是,从Spring Boot 2.0开始,如果你将Mapper接口放在@MapperScan注解指定的包或其子包下,那么即使不使用@Mapper注解,Spring Boot也能够自动扫描到这些Mapper接口。

Spring Boot提供的

@MapperScan
用途:这是Spring Boot提供的一个注解,用于指定Mapper接口所在的包路径,以便Spring Boot能够自动扫描并注册这些Mapper接口为Bean。
如果你使用了@Mapper注解,但仍然希望有一个全局的配置来指定Mapper接口的位置,那么@MapperScan就非常有用。

三、集成步骤

1. 引入依赖

首先我们先引入Mybatis所需依赖,mybatis本身已经提供了用于适配springBoot的Starter, 同时我们还需要引入 mysql-connector. 在pom.xml中添加:

<!-- mybatis-spring-boot-starter
这个版本需要指定了,因为场景启动器里面没有 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

<!-- MySQL JDBC驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

2. 数据源和mybatis配置

数据源配置:

# 数据源的类型
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
# JDBC 驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JDBC URL
spring.datasource.url=jdbc:mysql://localhost:3306/sharding?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
# 用户名
spring.datasource.username=root
# 密码
spring.datasource.password=root

细节说明:
spring.datasource.type 在 Spring Boot 的配置中,主要指的是数据源的类型,但这个数据源类型往往与数据库连接池紧密相关。在大多数情况下,当我们讨论数据源类型时,我们实际上是在谈论数据库连接池的实现。

  • Spring Boot 1.x版本中 默认的数据源类型为Tomcat JDBC连接池
    spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
  • Spring Boot 2.x版本中 默认的数据源类型为HikariCP连接池
    spring.datasource.type=com.zaxxer.hikari.HikariDataSource
  • 现阶段也常用Druid连接池(这个后续有空再说)
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

MyBatis 配置

# Mapper 文件的扫描路径,可以有多个,支持使用通配符。
#也就是我们写在resources目录里面的xml文件。
mybatis.mapper-locations=classpath*:mapper/**/*.xml

细节说明:

  1. 推荐使用classpath*前缀以确保资源能够被正确加载,无论它们位于类路径的哪个位置,包括嵌套在JAR文件中的位置
  2. mapper/**/*.xml
    这是最常见和推荐的方法。由于可以匹配零个或多个目录,因此它实际上会包括mapper目录本身及其所有子目录。这意味着,如果你的Mapper XML文件既在mapper目录下也在其子目录中,那么classpath*:mapper/**/*.xml将能够扫描到它们。

3. 开启MyBatis的SQL日志(看需求)

方式 一:
使用 mybatis.configuration.log-impl 配置
值是固定的

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

方式二:
使用 logging.level.com
值为的自己工程为mapper接口包路径

logging.level.com.example.springbootfull.mybatistest.mapper=DEBUG

注意:logging.level.com,后面的路径指的是mapper接口包路径

4. 使用逆向工程(非必要)

如果你项目里面已经写好了 实体类、 dao层接口、xml 映射文件 就不需要这一步操作了,我目前是为了测试,所以需要‘逆向工程"帮忙自动生成。
我这边idea自己有的,没有的人可以百度去一下,下个插件也行

先创建表

DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `account` varchar(255) NULL DEFAULT NULL,
  `create_at` datetime(6) NULL DEFAULT NULL,
  `enabled` bit(1) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) 

操作如下:
在这里插入图片描述
在这里插入图片描述
填完以后

在这里插入图片描述
在这里插入图片描述
建议不要动文件位置设置,直接ok,后面自己拖过去就好了

5. 启动类上加@MapperScan

说到@MapperScan,就得先讲一下 @Mapper,两者 都是 MyBatis 框架 下的注解。

通过 @Mapper 注解,可以明确地告诉 Spring 和 MyBatis,这个接口是一个 Mapper 接口,需要被 MyBatis 处理。这样,Spring 容器在启动时就会扫描到这些接口,并将它们注册为 MyBatis Mapper 组件。

而 @MapperScan 可以 集中管理 Mapper 接口的扫描路径,不用一个一个加,更加方便

package com.example.springbootfull;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.SpringVersion;

@SpringBootApplication
@MapperScan(basePackages = {"com.example.springbootfull.mybatistest.mapper"})
public class SpringbootFullApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootFullApplication.class, args);
    }

}

6. 测试类测试

package com.example.springbootfull;

import com.example.springbootfull.mybatistest.bean.SysUser;
import com.example.springbootfull.mybatistest.mapper.SysUserDao;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;

@SpringBootTest
class SpringbootFullApplicationTest2s {

    static final Logger logger = LoggerFactory.getLogger(SpringbootFullApplicationTest2s.class);

    @Autowired
    private SysUserDao sysUserDao;

    @Test
    void contextLoads() {

        // 创建实体类
        SysUser sysUser = new SysUser();
        sysUser.setAccount("mybtis呀");
        sysUser.setEnabled(Boolean.TRUE);
        sysUser.setCreateAt(new Date());
        sysUserDao.insertSelective(sysUser);

        // 根据自增ID检索实体
        SysUser sysUser1 = sysUserDao.selectByPrimaryKey(sysUser.getId());

        logger.info("user={}", sysUser1);
    }

}

结果运行如下:

在这里插入图片描述
在这里插入图片描述

参考文章
【1】SpringBoot集成Mybatis(持久化框架)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐