1. 程式人生 > 實用技巧 >《你還在寫sql語句嗎?》人生苦短,進入MybatisPlus的絲滑體驗

《你還在寫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);
} }

2.9、總結

  沒有一條sql,不用做事務控制,不用寫for迴圈取插入等等,這一切都全賴MP的功勞,對於大部分場景,MP已經可以滿足我們日常的操作,

我們不用關注sql是如何拼接的,如何執行的,將時間用於處理業務邏輯上。並且在當下流行的思想下,我們提倡最大可能的解耦,資料層我們

最好單表操作,利用service層繼續處理,得利於lambda表示式的誕生,集合的處理變得更加絲滑,效率大大提升。我們需要不斷思考,不斷

學習,避免重複造輪子,人生苦短,我更喜歡開箱即用。但使用過後,我更建議大家擼擼原始碼,瞭解底層的實現。這樣路才能走得遠且紮實。

三、娛樂時光

3.1、新鮮事 

  貴州公交車司機結果公佈,蓄意報復社會。

  每一條人名,背後都是一個家庭,將自己對社會的不公,發洩在20多條人命上,不管怎麼說,都是無法被原諒。

但願逝者安息,生者引以為戒,心理健康是當下最應被重視起來,希望大家平日少於人發生衝突,因為你永遠不知道,

對方是否可能做出極端的行為。

3.2、歌曲推薦

  愛的故事(上),每一名男孩子都有過青春期的懵懂,都有過暗戀的經歷,聽苦情歌,不過“全為愛上了你偏偏你不知”,

祝願全天下程式設計師都有歸宿,名花有主的,可不要貪杯哦。

3.3、影視推薦

  原始碼 Source Code(2011),我最喜歡影片中關於平行世界的暗示。

3.4、養眼桌布