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所示。

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所示。

在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所示。

创建实体类User,其中使用@Alias注解也可以表明类别名,代码如代码清单4-52所示。

4.4.4 基于XML的使用

创建Mapper对应接口类UserMapper,在类上加入注解@Mapper,表明这是一个Mapper。我们提前定义5个方法,分别是:

• 根据用户名查询用户。

• 根据用户名修改用户。

• 根据用户名删除用户。

• 保存用户。

• 获取用户列表。

UserMapper接口代码如代码清单4-53所示。

在src/mian/resources/mapper下创建UserMapper.xml,对应写好在UserMapper接口类的方法,完整内容如代码清单4-54所示。

因为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所示。

4.4.6 测试运行

前面对大部分使用场景进行了介绍,接下来进行测试。新建一个Controller,分别对刚刚写的每一个数据库操作写一个方法进行测试,代码内容如代码清单4-56所示。

具体测试可以在浏览器上访问代码中的注释,每一个方法笔者都对应写了测试地址,以上都是笔者亲测无误的。

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所示。

这里需要注意的是,configurationFile配置的是Mybatis-Generator插件所存放的位置,本案例是在src/main/resources/mybatis-generator下创建了一个generatorConfig.xml文件,在配置文件中对需要配置的内容做了详细的说明,配置内容如代码清单4-58所示。

在Mybatis-Generator中有部分数据这里读取的是application.properties文件中的内容。下面给出application.properties文件中的配置,如代码清单4-59所示。

到这里,其实就已经配置完成了。接下来我们查看IntelliJ IDEA中,Maven的工具栏,可以看到已经安装了Mybatis-Generator插件,如图4-15所示。

图4-15 Mybatis-Generator项目插件示例图

我们看一下Maven操作日志,提示已经生成了dao层、实体类、Mapper文件,如图4-16所示。

去对应目录看看,果然这些都生成了,如图4-17所示。

图4-16 Mybatis-Generator项目执行LOG示例图

图4-17 Mybatis-Generator项目结构示例图

我们再来查看一下Mapper,其实在Mapper内已经默认生成了几个简单的方法,让我们看一下UserMapper接口的内容,代码如代码清单4-60所示。

UserMapper.xml也对应写好了SQL,代码内容如代码清单4-61所示。

这些自动生成的方法都是可以直接使用的,可以使用在Controller内对应的写方法测试,也可以使用测试用例测试,这里就不一一测试了。

4.4.8 PageHelper插件

在操作数据库的时候,分页是必不可少的一项任务,在使用MyBatis时,可以利用PageHelper插件对MyBatis插件进行分页。PageHelper支持常见的12种数据库,如Oracle、MySQL、MariaDB、SQLite、DB2、PostgreSQL、SQL Server等。

在pom文件中加入PageHelper依赖,依赖代码如代码清单4-62所示。

配置文件除了MySQL配置外,还添加了一个PageHelper插件的配置,也就是配置SQL方言,配置如代码清单4-63所示。

代码清单4-63 Mybatis-PageHelper项目配置文件代码

    #pagehelper分页插件配置
    pagehelper.helperDialect=mysql

实体类和之前的一样,这里就不反复介绍了。由于PageHelper插件只是用于分页,因此我们只是在Mapper内用注解写了一个查询所有用户的方法,如代码清单4-64所示。

使用PageHelper其实特别方便,只要引入PageHelper类,然后设置页码和每页的数量即可,案例测试代码如代码清单4-65所示。

启动项目,在浏览器上访问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所示。

接下来在配置文件中配置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所示。

关于dao层,这里我们需要继承Mybatis-Plus提供的BaseMapper,只在里面写一个查询用户列表(getUserList)的方法,代码如代码清单4-69所示。

在Mapper.xml内写出对应方法,如代码清单4-70所示。

最后使用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所示。