![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=1739545527-bqkWyCfAjuXRZAwUIbSwTm3qkTDaOo79-0-baacdb51710d35234a0e3a5f7dafd86b)
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=1739545527-GG8Entl4IS6Za3VpssrbeXMcCXCuyZMS-0-f6de9e7c0c2996bd019a7524e64ec0a7)
在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=1739545527-uyONcR9YmAKyhcUMplIuOPHaIlwaFQaB-0-7ae8d485dc61d2713393b1a0d705c1a8)
创建实体类User,其中使用@Alias注解也可以表明类别名,代码如代码清单4-52所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T91_81036.jpg?sign=1739545527-olI5S3TEhbQ0n5GIJzqBfjfBfETqlioC-0-052a00ba4a9984e8822ddf65d1c22187)
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=1739545527-Mp2Nmb3SQyVBdqo8XaGbTT21A48TswJO-0-664345febad1b27170c71f7e4133c47a)
在src/mian/resources/mapper下创建UserMapper.xml,对应写好在UserMapper接口类的方法,完整内容如代码清单4-54所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T92_81038.jpg?sign=1739545527-BA2ZfAoQbdN22mHoQE2Pxa6eruRVo3uC-0-69e6429ad4897a6485dc7805c2493b71)
因为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=1739545527-0yE0627StwGZGoQGlxiRjgBzh7X2U2qB-0-699d71382f9e7c48065ad1e1f0ed1222)
4.4.6 测试运行
前面对大部分使用场景进行了介绍,接下来进行测试。新建一个Controller,分别对刚刚写的每一个数据库操作写一个方法进行测试,代码内容如代码清单4-56所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T95_81041.jpg?sign=1739545527-EXWd7oJXimo6XsXMEl0Ka9E86Ts854eJ-0-dccb7268cd679745823cbce7f7182652)
具体测试可以在浏览器上访问代码中的注释,每一个方法笔者都对应写了测试地址,以上都是笔者亲测无误的。
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=1739545527-udRS6YsnZ6hy3Wei7NEv24pT2zkQvxJe-0-3c282b7cf51f40fe35d19631f026f653)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T98_80863.jpg?sign=1739545527-cqit7D4ehos64LgHAccPv6EXznktuBcf-0-faa01a769096b5f7337baf8adce30fbb)
这里需要注意的是,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=1739545527-u9ckfzrfpFi5uaJrO7vfNXbwl9klknJJ-0-4bee0eaca3b169b7224f048130d4b1eb)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T100_80865.jpg?sign=1739545527-ncyEmtwL99JMwoFSdUZHNxjd5TPbxron-0-630d3e4643004380f5c0c8866e19af30)
在Mybatis-Generator中有部分数据这里读取的是application.properties文件中的内容。下面给出application.properties文件中的配置,如代码清单4-59所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T101_81045.jpg?sign=1739545527-1MUVGtPNkjjlloppcUKGu8l0yJgxBraN-0-3f0702ac036af415d54ffb426b395b3b)
到这里,其实就已经配置完成了。接下来我们查看IntelliJ IDEA中,Maven的工具栏,可以看到已经安装了Mybatis-Generator插件,如图4-15所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P101_30282.jpg?sign=1739545527-jTyzOb9B69QWHpSC3bgW2GlJqvYf0Wo7-0-8b4e401b16014bc053943faac930b93d)
图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=1739545527-BkvnpgIl0UCbztY1QoTuHEZUUCkHwFbA-0-720c1731100844207873dcd46283e4ef)
图4-16 Mybatis-Generator项目执行LOG示例图
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P102_30291.jpg?sign=1739545527-hHnNMHRoQ1L7IRTpx3ElCEkSFgpQ6cJh-0-27460763fd84bb1fef4de58cdbc00091)
图4-17 Mybatis-Generator项目结构示例图
我们再来查看一下Mapper,其实在Mapper内已经默认生成了几个简单的方法,让我们看一下UserMapper接口的内容,代码如代码清单4-60所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T102_81046.jpg?sign=1739545527-VZ0Nufnxrp2SukwvO9HAwS2SMy0wVPUk-0-6be1d9a55e78041b36e8d7ba09770645)
UserMapper.xml也对应写好了SQL,代码内容如代码清单4-61所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T103_81047.jpg?sign=1739545527-AZKeHvd5kwSVaZRoRse3uTM1e5B7DlSJ-0-c61f490d31d996d31595a465ce9f5bf5)
这些自动生成的方法都是可以直接使用的,可以使用在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=1739545527-rLFyQ3YHXFQBxgAnB1ANykWpmxP6oCCU-0-fa106c6da7336d41490fa0d42eedfad9)
配置文件除了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=1739545527-GYGjRhPIewFRUHOv5QeyrT30Boj0IoVk-0-5015af846e20784957cc0da878bceb97)
使用PageHelper其实特别方便,只要引入PageHelper类,然后设置页码和每页的数量即可,案例测试代码如代码清单4-65所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T106_81049.jpg?sign=1739545527-sD1NNYLBmIJDQP4NZ1r9NkRDC8MCTSVx-0-ecae72e6d90240153e42c81b10e278d1)
启动项目,在浏览器上访问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=1739545527-J1P0mQBAEDrqZqUOlGe1s5Rt2MtMNPfQ-0-5924108a7a6aa6e445947e74db26f70b)
接下来在配置文件中配置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=1739545527-u2vc828rK5M6HNRUcHKPv12XV6VzE12Q-0-9c96205f23e7b7f88b2429b170f6f28b)
关于dao层,这里我们需要继承Mybatis-Plus提供的BaseMapper,只在里面写一个查询用户列表(getUserList)的方法,代码如代码清单4-69所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81053.jpg?sign=1739545527-B1ibr2FfVJYzGOwR2aUUgfzoRy4lXTHa-0-c85897b9615361dc963e64bbaa15c7fd)
在Mapper.xml内写出对应方法,如代码清单4-70所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81054.jpg?sign=1739545527-YlUjGhKGXHAOXIDDuTVU0SimsteYzjMO-0-b651eb05684f050226f3566a286d5c93)
最后使用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=1739545527-jkHCiLixQELgDKb5ohGCaAqJhZUNRTcn-0-8e3ea6923445f5aa9525e7ac2cbc5a87)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T110_80889.jpg?sign=1739545527-ZMvRdqh0iQWCdHotaztAeQUb1lK2Vi2Y-0-f69d575823be104eb0349418a34d75ca)