![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=1739533462-D6SKixyo0uTFdjoER3psCby8zG0inkni-0-de6a9df39090e2649a13455b1b27598d)
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=1739533462-DJAQsJB6J54i6YVacE6oZpyjfUNWHoEM-0-530ef09295bea19dd96462daa140061e)
在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=1739533462-8k9BNwGb7QO4PyqB7lVZBLC185Nfmhoe-0-f184c7434eb7c971129c476b8b63a75a)
创建实体类User,其中使用@Alias注解也可以表明类别名,代码如代码清单4-52所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T91_81036.jpg?sign=1739533462-E6iqBuDz3KTefUEVenYKaJJ8KtDUCxqH-0-13f216de74b10c3003262673be263bc0)
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=1739533462-J8qO6x2SR1Pw64JPb0pYiJw82KgkKUWN-0-69e35adc83eca9f7fd3aeea7c96e3619)
在src/mian/resources/mapper下创建UserMapper.xml,对应写好在UserMapper接口类的方法,完整内容如代码清单4-54所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T92_81038.jpg?sign=1739533462-yyY25d1DzEUgIEZkmGDdOdIMxF3Mut1Y-0-a5908e7384606f7b8cf9cb3c60420926)
因为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=1739533462-8F7CqtnztN9U689m6tTO7VHvBopMwHgK-0-c5009713d1bd1163f0e057b0111cdce4)
4.4.6 测试运行
前面对大部分使用场景进行了介绍,接下来进行测试。新建一个Controller,分别对刚刚写的每一个数据库操作写一个方法进行测试,代码内容如代码清单4-56所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T95_81041.jpg?sign=1739533462-YoZG3TDIAJUx3pOu6rJu69Sg7VVSmWSk-0-2918ad6c5ccb759caa3d6316a4d552bd)
具体测试可以在浏览器上访问代码中的注释,每一个方法笔者都对应写了测试地址,以上都是笔者亲测无误的。
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=1739533462-MxfuRidukGNE8pPR9EfSfV8xNqlolx4x-0-84ef448f364fdcc28c9e03544f3651f9)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T98_80863.jpg?sign=1739533462-goMOHU18vG40jwPMlhoA81545MTgo4rr-0-4ad434693d5d5029bc437ca8f4a6e0f5)
这里需要注意的是,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=1739533462-G3i2WyjSRDSvK5n7oXXgASjyMWiiMVJa-0-dbcb929769213bbffcf0f235ae122e81)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T100_80865.jpg?sign=1739533462-9t1PD4abMWuhsGQsvlo43lE0RCqX0eP3-0-a6bdcd18c7c732e47d8e9debcba38e68)
在Mybatis-Generator中有部分数据这里读取的是application.properties文件中的内容。下面给出application.properties文件中的配置,如代码清单4-59所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T101_81045.jpg?sign=1739533462-FnXHd6r9HUpRQrOMdWcBAgpd77raEvYf-0-d2b46dd5c9338b416490b8d688bfe2b4)
到这里,其实就已经配置完成了。接下来我们查看IntelliJ IDEA中,Maven的工具栏,可以看到已经安装了Mybatis-Generator插件,如图4-15所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P101_30282.jpg?sign=1739533462-0dmuhVzMWASr6fsMNvRgHQ7ud04NksyV-0-2fa9d2e4d8fd941cf46fff9e058ca190)
图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=1739533462-q0Yvdcc4QKkrAMSpiTb5DSWzb3xWSHvN-0-e23387c02c114fed6be4c668afd08134)
图4-16 Mybatis-Generator项目执行LOG示例图
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-P102_30291.jpg?sign=1739533462-g66F6qzlA2WTBm5swQcR8kIFi070WKwm-0-a9e26fec59e218f3e6e6e96bb95cf2c7)
图4-17 Mybatis-Generator项目结构示例图
我们再来查看一下Mapper,其实在Mapper内已经默认生成了几个简单的方法,让我们看一下UserMapper接口的内容,代码如代码清单4-60所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T102_81046.jpg?sign=1739533462-K5blvzTwjOOBW3mgTn1y8BfxQQ2Lj4tg-0-dac6bc08e6cbe15080d68cccd39e889d)
UserMapper.xml也对应写好了SQL,代码内容如代码清单4-61所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T103_81047.jpg?sign=1739533462-4YviOeC5hSVsWmzY8HUZniKvjOSGZZSo-0-a44dd9c0ea3abf7f12d76d3aa539e58b)
这些自动生成的方法都是可以直接使用的,可以使用在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=1739533462-5TzxvEZWos90WKiCn8KLZW91M2MuQJrt-0-7feff54d7774551931b864c724d153f7)
配置文件除了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=1739533462-59bbMlMzPIwR0wiQ2oQF6YANcSVwgycG-0-bab55dd83c6d30e0893e24a4c54d9660)
使用PageHelper其实特别方便,只要引入PageHelper类,然后设置页码和每页的数量即可,案例测试代码如代码清单4-65所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T106_81049.jpg?sign=1739533462-fFDcQEX0GdqrfFRs88EBvm2Eg5ulBIhX-0-e63f8bd094b145e975d807f7ded4114e)
启动项目,在浏览器上访问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=1739533462-7xhXBHfxSiBsW0CY6Abwch7Ndtw0hw1J-0-be9b940a61a8ce9d79562d8eac872090)
接下来在配置文件中配置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=1739533462-IymwDSPk6tJV95NEtqKzI9P2HwuNr8Zm-0-c35d50200fbc3b9b6f21165e51f36a20)
关于dao层,这里我们需要继承Mybatis-Plus提供的BaseMapper,只在里面写一个查询用户列表(getUserList)的方法,代码如代码清单4-69所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81053.jpg?sign=1739533462-aQaAkvJ5J5kTF4mtuOEwZUEYBFYGZdvI-0-11fd554f0d42e913de6aa50addb1076c)
在Mapper.xml内写出对应方法,如代码清单4-70所示。
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T108_81054.jpg?sign=1739533462-9o4itTbXjVLoyYhniqYu8sNkyPWvq8fk-0-8d2469d8b2d1f7f3a414923e20baa858)
最后使用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=1739533462-59iZ2WBkNeORnJXwOogZjBdexdimR6jz-0-a52326e97ae07beefc17f1b7ae562b8b)
![](https://epubservercos.yuewen.com/47855F/15056703904175906/epubprivate/OEBPS/Images/Figure-T110_80889.jpg?sign=1739533462-yEbbt9N0Jke5eggRKJRxE45D3MAvFaL4-0-dcac5f185155b8a3d59b2c7e6e4dec03)