MyBatis-Plus如何最优雅最简洁地完成数据库操作

目录
  • 引言
  • 代码生成器
  • 项目初始化
  • 增删改
    • Service
    • Mapper
    • 查询
  • 枚举类
  • 逻辑删除
  • MyBatis-Plus-Example
  • 参考资料
  • 总结

引言

两点:

一,使用MyBatis-Plus最新版(3.0.1)完成相关操作

二,好久没写MyBatis操作数据库的博文了,有没有想我啊,哈哈,认真看,认真听,认真学。

测试效果:

使用swagger2显示API接口

swagge2 接口以及model信息

分页接口测试.png

下面听我细细道来,MyBatis-Plus的优雅、简洁与强大。

代码生成器

代码生成器,又被叫做逆向工程,MyBatis官方为了推广,自己也写了一个,我之前也使用这个,功能也是非常强大,强大以为支持自定义配置,那么问题来了,我该怎么配置才合理呢,所以,有人把所有的配置项都弄成中文的,还有人开发了生成插件,这些在我以往的博文中都看看到。MyBatis-Plus的代码生成器到底怎么样,这我就不评判了,我就这样说,用用看吧。

在MyBatis-Plus的官网文档中,有将代码生成器的问题,有配置详解,也有项目示例代码,复制来就可用。

我这次是用MP 3.0.1,也就是最新版,官方还没有更新呢,所以,我去找了很久的源码,才将这个完成,勉强适合自己的了。这个在 CodeGenerator Module中,可以下下下来,导入到IDE中,看一下,修改配置就能运行。有问题,也可以与我讨论。

功能列表:

[] 自动生成model类

[] 自动生成dao接口

[] 自动生成xml文件

[] 自动生成service接口

[] 自动生成service实现类

[] model支持Builder模式

[] 支持swagger2

[] 支持生成数据库字段常量

[] 支持生成Kotlin代码

[] ......

项目初始化

第一步:pom.xml引入MyBatis-Plus依赖,注意,不需要再引入MyBatis的包,因为我这里使用Spring Boot搭建的工程,所有因为方式见下:

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

第二步:将生成的代码,拷贝到相应的包下

代码目录结构

第三步:在配置文件中进行相应的配置

具体配置可参考官网,这里需要注意这样几个地方:

mybatis-plus:
  # xml
  mapper-locations: classpath:mapper/*Mapper.xml
  # 实体扫描,多个package用逗号或者分号分隔
  type-aliases-package: com.fengwenyi.mp3demo.model
  configuration:
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

日志:分页查询

第四步:在启动类上添加下面的注解

@EnableTransactionManagement
@MapperScan("com.fengwenyi.mp3demo.dao")

增删改

Service

我们一起去看源码 com.baomidou.mybatisplus.extension.service.IService<T>

增加:

    /**
     * <p>
     * 插入一条记录(选择字段,策略插入)
     * </p>
     *
     * @param entity 实体对象
     */
    boolean save(T entity);

修改:

    /**
     * <p>
     * 根据 ID 选择修改
     * </p>
     *
     * @param entity 实体对象
     */
    boolean updateById(T entity);

    /**
     * <p>
     * 根据 whereEntity 条件,更新记录
     * </p>
     *
     * @param entity        实体对象
     * @param updateWrapper 实体对象封装操作类
     * {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
     */
    boolean update(T entity, Wrapper<T> updateWrapper);

删除:

    /**
     * <p>
     * 根据 ID 删除
     * </p>
     *
     * @param id 主键ID
     */
    boolean removeById(Serializable id);

    /**
     * <p>
     * 根据 entity 条件,删除记录
     * </p>
     *
     * @param queryWrapper 实体包装类
     * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    boolean remove(Wrapper<T> queryWrapper);

Mapper

com.baomidou.mybatisplus.core.mapper.BaseMapper<T>

增加:

    /**
     * <p>
     * 插入一条记录
     * </p>
     *
     * @param entity 实体对象
     */
    int insert(T entity);

修改:

    /**
     * <p>
     * 根据 whereEntity 条件,更新记录
     * </p>
     *
     * @param entity        实体对象 (set 条件值,不能为 null)
     * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
     */
    int update(@Param(Constants.ENTITY) T entity,
               @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * <p>
     * 根据 ID 修改
     * </p>
     *
     * @param entity 实体对象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

删除:

    /**
     * <p>
     * 根据 entity 条件,删除记录
     * </p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根据 ID 删除
     * </p>
     *
     * @param id 主键ID
     */
    int deleteById(Serializable id);

以上相当于是常用API了,我们去看看,他是怎么实现的。毫无疑问,Mapper是底层,Service调用Mapper去执行sql,完成相关操作,所以,你完全可以直接调用Mapper完成相关操作,就跟使用MyBatis一样。下面我们去看看,他帮我们写的Service是什么样子,这里只看一个修改操作吧。

接口:

    /**
     * <p>
     * 根据 whereEntity 条件,更新记录
     * </p>
     *
     * @param entity        实体对象
     * @param updateWrapper 实体对象封装操作类
     * {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
     */
    boolean update(T entity, Wrapper<T> updateWrapper);

实现:

    @Override
    public boolean update(T entity, Wrapper<T> updateWrapper) {
        return ServiceImpl.retBool(baseMapper.update(entity, updateWrapper));
    }

    /**
     * <p>
     * 判断数据库操作是否成功
     * </p>
     * <p>
     * 注意!! 该方法为 Integer 判断,不可传入 int 基本类型
     * </p>
     *
     * @param result 数据库操作返回影响条数
     * @return boolean
     */
    protected static boolean retBool(Integer result) {
        return SqlHelper.retBool(result);
    }

    /**
     * <p>
     * 判断数据库操作是否成功
     * </p>
     *
     * @param result 数据库操作返回影响条数
     * @return boolean
     */
    public static boolean retBool(Integer result) {
        return null != result && result >= 1;
    }

哈哈,是不是我们自己也会这样写啊!

查询

接下来,我们一起讨论下查询吧。

MP 3.x,查询接口发生了很大的变化,反正我是不喜欢的,你就弄一个什么开头啊,到时候,我一点就知道有哪些方法了,他这里有 list*, get*,反正就是一个字——没必要。

先看下接口说明:

    /**
     * <p>
     * 查询列表
     * </p>
     *
     * @param queryWrapper 实体对象封装操作类
     * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    List<T> list(Wrapper<T> queryWrapper);

      /**
     * <p>
     * 根据 ID 查询
     * </p>
     *
     * @param id 主键ID
     */
    T getById(Serializable id);

    /**
     * <p>
     * 根据 Wrapper,查询一条记录
     * </p>
     *
     * @param queryWrapper 实体对象封装操作类
     * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    T getOne(Wrapper<T> queryWrapper);

嗯,差不多了吧,这样需要注意这样一个方法:

    /**
     * <p>
     * 从list中取第一条数据返回对应List中泛型的单个结果
     * </p>
     *
     * @param list
     * @param <E>
     * @return
     */
    public static <E> E getObject(List<E> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            int size = list.size();
            if (size > 1) {
                SqlHelper.logger.warn(
String.format("Warn: execute Method There are  %s results.", size));
            }
            return list.get(0);
        }
        return null;
    }

下面说下分页的问题

根据官网的说法,需要借助插件,这我们是可以理解。

在Spring Boot启动类里面添加:

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

这样就可以使用他提供的分页接口了:

    /**
     * <p>
     * 翻页查询
     * </p>
     *
     * @param page         翻页对象
     * @param queryWrapper 实体对象封装操作类
     * {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);

我们去看一下:

    @Override
    public IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper) {
        queryWrapper = (Wrapper<T>) SqlHelper.fillWrapper(page, queryWrapper);
        return baseMapper.selectPage(page, queryWrapper);
    }

    /**
     * <p>
     * 填充Wrapper
     * </p>
     *
     * @param page    分页对象
     * @param wrapper SQL包装对象
     */
    @SuppressWarnings("unchecked")
    public static Wrapper<?> fillWrapper(IPage<?> page, Wrapper<?> wrapper) {
        if (null == page) {
            return wrapper;
        }
        if (ArrayUtils.isEmpty(page.ascs())
            && ArrayUtils.isEmpty(page.descs())
            && ObjectUtils.isEmpty(page.condition())) {
            return wrapper;
        }
        QueryWrapper qw;
        if (null == wrapper) {
            qw = new QueryWrapper<>();
        } else {
            qw = (QueryWrapper) wrapper;
        }
        // 排序
        if (ArrayUtils.isNotEmpty(page.ascs())) {
            qw.orderByAsc(page.ascs());
        }
        if (ArrayUtils.isNotEmpty(page.descs())) {
            qw.orderByDesc(page.descs());
        }
        // MAP 参数查询
        if (ObjectUtils.isNotEmpty(page.condition())) {
            qw.allEq(page.condition());
        }
        return qw;
    }

    /**
     * <p>
     * 根据 entity 条件,查询全部记录(并翻页)
     * </p>
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

分页的代码大抵就是这样,我之前也自己写过,思路还是相当来说比较简单,关键是看你的查询添加如何封装,分页类如何构造。

这里有一点说明:

分页从 1 开始 !!!

枚举类

1、实现 接口

/**
 * <p>
 * 自定义枚举接口
 * </p>
 *
 * @author hubin
 * @since 2017-10-11
 */
public interface IEnum<T extends Serializable> {

    /**
     * 枚举数据库存储值
     */
    T getValue();

}

2、实现注意

    @Override
    public Integer getValue() {
        return this.value;
    }

    @JsonValue
    public String getDesc() {
        return desc;
    }

这是Jackson的写法,我没用FastJson,所以用的伙伴,去官网看一下:FastJson看官网

3:被忘了在配置文件中添加扫描:

mybatis-plus:
  # 扫描枚举类 # 支持统配符 * 或者 ; 分割
  type-enums-package: com.fengwenyi.mp3demo.enums

差不多了吧,好像

逻辑删除

1、代码生成器中配置:

new StrategyConfig().setLogicDeleteFieldName("is_delete") // 逻辑删除属性名称

或者,你可以手写,参考:

    @ApiModelProperty(value = "是否逻辑删除(true:删除;false:正常(默认))")
    @TableLogic
    private Boolean isDelete;

2、自定义数据库的值:

mybatis-plus:
  global-config:
    db-config:
      #逻辑删除配置
      logic-delete-value: 1
      logic-not-delete-value: 0

MyBatis-Plus-Example

MyBatis-Plus的代码都会上传到github上

https://github.com/fengwenyi/MyBatis-Plus-Example

参考资料

MyBatis-Plus

MyBatis-Plus 使用枚举自动关联注入

mybatis-plus插件使用的一些问题

设计模式之Builder模式

修复Long类型太长,而Java序列化JSON丢失精度问题的方法

总结

到此这篇关于MyBatis-Plus最优雅最简洁地完成数据库操作的文章就介绍到这了,更多相关MyBatis-Plus数据库操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot Mybatis-Plus数据库单元测试实战(三种方式)

      单元测试长久以来是热门话题,本文不会讨论需不需要写单测,可以看看参考资料1,我个人认为写好单测应该是每个优秀开发者必备的技能,关于写单测的好处在这里我就不展开讨论了,快速进入本文着重讨论的话题,如何写好数据库单测.   为什么要写数据库单测? 相信大家是不是有这样类似的经历,在写完复杂的sql语句后,自信满满的提测,发现很大一部分Bug都是因为sql语句出现问题了,要么少写逗号,要么漏了字段,悔不当初哇,为啥写完不多测测呢!   没关系!这就教你如何写数据库单测,让你轻松告别数据库相关bug

  • 搭建MyBatis-Plus框架并进行数据库增删改查功能

    搭建MyBatis-Plus框架并进行数据库添加 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 1.搭建环境 Jdk:jdk1.8.0_261 Idea:IntelliJ IDEA Maven:apache-maven-3.3.6 MySQL:mysql-5.5.61 2.项目搭建 3.配置maven 4.项目结构 创建数据库 CREATE DATABASE tzy03; USE tzy03;

  • 关于Mybatis-Plus字段策略与数据库自动更新时间的一些问题

    字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" 问题描述: 当字段策略为 0 "忽略判断" 的时候,如果实体和数据库有字段是需要自动更新的,例如update_time,更新某条记录的时候自动刷新update_time,理论上我们在业务控制的时候是不需要设置update_time的,利用数据库特性就好,但是在该字段策略下,业务逻辑要更新字段(没有主动设置 update_time),这时候因为忽略判断,

  • MyBatis-Plus如何最优雅最简洁地完成数据库操作

    目录 引言 代码生成器 项目初始化 增删改 Service Mapper 查询 枚举类 逻辑删除 MyBatis-Plus-Example 参考资料 总结 引言 两点: 一,使用MyBatis-Plus最新版(3.0.1)完成相关操作 二,好久没写MyBatis操作数据库的博文了,有没有想我啊,哈哈,认真看,认真听,认真学. 测试效果: 使用swagger2显示API接口 swagge2 接口以及model信息 分页接口测试.png 下面听我细细道来,MyBatis-Plus的优雅.简洁与强大.

  • JavaScript代码优雅,简洁的编写技巧总结

    1. 强类型检查 用===代替 == // 如果处理不当,它会极大地影响程序逻辑.这就像,你想向左走,但由于某种原因,你向右走 0 == false // true 0 === false // false 2 == "2" // true 2 === "2" // false // 例子 const value = "500"; if (value === 500) { console.log(value); // 条件不成立,不会进入 } i

  • Spring Boot整合mybatis使用注解实现动态Sql、参数传递等常用操作(实现方法)

    前面介绍了Spring Boot 整合mybatis 使用注解的方式实现数据库操作,介绍了如何自动生成注解版的mapper 和pojo类. 接下来介绍使用mybatis 常用注解以及如何传参数等数据库操作中的常用操作. 其实,mybatis 注解方式 和 XML配置方式两者的使用基本上相同,只有在构建 SQL 脚本有所区别,所以这里重点介绍两者之间的差异,以及增删改查,参数传递等注解的常用操作. 详解SpringBoot 快速整合Mybatis(去XML化+注解进阶)已经介绍过了,不清楚的朋友可

  • Mybatis之Select Count(*)的获取返回int的值操作

    本文将介绍,SSM中mybatis 框架如何获取Select Count(*)返回int 的值. 1. Service 代码: public boolean queryByunitclass(String unitclass, String unitsubclass) throws Exception { int count = matceMachineUnitMapper.queryByunitclass(unitclass, unitsubclass); if (count > 0) { r

  • mybatis的dtd约束文件及配置文件xml自动提示操作

    一.mybatis的dtd约束文件位置 我使用的是mybatis-3.2.7这个版本的mybatis,里面的核心jar包是:mybatis-3.2.7.jar,将这个jar包解压缩后进入\org\apache\ibatis\builder\xml 二.mybatis的dtd约束文件下载 (1)mybatis-3-config.dtd约束文件下载: http://mybatis.org/dtd/mybatis-3-config.dtd (2)mybatis-3-mapper.dtd约束文件下载:

  • SpringBoot整合Mybatis实现高德地图定位并将数据存入数据库的步骤详解

    第一步配置yml文件 server: port: 8080 spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver thymel

  • Mybatis中多个对象包含同一个对象的处理操作

    多个对象对应一个对象时,应该如何进行查询? 例如 关键字:association : 联系 ,关联 多个人可以关联一个人. 首先做一些准备,如:实体类,工具类和Mybatis核心文件 实体类: //老师实体类 package com.MLXH.pojo; public class Teacher { private int id; private String name; public Teacher() { } public Teacher(int id, String name) { thi

  • MyBatis-Plus中最简单的查询操作教程(Lambda)

    目录 引言 Lambda 分页查询 条件查询 [1]多eq [2]or 条件构造器 自定义sql 封装我们自己的Service 资料 总结 引言 MyBatis-Plus | 最优雅最简洁地完成数据库操作 是对MyBatis-Plus的功能进行简单介绍,虽然是介绍,也让我们领略到他的优雅与强大.你是不是已经被吸引了?别着急,上一节,我们算是参观了MyBatis的风景,这一节,我将带你领略他独特的魅力. Lambda 官方表示,3.x支持Lambda表达式,那应该怎么使用呢?我们来看个例子: Qu

  • mybatis同一张表多次连接查询相同列赋值问题小结

    最近遇到的一些问题总结: 1. MySQL数据库同一张表做四次左连接查询数据冗余. a. mysql数据库连接查询 b. mysql表数据去重 2. mybatis查询相同列赋值重复问题. a. 使用mybatis强大的resultMap b. mysql数据查询别名 数据库表为 Create Table CREATE TABLE `STUDENT_SCORE` ( `score_id` int(11) unsigned NOT NULL AUTO_INCREMENT,//主键 `test_id

  • 一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程

    前言 SSM(Spring+SpringMVC+Mybatis)是目前较为主流的企业级架构方案,不知道大家有没有留意,在我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配合注解的方式,编程非常快捷,而且通过restful风格定义url,让地址看起来非常优雅. 另外,MyBatis也可以替换Hibernate,正因为MyBatis的半自动特点,我们程

随机推荐