zoukankan      html  css  js  c++  java
  • 《你还在写sql语句吗?》人生苦短,进入MybatisPlus的丝滑体验

    一、发展历程

      依稀记得大学期间,类中写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); }

      
      @Override
      public SResponseBean queryProjectNameList(SRequestBean<SiteProjectNameListQueryReq> queryReq) throws BaseBusinessException {
      /*官方不推荐这种写法,入侵性高,需要写死字段列名
      我们采用直接查询所有,然后通过lambda进行去重
      QueryWrapper<SiteProject> queryWrapper = new QueryWrapper<>();
      queryWrapper.select("DISTINCT name").eq("source", queryReq.getBody().getSource());*/
      //构建查询条件
      LambdaQueryWrapper<SiteProject> queryWrapper = Wrappers.<SiteProject>lambdaQuery()
    .eq(SiteProject::getSource, queryReq.getBody().getSource());
      List<SiteProject> siteProjectList= siteProjectMapper.selectList(queryWrapper);
      //针对结果进行去重
      List<SiteProject> distinctList = siteProjectList.stream().collect(
    Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getName()))),
    ArrayList::new));
      //转换成返回的dto
      List<SiteProjectNameListRes> siteProjectNameListResList = SBeanUtils.convertToResponse(SiteProjectNameListRes.class, distinctList);
      return SResponseUtil.output(siteProjectNameListResList);
      }
    }

    2.9、总结

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

    日常的操作,我们不用关注sql是如何拼接的,如何运行的,将时间用于处理业务逻辑上。并且在当下流行的思想下,我们提倡最大

    可能的解耦,数据层我们最好单表操作,利用service层继续处理,得利于lambda表达式的诞生,集合的处理变得更加丝滑,效率大

    大提升。我们需要不断思考,不断学习,避免重复造轮子,人生苦短,我更喜欢开箱即用。但使用过后,我更建议大家撸撸源码,

    了解底层的实现。这样路才能走得远且扎实。

    三、娱乐时光

    3.1、新鲜事 

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

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

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

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

    3.2、歌曲推荐

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

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

    3.3、影视推荐

      源代码 Source Code (2011),如果你也对平行世界有兴趣,不然看看这部影片。

     3.4、养眼壁纸

  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/weipt0106/p/13296600.html
Copyright © 2011-2022 走看看