![Spring Boot 2实战之旅](https://wfqqreader-1252317822.image.myqcloud.com/cover/805/26542805/b_26542805.jpg)
4.4 使用MyBatis操作数据库
4.4.1 MyBatis简介
在MyBatis官网(官网地址:http://www.mybatis.org/mybatis-3/zh/index.html)上是这样介绍MyBatis的:MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
通俗地理解,MyBatis最大的优点是:
• 可以手写SQL,比较灵活,对于很多互联网公司、业务迭代速度快的公司或者业务复杂的项目,MyBatis修改、维护等方面更加灵活。
• 从学习成本上来说,MyBatis上手更加容易,基本上没有更多学习成本,这是很多公司选用MyBatis的理由。
• 从SQL优化方面来说,手写的SQL优化起来更加方便。
4.4.2 MyBatis依赖配置
创建项目,在pom文件中加入MyBatis依赖和MySQL数据库依赖,代码如代码清单4-49所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T89_81033.jpg?sign=1739534970-tngJy0UfTdlqeDv9wcITJUIEQK9SeHUr-0-9ca4f715eb4428f918d15c9bdd87c981)
4.4.3 配置文件
在配置文件中需要配置数据库信息以及MyBatis配置。数据库配置这里就不介绍了,关于MyBatis主要需要配置以下几种。
• logging.level.com.dalaoyang.dao.UserMapper:日志的打印级别,这里的com.dalaoyang.dao.UserMapper是本文案例中Mapper的位置,实际项目应该配置对应Mapper的位置。
• mybatis.mapper-locations:Mapper文件的存放位置。
• mybatis.check-config-location:MyBatis配置是否开启。
• mybatis.config-location:MyBatis配置文件位置,与mybatis.check-config-location配合使用。
本案例对上述内容都进行了配置,配置文件代码如代码清单4-50所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T90_81034.jpg?sign=1739534970-HFiuoQMW5v3UfH5lE8yc5LWSZxc6qGz2-0-33f12ab3a18fa0b2b681324137538ad8)
在src/mian/resources/mybatis下创建mybatis-config.xml,这个文件是MyBatis的全局配置文件,包含以下几种类型的配置:
• properties(属性)
• settings(全局配置参数)
• typeAliases(类型别名)
• typeHandlers(类型处理器)
• objectFactory(对象工厂)
• plugins(插件)
• environments(环境集合属性对象)
• environment(环境子属性对象)
• transactionManager(事务管理)
• dataSource(数据源)
• mappers(映射器)
案例中仅配置了一些常使用的类型别名typeAliases,Mybatis-config.xml内容如代码清单4-51所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T91_81035.jpg?sign=1739534970-DTnOUT8B4lXK7KZ0wxRE69HZrGRGsPn9-0-bfbfce66c59707923257f7fc5e2dae30)
创建实体类User,其中使用@Alias注解也可以表明类别名,代码如代码清单4-52所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T91_81036.jpg?sign=1739534970-kXzPzpky6Qb8HdmcgmKxbua3TJ0gh8Wq-0-682275d135f70c79f8656a35bed0a9e5)
4.4.4 基于XML的使用
创建Mapper对应接口类UserMapper,在类上加入注解@Mapper,表明这是一个Mapper。我们提前定义5个方法,分别是:
• 根据用户名查询用户。
• 根据用户名修改用户。
• 根据用户名删除用户。
• 保存用户。
• 获取用户列表。
UserMapper接口代码如代码清单4-53所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T92_81039.jpg?sign=1739534970-3sdWd2ZpqXWBdxOKqbFJ67KZGVdcTmq4-0-94637155ff2ae91f26f4ce5f7cbe31b0)
在src/mian/resources/mapper下创建UserMapper.xml,对应写好在UserMapper接口类的方法,完整内容如代码清单4-54所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T92_81038.jpg?sign=1739534970-h1QkFJxhhmb8pWuMBeffofSCoFbO7Bmv-0-c2c71ff146bd517838c60c1a7a9a3789)
因为MyBatis深受很多公司的喜爱,所以介绍一下Mapper的标签。标签大致分为以下几种。
(1)定义SQL语句
• insert:多用于执行插入语句,标签内有两个属性id(唯一标识符)和parameterType(传入的参数类型)。
• delete:多用于执行删除语句,标签内有两个属性id(唯一标识符)和parameterType(传入的参数类型)。
• update:多用于执行修改语句,标签内有两个属性id(唯一标识符)和parameterType(传入的参数类型)。
• select:用于执行查询,与上面三个标签相比,多了一个resultType属性,用于接收返回类型。
注 意
比如在insert标签内写delete语句不会报错,但是不建议这样使用。
(2)结果集
• resultMap:用于建立SQL查询结果字段与实体属性的映射关系信息。
(3)动态SQL拼接
• if:用于判断,在test属性内加入条件。
• choose:用于判断,与when和otherwise配合使用。
• foreach:循环语句,其中包含属性collection(集合,内容可以是list、array和map)、item(循环遍历的元素)、index(下标)、open(前缀)、close(后缀)、separator(分隔符)。
(4)格式化输出
• where:根据标签内的值是否存在自动拼接where语句。
• set:根据标签内的值是否存在自动拼接set语句。
• trim:多用于灵活去除多余关键字的标签,一般结合where或set使用。
(5)配置关联关系
• collection:用于配置一对一关系。
• association:用于配置一对多关系。
(6)SQL标签
• sql:主要用于提取sql片段,便于复用。
4.4.5 基于注解使用
MyBatis不仅可以使用XML形式操作数据库,还可以使用注解形式操作数据库,比如如下注解。
• @Select:其中值写查询SQL。
• @Update:其中值写修改SQL。
• @Delete:其中值写删除SQL。
• @Insert:其中值写插入SQL。
• @Results:是以@Result为元素的数据。
• @Result:映射实体类属性和字段之间的关系。
• @ResultMap:用于解决返回结果映射问题,与上面介绍的resultMap标签功能类似。
• @Result:可以用作表明自定义对象,方便内容重用。
• @SelectProvider:相当于直接使用在类中写好的SQL,将SQL封装到类内,方便管理。type属性表明使用哪个类,method对应使用方法。
• @UpdateProvider:功能类似于@SelectProvider。
• @DeleteProvider:功能类似于@SelectProvider。
• @InsertProvider:功能类似于@SelectProvider。
其实现效果和使用XML模式是一样的,并且两种模式可以混用。例子如代码清单4-55所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T94_81040.jpg?sign=1739534970-tHVJ7Hba3m5CGO6Y00lnSGGN8PsINeOt-0-f24d96209eded0955fe1f162a8d025a4)
4.4.6 测试运行
前面对大部分使用场景进行了介绍,接下来进行测试。新建一个Controller,分别对刚刚写的每一个数据库操作写一个方法进行测试,代码内容如代码清单4-56所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T95_81041.jpg?sign=1739534970-J8r626bh7wyN5GRYmGtS7Pm2KwEmf3u4-0-e0d065f8ebf8b2091cbf6cb3e6f794be)
具体测试可以在浏览器上访问代码中的注释,每一个方法笔者都对应写了测试地址,以上都是笔者亲测无误的。
4.4.7 Mybatis-Generator插件学习
由于业务的不断增长,数据库中的表也随之增长,造成在没创建表时就需要在项目内反复创建实体类、Mapper文件、dao层文件等,这样的重复工作虽然难度不大,但是会浪费人力,因此MyBatis创建了一个针对这个问题的插件Mybatis-Generator。Mybatis-Generator是MyBatis官方提供的一个便捷型插件,利用它可以根据数据库表结构自动在项目内创建对应的实体类、Mapper文件和dao层。
(1)在pom文件中加入Mybatis-Generator插件
在pom文件中加入Mybatis-Generator插件,为了方便观看,这里展示完整pom文件代码,如代码清单4-57所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T96_81042.jpg?sign=1739534970-OPf0wDDakfek4lK87At9cR8ANpf0RxAL-0-fbdeb722d15f1aa96e5464c0c348bc6d)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T98_80863.jpg?sign=1739534970-ZVISmKsAWP4LzVztJNT1WMMo4VCEhUnP-0-493ca98df9d7aabdc09b1d5737b6b48b)
这里需要注意的是,configurationFile配置的是Mybatis-Generator插件所存放的位置,本案例是在src/main/resources/mybatis-generator下创建了一个generatorConfig.xml文件,在配置文件中对需要配置的内容做了详细的说明,配置内容如代码清单4-58所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T99_81044.jpg?sign=1739534970-ckNZpiydprFOxZo40X4ZMIzIBKzI8l3Z-0-0f421e20d20ac34555aae31bd000321f)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T100_80865.jpg?sign=1739534970-3AEUgtfXdfh9GHu6CorbpQbduEuRm8Rx-0-1911dbf9481d849d5ba76a728b0878a8)
在Mybatis-Generator中有部分数据这里读取的是application.properties文件中的内容。下面给出application.properties文件中的配置,如代码清单4-59所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T101_81045.jpg?sign=1739534970-XL7w1YzNaCxCSpEocPrUCtqjRKJtEGPf-0-c0251125984384a954442e88738663a3)
到这里,其实就已经配置完成了。接下来我们查看IntelliJ IDEA中,Maven的工具栏,可以看到已经安装了Mybatis-Generator插件,如图4-15所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P101_30282.jpg?sign=1739534970-Es08eMd6LyL8rCpN7kFkpl30pJRLhPPx-0-4b39eafb14c9aa7da7093df5f6d43ba0)
图4-15 Mybatis-Generator项目插件示例图
我们看一下Maven操作日志,提示已经生成了dao层、实体类、Mapper文件,如图4-16所示。
去对应目录看看,果然这些都生成了,如图4-17所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P102_30288.jpg?sign=1739534970-XoPQqGbgTtZP3cRR9ubXaOUBM48qLiPa-0-f0eb3ab64ee46db0caaf4131d7fa4e28)
图4-16 Mybatis-Generator项目执行LOG示例图
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P102_30291.jpg?sign=1739534970-YUdHb27MMrHmWtT29Id7H078mWth74hk-0-f6e16035ff18e13fd39dae1461a68ed9)
图4-17 Mybatis-Generator项目结构示例图
我们再来查看一下Mapper,其实在Mapper内已经默认生成了几个简单的方法,让我们看一下UserMapper接口的内容,代码如代码清单4-60所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T102_81046.jpg?sign=1739534970-MChrBVeKjlczGAbcEwAsepCLY4szu5Ih-0-fe82a8d873b38e8f4bd7f266fa7381df)
UserMapper.xml也对应写好了SQL,代码内容如代码清单4-61所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T103_81047.jpg?sign=1739534970-zaz4OvbMfGqBVyZz4x48WL5LY9WOza4j-0-2c010da00b682376f97215967ec94477)
这些自动生成的方法都是可以直接使用的,可以使用在Controller内对应的写方法测试,也可以使用测试用例测试,这里就不一一测试了。
4.4.8 PageHelper插件
在操作数据库的时候,分页是必不可少的一项任务,在使用MyBatis时,可以利用PageHelper插件对MyBatis插件进行分页。PageHelper支持常见的12种数据库,如Oracle、MySQL、MariaDB、SQLite、DB2、PostgreSQL、SQL Server等。
在pom文件中加入PageHelper依赖,依赖代码如代码清单4-62所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T105_81048.jpg?sign=1739534970-ukf5WZOekAIarskjLZ6TASvwtRMA3byA-0-cc8d30b31b60d9939a71b4d6d15c93ab)
配置文件除了MySQL配置外,还添加了一个PageHelper插件的配置,也就是配置SQL方言,配置如代码清单4-63所示。
代码清单4-63 Mybatis-PageHelper项目配置文件代码
#pagehelper分页插件配置 pagehelper.helperDialect=mysql
实体类和之前的一样,这里就不反复介绍了。由于PageHelper插件只是用于分页,因此我们只是在Mapper内用注解写了一个查询所有用户的方法,如代码清单4-64所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T106_81050.jpg?sign=1739534970-cwDSbqhZhflVvW2AtkvCh8kUdYp94oJZ-0-c11a134f61ad395d32d83333f8281e0b)
使用PageHelper其实特别方便,只要引入PageHelper类,然后设置页码和每页的数量即可,案例测试代码如代码清单4-65所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T106_81049.jpg?sign=1739534970-Qqw3E5hqj0KIM81wKNugJ9YW5V1ihJEP-0-1b72ad61b6c0bf714ff8a0b2eca17dd4)
启动项目,在浏览器上访问http://localhost:8080/getUserListPage?pageNum=1&pageSize=2,这里pageNum为页码、pageSize为每页的数量。是不是很简单?接下来我们介绍一个更全面的插件。
4.4.9 Mybatis-Plus插件
Mybatis-Plus是苞米豆团队开发的一个MyBatis增强型插件,官网上介绍只做增强,不做改变,为简化开发、提高效率而生。其特性有很多,这里不一一介绍,感兴趣的读者可以在官网上查看,官网地址:https://mp.baomidou.com/。
接下来我们学习Spring Boot如何使用Mybatis-Plus插件。新建项目,在pom文件中加入Mybatis-Plus依赖,完整pom文件依赖如代码清单4-66所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T107_81051.jpg?sign=1739534970-CsnlINEQl8TcpWMlq3c80PMLdRSng6Tg-0-92a1aae5078ca015cc454cc0e17373f3)
接下来在配置文件中配置mapper.xml文件的位置和type-aliases实体的位置,配置如代码清单4-67所示。
代码清单4-67 Mybatis-Plus项目配置文件代码
##mybatis-plus mapper xml 文件地址 mybatis-plus.mapper-locations=classpath*:mapper/*Mapper.xml ##mybatis-plus type-aliases 文件地址 mybatis-plus.type-aliases-package=com.dalaoyang.entity
实体类还是使用之前的User类,可以复制过来,新建一个Mybatis-Plus配置类MybatisPlusConfig,在这里可以设置一些方言的配置等,代码如代码清单4-68所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T107_81052.jpg?sign=1739534970-iV1LvAAbmp8TyUGHZtNWWt1N3GudEVoD-0-5bf847c05e245eb459a71f6d3df3fbc1)
关于dao层,这里我们需要继承Mybatis-Plus提供的BaseMapper,只在里面写一个查询用户列表(getUserList)的方法,代码如代码清单4-69所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81053.jpg?sign=1739534970-EuqZyiXADFYwF996z7c310N7sh6Qmq92-0-abe6e39075c732d1a0091f6f066619aa)
在Mapper.xml内写出对应方法,如代码清单4-70所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81054.jpg?sign=1739534970-7vOQU4rV4Vnn5JtJhaQk1OI0Rjk9KZOL-0-2c9d32a673be638aac6454d0cb9a93e7)
最后使用Controller进行测试,方法介绍如下。
• getUserList:尝试使用传统MyBatis方法,若可以使用,则证明Mybatis-Plus插件没有影响原有使用。
• getUserListByName:使用Mybatis-Plus提供的selectByMap方法,参数是Map,在Map内写入查询条件。
• saveUser:使用Mybatis-Plus提供的insert方法,参数使用对应实体即可,返回影响行数。
• updateUser:使用Mybatis-Plus提供的insert方法,参数使用对应实体(带ID)即可,返回影响行数。
• getUserListByPage:使用Mybatis-Plus提供的selectPage方法,这是一个条件分页查询方法,需要用到Mybatis-Plus的对象EntityWrapper存放查询条件,使用Page来存放分页信息。
关于测试Mybatis-Plus的完整Controller代码如代码清单4-71所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T109_81055.jpg?sign=1739534970-1SpAQINNbm8KtpjVd6fSomWRWGhrBH6C-0-f36d9fcb3b6deb276ce7eee5eef60043)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T110_80889.jpg?sign=1739534970-p5GXdB23gy2RAuGP2AuU5OK5w2MEqo7G-0-1d682621b1dfe8c97ce685cb588c8c1d)