![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=1739274681-G3fvUKFNS1AvYRZMUFYw1eCOtqv6a7W4-0-8e5c864fef899feda3a6816b8e5f4c5e)
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=1739274681-jSDFH9p2qmqb3VSMQTm0pnTD2o6lFvHO-0-be57e9153230dd57650c51b0fcefbaed)
在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=1739274681-vyR4jtYiu10AZX9aiaT5QuUD3R32mRyw-0-9ce6ae6051f1a19bb9f1898b2218f861)
创建实体类User,其中使用@Alias注解也可以表明类别名,代码如代码清单4-52所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T91_81036.jpg?sign=1739274681-IhkAczrQEoTs0nfeyBZsbNwvnaKXPRhS-0-248c0e7c9134239269e1ae62f90d17f6)
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=1739274681-eQgYLv8TzSgj7bUmo3x0G8EvhlsM6Txd-0-7845a9ae1998d8ed5e2df1a9a31847d5)
在src/mian/resources/mapper下创建UserMapper.xml,对应写好在UserMapper接口类的方法,完整内容如代码清单4-54所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T92_81038.jpg?sign=1739274681-faXZcD7hyczU5LtfHf2HTlyaj3KC1Z8R-0-1f9e37dafa582ba895e71b4581a426ad)
因为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=1739274681-XCmF1f8qHSkCi2mO7VfNqlpViLTYknCE-0-234b8ce887ffb6b2b4a79a88d009e336)
4.4.6 测试运行
前面对大部分使用场景进行了介绍,接下来进行测试。新建一个Controller,分别对刚刚写的每一个数据库操作写一个方法进行测试,代码内容如代码清单4-56所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T95_81041.jpg?sign=1739274681-mPyHGTTbfOEsYvJyNd27CEcL6gXJmHnT-0-6d564843dbe40e69391153c7c39317bd)
具体测试可以在浏览器上访问代码中的注释,每一个方法笔者都对应写了测试地址,以上都是笔者亲测无误的。
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=1739274681-CZ1FVhCtGvtmbGnkpqdusN3ZDSEusk4c-0-c58a0c4f4b1de813147ce8b74dd0813a)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T98_80863.jpg?sign=1739274681-kJXyJdT9zBRrcHS6YhW2Q5LMMDqSKiTx-0-c1a5dc04e70d383004b642840b21ed87)
这里需要注意的是,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=1739274681-zVg36OwsuhgkAccpWU7F6W9cdABlOiho-0-717b91cee338e43b3ed8187e9bdda0ac)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T100_80865.jpg?sign=1739274681-5R511ES9mvfGudvY4cwzLL7aP9iFRdt4-0-2024233562486e95fd9fd68e2c7cfccc)
在Mybatis-Generator中有部分数据这里读取的是application.properties文件中的内容。下面给出application.properties文件中的配置,如代码清单4-59所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T101_81045.jpg?sign=1739274681-7rxYe7ZL3UKS9OsulyjcjhFB6qZWqgDx-0-a0d7bd1fcec6cc15b3b40dbd5f10db69)
到这里,其实就已经配置完成了。接下来我们查看IntelliJ IDEA中,Maven的工具栏,可以看到已经安装了Mybatis-Generator插件,如图4-15所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P101_30282.jpg?sign=1739274681-Bbwn8IIuG3vQtyP0mKyrHba4QBn68xQH-0-51b05ef204611015cb12220f260d4ba0)
图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=1739274681-K6zxQK3ztQKm4isHehUEbc3XCB032eQH-0-51ad7f0c944fe8909fc72645743a7fb1)
图4-16 Mybatis-Generator项目执行LOG示例图
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P102_30291.jpg?sign=1739274681-4Lq3W5NaWQ0C1oiP7j08xVkgGgZJD6HK-0-b3205434c91b034aa8432658d3242e1b)
图4-17 Mybatis-Generator项目结构示例图
我们再来查看一下Mapper,其实在Mapper内已经默认生成了几个简单的方法,让我们看一下UserMapper接口的内容,代码如代码清单4-60所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T102_81046.jpg?sign=1739274681-MpO1rsoSNHXbd2Aka5TdufHt62xVojZX-0-0c3fd86345ab49d95a46d86c54cdb162)
UserMapper.xml也对应写好了SQL,代码内容如代码清单4-61所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T103_81047.jpg?sign=1739274681-vkgBxVF5d2o7KazBNMXESCcBAYzcVmkn-0-8babdb111f328d71651f34cf831bdd38)
这些自动生成的方法都是可以直接使用的,可以使用在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=1739274681-sfGM0S0wWwDg6TtN4aB7K2DM2YXkUqOc-0-2c74df603bb3e406efce8af4a6e49358)
配置文件除了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=1739274681-imc1BpocMlw1WCHNKbSnpFivTWDrXEuo-0-c1776603c0ae45405f7faea0f3f0ba36)
使用PageHelper其实特别方便,只要引入PageHelper类,然后设置页码和每页的数量即可,案例测试代码如代码清单4-65所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T106_81049.jpg?sign=1739274681-gJpfRKoOYl4RdAUmxyKDqne46iZ7Ipi8-0-31ce7b8bd632b38bbce42f4f44d32e43)
启动项目,在浏览器上访问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=1739274681-d4K23friKOwrGUiO4TBx1HV9wdtfkzXw-0-1d2d9409f68b6838431a6d728e296c4a)
接下来在配置文件中配置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=1739274681-5rWsqJjmYLMnClTeyaFv4UYB2LlQATiG-0-7b9ac49ade3a04425783202eb6f6b944)
关于dao层,这里我们需要继承Mybatis-Plus提供的BaseMapper,只在里面写一个查询用户列表(getUserList)的方法,代码如代码清单4-69所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81053.jpg?sign=1739274681-0xsn8mjh0x2p1g0L4Eg77WbUppDxCr22-0-ed0326541486721cff6956bb15376640)
在Mapper.xml内写出对应方法,如代码清单4-70所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81054.jpg?sign=1739274681-Dw1Hq8RJpl75dMP933GdiwV0XR2nOW5f-0-34c8743d376d10454a32ad88f2d7144b)
最后使用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=1739274681-VU2pG6jtyEpQMvb0IuNPTQyxu8cMVbnD-0-9efdb9cda20004e5de2eddec13561016)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T110_80889.jpg?sign=1739274681-N8kG36ICIqr9WmrUnPsOw8xIsNJ7O0Iz-0-fac3ba597b849be1cc14705b3d3fca94)