一、发展历程

  依稀记得大学期间,类中写sql语句的日子,一个sql语句占据了大部分时间,到后来hibernate的出现算是解决了这一痛点。工作

后,我们又接触到了mybatis这样的框架,瞬间感觉这个世界美好了很多。但岂能就此满足。借机与mybatis的出现,我们已经将好多

逻辑处理搬到xml文件中利用sql进行处理,耦合性就变得十分大,如果没有MybatisPlus的出现(后文简称MP),这可能就是我们当前认

知下最常规且常用的操作,直到我接触Python后,再到MP,瞬间感觉“人生苦短,快用MP”(此处我们只讨论MP带来的效率提升,至

于他的局限性,此文不做赘述后续会单独讲解)

  废话不多说,让我们从零开始,进入MP的体验。

二、MP旅程

2.1、优势及特性

  请参考MP官网

2.2、pom文件引入

<!-- mybatisPlus与SpringBoot的整合 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency> <!-- 根据表逆向生成代码 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency>

2.3、流程讲解

  1、利用逆向工程生成entity与mapper接口,mapper xml文件(后续专门出一片逆向工程)。

  2、注入Mapper操作或者利用service层操作(主要用于屁来给你操作,自带事务)。

  3、我们需要考虑的就是,如何组装条件。

  4、多张表操作时,在service进行数据组装。

  5、将返回的数据,按照前端要求封装到返回的dto中。

2.4、Entity

  与数据库的表一一对应,将表列抽象成实体类属性,逆向生成后,原则上不能改动,统一在dto进行处理

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="SiteProjectSource对象", description="角色与项目来源关联表")
public class SiteProjectSource implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO)
private Integer id; private Integer roleId; private String roleName; private String projectSource; private Date updateTime;
}

2.5、Mapper接口

  默认不提供接口,如果业务需要特殊处理,我们需要自己扩展MapperEX项目,进行继承扩展

默认生成的文件,一般不做改动。

public interface SiteProjectSourceMapper extends BaseMapper<SiteProjectSource> {

}

2.6、Mapper 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.cbi.site.provider.mapper.SiteProjectSourceMapper"> </mapper>

2.7、IService接口

  继承的IService接口,是MP对外提供的

public interface ISiteProjectSourceService extends IService<SiteProjectSource> {

    SResponseBean updateProjectSource(SRequestBean<SiteProjectSourceUpdateReq> updateReq) throws BaseBusinessException;

    SResponseBean queryProjectSourcePage(SRequestBean<SiteProjectSourcePageQueryReq> pageQueryReq) throws  Exception;
}

2.8、Service实现类

@Service
public class SiteProjectServiceImpl extends ServiceImpl<SiteProjectMapper, SiteProject> implements ISiteProjectService { @Autowired
private SiteProjectMapper siteProjectMapper; @Autowired
private SiteWorkOrderMapper siteWorkOrderMapper; /**
* 创建项目信息
* @param createReqs 请求参数
* */
@Override
public SResponseBean createProject(SRequestBean<List<SiteProjectCreateReq>> createReqs) throws BaseBusinessException {
List<SiteProjectCreateReq> body = createReqs.getBody();
List<SiteProject> siteProjects = SBeanUtils.convertToResponse(SiteProject.class, body);
     //批量插入需要使用this调用,即MP的IService提供的接口
boolean flag = this.saveBatch(siteProjects);
AssertUtils.isTrue(flag, SCodeEnum.INSERT_ERROR);
return SResponseUtil.output(SCodeEnum.SUCCESS);
} @Override
public SResponseBean enableOrdisableProject(SRequestBean<List<SiteProjectModifyReq>> modifyReqs, String flag) throws BaseBusinessException {
//利用lambda组装查询条件
     List<SiteProject> siteProjects = modifyReqs.getBody().stream().map(
r -> new SiteProject().setId(r.getId()).setEnabled(flag)
).collect(Collectors.toList());
     //利用ids进行批量更新
boolean updateFlag = this.updateBatchById(siteProjects);
AssertUtils.isTrue(updateFlag, SCodeEnum.INSERT_ERROR);
return SResponseUtil.output(SCodeEnum.SUCCESS);
} @Override
public SResponseBean updateProject(SRequestBean<SiteProjectUpdateReq> updateReq) throws BaseBusinessException {
SiteProjectUpdateReq body = updateReq.getBody();
SiteProject siteProject = BeanUtil.toBean(body, SiteProject.class);
     //单条更新,我们利用Mapper即可
int updateNum = siteProjectMapper.updateById(siteProject);
AssertUtils.isTrue(updateNum>0, SCodeEnum.UPDATE_ERROR);
return SResponseUtil.output(SCodeEnum.SUCCESS);
} @Override
public SResponseBean queryProject(SRequestBean<SiteProjectQueryReq> queryReq) throws BaseBusinessException {
SiteProjectQueryReq body = queryReq.getBody();
SiteProject siteProject = BeanUtil.toBean(body, SiteProject.class);

//官方建议利用LambdaQueryWrapper,灵活易于扩展,支持链式拼接条件,不用写死列名
          /*QueryWrapper<SiteProject> queryWrapper = new QueryWrapper<SiteProject>().setEntity(siteProject);
          if(Objects.nonNull(body.getUpdateTimeStart())) {
              queryWrapper.ge("update_time", body.getUpdateTimeStart());
          }

      if(Objects.nonNull(body.getUpdateTimeEnd())) {
        queryWrapper.le("update_time", body.getUpdateTimeEnd());
      }*/

      LambdaQueryWrapper<SiteProject> queryWrapper = Wrappers.<SiteProject>lambdaQuery();
      //组装日期区间
      if(Objects.nonNull(body.getUpdateTimeStart())) {
        queryWrapper.ge(SiteProject::getUpdateTime, body.getUpdateTimeStart());
      }
      if(Objects.nonNull(body.getUpdateTimeEnd())) {
        queryWrapper.le(SiteProject::getUpdateTime, body.getUpdateTimeEnd());
      }

        List<SiteProject> siteProjects = siteProjectMapper.selectList(queryWrapper);
return SResponseUtil.output(siteProjects);
}

@Override
public SResponseBean queryProjectPage(SRequestBean<SiteProjectPageQueryReq> pageQueryReq) throws BaseBusinessException {
SiteProjectPageQueryReq body = pageQueryReq.getBody();
SiteProject siteProject = BeanUtil.toBean(body, SiteProject.class);
QueryWrapper<SiteProject> queryWrapper = new QueryWrapper<SiteProject>()
.setEntity(siteProject);
DBUtils.PackageDateInterval(queryWrapper,"update_time",body.getUpdateTimeStart(),body.getUpdateTimeEnd());
Page<SiteProject> page = new Page<>(body.getPageNum(), body.getPageSize());
     //天然的分页查询
Page<SiteProject> siteProjectPage = siteProjectMapper.selectPage(page, queryWrapper);
return SResponseUtil.output(siteProjectPage);
} }

2.9、总结

  没有一条sql,不用做事务控制,不用写for循环取插入等等,这一切都全赖MP的功劳,对于大部分场景,MP已经可以满足我们日常的操作,

我们不用关注sql是如何拼接的,如何运行的,将时间用于处理业务逻辑上。并且在当下流行的思想下,我们提倡最大可能的解耦,数据层我们

最好单表操作,利用service层继续处理,得利于lambda表达式的诞生,集合的处理变得更加丝滑,效率大大提升。我们需要不断思考,不断

学习,避免重复造轮子,人生苦短,我更喜欢开箱即用。但使用过后,我更建议大家撸撸源码,了解底层的实现。这样路才能走得远且扎实。

三、娱乐时光

3.1、新鲜事 

  贵州公交车司机结果公布,蓄意报复社会。

  每一条人名,背后都是一个家庭,将自己对社会的不公,发泄在20多条人命上,不管怎么说,都是无法被原谅。

但愿逝者安息,生者引以为戒,心理健康是当下最应被重视起来,希望大家平日少于人发生冲突,因为你永远不知道,

对方是否可能做出极端的行为。

3.2、歌曲推荐

  爱的故事(上),每一名男孩子都有过青春期的懵懂,都有过暗恋的经历,听苦情歌,不过“全为爱上了你偏偏你不知”,

祝愿全天下程序员都有归宿,名花有主的,可不要贪杯哦。

3.3、影视推荐

  源代码 Source Code (2011),我最喜欢影片中关于平行世界的暗示。

3.4、养眼壁纸

《你还在写sql语句吗?》人生苦短,进入MybatisPlus的丝滑体验的更多相关文章

  1. 写sql语句分别按日,星期,月,季度,年统计

    --写sql语句分别按日,星期,月,季度,年统计销售额 --按日 ' group by day([date]) --按周quarter ' group by datename(week,[date]) ...

  2. (摘至)程序员老鸟写sql语句的经验之谈

    做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构的设计,sql语句的编写等.因此在开发系统的时候,表结构设计是否合理,sql语句是否标准,写出的sql性能是否优化往往会成为 ...

  3. 程序员老鸟写sql语句的经验之谈

    做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构的设计,sql语句的编写等.因此在开发系统的时候,表结构设计是否合理,sql语句是否标准,写出的sql性能是否优化往往会成为 ...

  4. 写sql语句注意事项

    做管理系统的,无论是bs结构的还是cs结构的,都不可避免的涉及到数据库表结构的设计,sql语句的编写等.因此在开发系统的时候,表结构设计是否合理,sql语句是否标准,写出的sql性能是否优化往往会成为 ...

  5. Python 数据分析:让你像写 Sql 语句一样,使用 Pandas 做数据分析

    Python 数据分析:让你像写 Sql 语句一样,使用 Pandas 做数据分析 一.加载数据 import pandas as pd import numpy as np url = ('http ...

  6. PL/SQL中直接写SQL语句和用EXECUTE IMMEDIATE方法的区别

    PL/SQL中直接写SQL语句和用EXECUTE IMMEDIATE方法的区别 在PL/SQL中在执行SQL语句时可以直接写SQL或者可以把一个SQL语句拼成一个字符串,如下: select * fr ...

  7. 怎样写SQL语句可以提高数据库的性能

    1.首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录 ...

  8. 在程序开发中怎样写SQL语句可以提高数据库的性能

    以下内容是公司dba总结. 1. 首先要搞明白什么叫执行计划?   执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来 ...

  9. 在mybatis中写sql语句的一些体会

    本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...

随机推荐

  1. Redis系列(四):数据结构String类型中基本操作命令和源码解析

    1.介绍 string类型本质上是char[]数组的封装  中文网:http://www.redis.cn/commands.html#string  2.常用命令 set 命令 set命令的时间复杂 ...

  2. PowerBuilder中DW如何手动触发事件

    调用setitem默认不会触发itemchanged事件 如果想实现可手动触发itemchanged事件 事件格式如下: dw_list.event itemchanged( /*long row*/ ...

  3. Spring Boot 2 实战:利用Redis的Geo功能实现查找附近的位置

    1. 前言 老板突然要上线一个需求,获取当前位置方圆一公里的业务代理点.明天上线!当接到这个需求的时候我差点吐血,这时间也太紧张了.赶紧去查相关的技术选型.经过一番折腾,终于在晚上十点完成了这个需求. ...

  4. phpstorm设置xdebug调试

    phpstorm设置xdebug调试# wamp开发环境安装完成以后,打开网页,输入 :localhost 检测xdebug是否开启 3.若xdebug已开启,请找到你wamp或者phpstudy的安 ...

  5. layui动态添加的元素click等事件触发不了的解决办法

    在页面加载完成时候 '.add_project' 元素是可以触发click时间的,当动态添加 '.add_project' 时候,新添加的元素却触发不了click事件,类似下面的写法: $(" ...

  6. dubbo源码解析之负载均衡

    在分布式系统中,负载均衡是必不可少的一个模块,dubbo 中提供了五种负载均衡的实现,在阅读这块源码之前,建议先学习负载均衡的基础知识.把看源码当做一个印证自己心中所想的过程,这样会得到事半功倍的效果 ...

  7. Linux hostname主机名配置文件/etc/hosts详解

    这篇文章为大家介绍linux hostname主机名配置文件/etc/hosts,包括主机名的用途.配置文件的操作方法等,有需要的朋友,可以参考下 1.什么是Linux主机名 无论在局域网还是INTE ...

  8. 《UNIX环境高级编程》(APUE) 笔记第四章 - 文件和目录

    4 - 文件和目录 1. 函数 stat.fstat.fstatat 和 lstat #inlcude <sys/stat.h> int stat(const char *restrict ...

  9. Python之浅谈多态和封装

    目录 组合 什么是组合 为什么使用组合 多态和多态性 多态 什么是多态? 多态性 好处 多态性 什么是多态性 封装 封装是什么意思? 隐藏 如何用代码实现隐藏 python 实际上是可以访问隐藏属性的 ...

  10. 题解 P1144 【最短路计数】

    这道题用一次SPFA就可以过了.在求最短路的同时,对答案进行统计即可. 实现: \(dis_i\)表示从1到\(i\)的最短路(实在还是不懂的话看程序吧). 当\(dis_i>dis_j+1\) ...