我们在项目中使用 MyBaits 的时候,针对需要操作的一张表,需要创建实体类、Mapper 映射器、Mapper 接口,里面又有很多的字段和方法的配置,这部分的工作是非常繁琐的。而大部分时候我们对于表的操作是相同的,比如根据主键查询、根据Map查询、单条插入、批量插入、根据主键删除等等等等。

当我们的表很多的时候,意味着有大量的重复工作。所以有没有一种办法,可以根据我们的表,自动生成实体类、Mapper映射器、Mapper接口,里面包含了我们需要用到的这些基本方法和SQL呢?

1.MBG

MyBatis也提供了一个这样的东西,叫做 MyBatis Generator,简称 MBG。我们只需要修改一个配置文件,使用相关的 jar 包命令或者Java 代码就可以帮助我们生成实体类、映射器和接口文件。

1.1 使用步骤

第一步,引入依赖

<plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><dependencies><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.7</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.13</version></dependency></dependencies><executions><execution><id>mybatis generator</id><phase>package</phase><goals><goal>generate</goal></goals><configuration><!--允许移动生成的文件--><verbose>true</verbose><!--允许自动覆盖文件--><overwrite>true</overwrite><configurationFile>src/main/resources/generatorConfig.xml</configurationFile></configuration></execution></executions>
</plugin>

第二步,配置文件(generator-config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>  <!-- 1.数据库信息 --><!-- 数据库驱动-->  <classPathEntry  location="mysql-connector-java-5.1.38.jar"/>  <context id="DB2Tables"  targetRuntime="MyBatis3">  <commentGenerator>  <property name="suppressDate" value="true"/>  <!-- 是否去除自动生成的注释 true:是 : false:否 -->  <property name="suppressAllComments" value="true"/>  </commentGenerator>  <!--数据库链接URL,用户名、密码 -->  <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/mybatis-test" userId="root" password="123456">  </jdbcConnection>  <javaTypeResolver>  <property name="forceBigDecimals" value="false"/>  </javaTypeResolver>  <!-- 2.生成文件位置:实体类(entity),接口(dao),映射文件(mapper)--><!-- 生成模型的包名和位置-->  <javaModelGenerator targetPackage="com.my.entity" targetProject="src">  <property name="enableSubPackages" value="true"/>  <property name="trimStrings" value="true"/>  </javaModelGenerator>  <!-- 生成映射文件的包名和位置-->  <sqlMapGenerator targetPackage="com.my.mapper" targetProject="src">  <property name="enableSubPackages" value="true"/>  </sqlMapGenerator>  <!-- 生成DAO的包名和位置-->  <javaClientGenerator type="XMLMAPPER" targetPackage="com.my.dao" targetProject="src">  <property name="enableSubPackages" value="true"/>  </javaClientGenerator>  <!-- 3.要生成的数据库表信息 --><!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->  <table tableName="blog" domainObjectName="Blog" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table></context>
</generatorConfiguration>

第三步,执行mybatis-generator插件。生成的类和xml如下图:

1.2 mapper中的函数

我们随便打开一个dao层的接口,看 MBG 给我们生成了什么方法:

public interface UserMapper {// 按条件计数int countByExample(UserExample example);// 插入数据(返回值为ID)int insert(User record);// 选择性插入,插入值不为null的数据int insertSelective(User record);// 按主键删除int deleteByPrimaryKey(Integer uId);// 按条件删除int deleteByExample(UserExample example);// 按主键查询User selectByPrimaryKey(Integer uId);// 按条件查询List<User> selectByExample(UserExample example);// 按主键更新int updateByPrimaryKey(User record);// 按条件更新int updateByExample(@Param("record") User record, @Param("example") UserExample example);// 按主键更新值不为null的字段int updateByPrimaryKeySelective(User record);// 按条件更新值不为null的字段int updateByExampleSelective(@Param("record") User record, @Param("example") UserExample example);
}

那这些作为参数的 Example 是什么呢?

1.2 Example

MBG 的配置文件里面有一个 Example 的开关,这个东西用来构造复杂的筛选条件的,换句话说就是根据我们的代码去生成 where 条件

xxxExample example = new xxxExample();
Criteria criteria = new Example().createCriteria();
方法 说明
example.setOrderByClause(“字段名 ASC”); 添加升序排列条件,DESC为降序
example.setDistinct(false) 去除重复,boolean型,true为选择不重复的记录。
criteria.andXxxIsNull 添加字段xxx为null的条件
criteria.andXxxIsNotNull 添加字段xxx不为null的条件
criteria.andXxxEqualTo(value) 添加xxx字段等于value条件
criteria.andXxxNotEqualTo(value) 添加xxx字段不等于value条件
criteria.andXxxGreaterThan(value) 添加xxx字段大于value条件
criteria.andXxxGreaterThanOrEqualTo(value) 添加xxx字段大于等于value条件
criteria.andXxxLessThan(value) 添加xxx字段小于value条件
criteria.andXxxLessThanOrEqualTo(value) 添加xxx字段小于等于value条件
criteria.andXxxIn(List<?>) 添加xxx字段值在List<?>条件
criteria.andXxxNotIn(List<?>) 添加xxx字段值不在List<?>条件
criteria.andXxxLike(“%”+value+”%”) 添加xxx字段值为value的模糊查询条件
criteria.andXxxNotLike(“%”+value+”%”) 添加xxx字段值不为value的模糊查询条件
criteria.andXxxBetween(value1,value2) 添加xxx字段值在value1和value2之间条件
criteria.andXxxNotBetween(value1,value2) 添加xxx字段值不在value1和value2之间条件

原理:在实体类中包含了两个有继承关系的Criteria,用其中自动生成的方法来构建查询条件。把这个包含了 Criteria 的实体类作为参数传到查询参数中,在解析 Mapper映射器的时候会转换成SQL条件。

UserMapper mapper = session.getMapper(UserMapper.class);
UserExample example = new UserExample ();
UserExample.Criteria criteria = example.createCriteria();
criteria.andUidEqualTo(1);
List<Blog> list = mapper.selectByExample(example)

生成的sql语句

select 'true' as QUERYID, uid, username, phone from t_user WHERE ( uid = ? )

1.4 MBG 存在的问题

当我们使用 MBG 时,如果表字段发生了变化,我们需要修改实体类和 Mapper 文件定义的字段和方法。如果是增量维护,那么一个个文件去修改。如果是全量替换,我们还要去对比用 MBG 生成的文件。字段变动一次就修改一次,维护起来非常麻烦。

解决这个问题,我们有两种思路。

解决方案一

因为 MyBatis 的 Mapper 是支持继承的,所以我们可以把 Mapper.xml 和 Mapper 接口都分成两个文件。

  • 一个是MBG生成的,这部分是固定不变的。
  • 一个是自己手动创建的DAO类,并且继承生成的接口

所以以后发生变化的部分就在手动创建的DAO里面维护。具体操作步骤如下:

第一步,BlogMapperExt 继承generator生成的 Mapper

public interface BlogMapperExt extends BlogMapper {public Blog selectBlogByName(String name);
}

第二步,编写扩展的 mapper 文件 – BlogMapperExt.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-
3-mapper.dtd">
<mapper namespace="com.my.mapper.BlogMapperExt"><!-- 只能继承 statement,不能继承sql、resultMap等标签 --><!-- 所以,如果收数据库字段名发生了变化,可以在这里重新定义 resultMap --><!-- 但是,对于那些没有发生变化的字段或逻辑,仍然可以复用 --><resultMap id="BaseResultMap" type="blog"><id column="bid" property="bid" jdbcType="INTEGER"/><result column="name" property="name" jdbcType="VARCHAR"/><result column="author_id" property="authorId" jdbcType="INTEGER"/></resultMap><!-- 在 parent xml 和 child xml 的 statement id 相同的情况下,会使用  child xml 的 statement id --><select id="selectBlogByName" resultMap="BaseResultMap" statementType="PREPARED">select * from blog where name = #{name}</select>
</mapper>

3.配置mybatis-conf,扫描新的 BlogMapperExt.xml

<mappers><mapper resource="BlogMapper.xml"/><mapper resource="BlogMapperExt.xml"/>
</mappers>

以后只要修改Ext的文件就可以了。但是这么做有一个缺点 – 文件会增多冗余。

解决方案二

既然针对每张表生成的基本方法都是一样的,也就是公共的方法部分代码都是一样的,那么就可以把这部分合并成一个文件,通过泛型来实现多种类型。

public interface BlogMapper extends Mapper<Blog>

除了配置文件变动的问题之外,通用Mapper还可以解决:

  • 每个Mapper接口中大量的重复方法的定义
  • 屏蔽数据库的差异
  • 提供批量操作的方法
  • 实现分页

这下就引出了我们接下来要说的通用Mapper…

多提一句,通用Mapper和PageHelper作者是同一个人(刘增辉)

2.通用Mapper

这里就不再过多介绍通用Mapper了,下面说一下在 SpringBoot 中如何使用:

第一步,引入依赖:

<dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>1.3.2</version>
</dependency>

第二步,手动创建实体类

public class User {private Long uid;private String username;private String phone;private String password;// getter和setter这里就不列出来了
}

第三步,创建 dao 层的接口并继承 Mapper

@Mapper
public interface UserDao extends tk.mybatis.mapper.common.Mapper<User> {// 如果自动生成的sql不够我们用或者性能差,我们可以直接是使用注解写在接口中// @Insert、@Delete、@Update、@Select@Select("SELECT * from `user` WHERE uid = #{uid}")User selectUserByUid(long uid);@Update("UPDATE `user` set `password` = #{pwd} WHERE uid = #{uid}")int updatePwdByUid(String pwd, long uid);
}

使用方式跟上面 MBG 一样,都是提供了那些基本的函数和 Example。

3.Mybatis-plus

MyBatis-Plus 是原生 MyBatis 的一个增强工具,可以在使用原生 MyBatis 的所有功能的基础上,使用plus特有的功能。

MyBatis-Plus的核心功能:

另外,MyBatis-Plus 还自带了分页的功能

这里还是简单说一下 mybatis-plus 如何在 SpringBoot 中使用:

第一步,引入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.1</version>
</dependency>

第二步,手动创建实体类

public class User {private Long uid;private String username;private String phone;private String password;// getter和setter这里就不列出来了
}

第三步,创建 dao 层的接口并继承 BaseMapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;@Mapper
public interface UserMapper extends BaseMapper<User> {}

第四步,配置启用分页功能

@Configuration
public class MybatisPlusConfig {/*** 分页插件*/@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}

在使用上,mybatis-plus 与上面两个略有不同。我们下面就来看看继承的 BaseMapper 到底是什么样子把。

/*** Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能* <p>这个 Mapper 支持 id 泛型</p>*/
public interface BaseMapper<T> extends Mapper<T> {/*** 插入一条记录** @param entity 实体对象*/int insert(T entity);/*** 根据 ID 删除** @param id 主键ID*/int deleteById(Serializable id);/*** 根据 columnMap 条件,删除记录** @param columnMap 表字段 map 对象*/int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);/*** 根据 entity 条件,删除记录** @param wrapper 实体对象封装操作类(可以为 null)*/int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);/*** 删除(根据ID 批量删除)** @param idList 主键ID列表(不能为 null 以及 empty)*/int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);/*** 根据 ID 修改** @param entity 实体对象*/int updateById(@Param(Constants.ENTITY) T entity);/*** 根据 whereEntity 条件,更新记录** @param entity        实体对象 (set 条件值,可以为 null)* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)*/int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);/*** 根据 ID 查询** @param id 主键ID*/T selectById(Serializable id);/*** 查询(根据ID 批量查询)** @param idList 主键ID列表(不能为 null 以及 empty)*/List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);/*** 查询(根据 columnMap 条件)** @param columnMap 表字段 map 对象*/List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);/*** 根据 entity 条件,查询一条记录** @param queryWrapper 实体对象封装操作类(可以为 null)*/T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);/*** 根据 Wrapper 条件,查询总记录数** @param queryWrapper 实体对象封装操作类(可以为 null)*/Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);/*** 根据 entity 条件,查询全部记录** @param queryWrapper 实体对象封装操作类(可以为 null)*/List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);/*** 根据 Wrapper 条件,查询全部记录** @param queryWrapper 实体对象封装操作类(可以为 null)*/List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);/*** 根据 Wrapper 条件,查询全部记录* <p>注意: 只返回第一个字段的值</p>** @param queryWrapper 实体对象封装操作类(可以为 null)*/List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);/*** 根据 entity 条件,查询全部记录(并翻页)** @param page         分页查询条件(可以为 RowBounds.DEFAULT)* @param queryWrapper 实体对象封装操作类(可以为 null)*/IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);/*** 根据 Wrapper 条件,查询全部记录(并翻页)** @param page         分页查询条件* @param queryWrapper 实体对象封装操作类*/IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

【MyBatis】高级特性(三):MBG、通用Mapper、Mybatis-plus相关推荐

  1. MBG+通用Mapper使用教程!

    MBG+通用Mapper使用教程 MBG+通用Mapper使用步骤 MBG 1.引入依赖(MBG依赖,mabatis,数据库驱动,数据源,lombok) 2.配置连接相关参数 3.将generator ...

  2. mysql通用mapper_通用Mapper(Mybatis)

    1.Mapper的简单介绍 2.Mapper的作用 通用Mapper可以通过Mybatis的拦截器原理,动态的帮我们实现单表的增删改查功能,大大降低了我们的开发成本,减少了我们的工作量. 3.Mapp ...

  3. mybatis入门(三)之Mapper XML 文件

    转载自   mybatis Mapper XML 文件 Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单 ...

  4. 三个插件Lombok、MBG和通用mapper文件的使用

    一.Lombok Lombok 是一个简化Java代码的工具 作用:能通过注解的方式,在编译时自动为类生成构造器.get/set.equals.toString.hashcode方法 使用: 1.引入 ...

  5. 通用mapper(mapper-mybatis)

    目录 1.1 通用mapper简介 1.2 通用mapper快速入门(文档) 1.3 添加依赖 1.4和 Spring 集成 1.4.1 XML 配置 1.使用 MapperScannerConfig ...

  6. SSM-Mybatis通用Mapper

    Mybatis通用Mapper 介绍(重要) 如果使用过Mybaitis 的人都知道Mapper 他是一个接口 而这个接口内定义的方法 关联mapper.xml文件里的sql语句 使用Mybatis的 ...

  7. 通用mapper的使用

    一.通用mapper概述 它是mybatis的一个插件,单表查询的时候,使用通用mapper会非常的方便. 极大地方便开发人员,可以按照需要选择通用方法,还可以自定义通用方法. 不过它也有一个非常大的 ...

  8. 【通用mapper】项目升级通用Mapper引发的一连串问题以及问题解决

    项目环境 通用Mapper版本 <dependency><groupId>tk.mybatis</groupId><artifactId>mapper- ...

  9. 搭建SSM环境整合通用Mapper和PageHelper

    新建Maven工程 填写项目的Maven坐标 创建父工程依赖 ssm-parent 修改ssm-parent 的 pom.xml <project xmlns="http://mave ...

最新文章

  1. 更换XP SN的vbs
  2. c语言循环设计思想结构,C语言程序设计_05循环结构程序设计讲述.pptx
  3. MySQL多实例安装配置指南
  4. 架WSUS服务器 内网自动打补丁
  5. python3 爬虫 requests安装_BOSS直聘招聘信息获取之爬虫工具分析
  6. [html] HTML5中新添加的表单属性有哪些?
  7. Qt|C++工作笔记-对虚函数的进一步认识(关键是Qt中如何正确使用,达到想要的效果)
  8. python 读出指定的行_【python】有规律的文本中读取指定的行
  9. 异常:Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z
  10. nasdocker推荐,附小技巧
  11. Kernel那些事儿之内存管理(8) --- Slab(中)
  12. java 保存 设置_java的保存按钮怎么设置?
  13. java 开发规约插件_阿里巴巴Java开发规约IDE插件
  14. 1223 Dice Roll Simulation
  15. Python编写csdn刷博客数量软件
  16. 【魔改蜗牛星际】B双主板变“皇帝板”扩展到8个SATA口
  17. mac怎么查python的版本_Mac下如何查看Python的版本?
  18. 历代显卡精彩演示DEMO赏析点评之NV篇
  19. 计算各种面值人民币张数
  20. java 动态密码错误_什么是OTP:Java一次动态密码、付款码原理

热门文章

  1. 查看C盘Users的Appdata文件夹
  2. 2022安全生产监管人员特种作业证考试题库及在线模拟考试
  3. PyEcharts输出保存图片的多种方法
  4. python setdefault setdefault.append
  5. 基于MATLAB与SOIDWORKS的关节型六轴机械臂仿真
  6. Jetson Orin(Ubuntu20.04)安装NoMachine和Jtop
  7. automake 的使用(一)
  8. 电力系统潮流计算matlab仿真,计算结果自动保存到excel文件中
  9. 鸡泽:中国辣椒网引来11万份合同
  10. markdown根号