《你還在寫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" "//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、養眼壁紙