基於Mustache實現sql拼接

  • 2019 年 11 月 5 日
  • 筆記

一、前言

Mustache語法是一種模板語法,它可以幫我們拼接我們想要的東西。入職新公司,而項目里的sql語句就是用Mustache語法來拼接的,網上關於這個的教程、資料比較少,所以自己也記錄一下筆記,本篇筆記的內容主要是講Mustache語法在web開發中的持久層用來拼接sql的應用,若想學習更多關於Mustache相關只是請參考:Mustache的GitHub地址

二、Mustache語法

Mustache 的模板語法很簡單,就那麼幾個:

  • {{keyName}}
  • {{#keyName}} {{/keyName}}
  • {{^keyName}} {{/keyName}}
  • {{.}}
  • {{<partials}}
  • {{{keyName}}}
  • {{!comments}}

此處具體使用可以參考部落格:Mustache 入門教程

三、Mustache拼接sql

持久層框架使用的是JPA,類申明如下,後文介面均在此類中:

/**   * 模組定義操作持久層   *   * @author csh   * @date 2019/10/9   */  public interface ModuleRepository extends PagodaJpaRepository<Module, Long>, JpaSpecificationExecutor<Module> {}

3.1 單個參數拼接

    /**       * 根據項目主鍵查詢模組詳細資訊       *       * @param itemId 項目主鍵       * @return 模組詳細資訊       */      @SqlTemplate(              name = "queryDetailById",              sql = "SELECT id,item_id,module_code,module_name,path,remark,creator_name,creator_code,created_at,modifier_name,modifier_code,last_modified_at " +                      " FROM module WHERE item_id = :itemId AND del = 0"      )      List<Module> queryDetailById(@Param("itemId") Long itemId);

這裡使用「:」是為了防止sql注入


3.2 多個參數拼接

多個參數封裝的實體類:

/**   * 模組資訊查詢入參   *   * @author csh   * @date 2019/10/12   */  @Data  public class QueryModuleInput implements Serializable {      /**       * 項目中文名稱       */      @NotNull      private Long itemId;        /**       * 模組名稱       */      @NotNull      @NotBlank      private String moduleName;  }

接受查詢參數的介面:

    /**       * 根據項目名、模組名進行複雜查詢       *       * @param moduleInput 項目名、模組名入參       * @return 返回查詢出來的列表       */      @SqlTemplate(              name = "complexQuery",              sql = "SELECT id,item_id,module_code,module_name,path,remark,creator_name,creator_code,created_at,modifier_name,modifier_code,last_modified_at " +                      "FROM module WHERE del = 0 {{#itemId}} AND item_id = :itemId {{/itemId}} {{#moduleName}} AND module_name = :moduleName {{/moduleName}}"      )      List<Module> listByNames(QueryModuleInput moduleInput);

注意:如果{{#keyName}} {{/keyName}}中的 keyName 值為 null, undefined, false;則不渲染輸出任何內容。


3.3 IN語法的拼接

    /**       * 根據模組查詢介面       *       * @param moduleIdList       * @return       */      @SqlTemplate(              name = "findInterfaceByModuleId",              sql = "select * from interface where 1=1" +                      "{{#moduleIdList_exists}} and module_id in ({{#moduleIdList}}{{^-first}}, {{/-first}}{{this}}{{/moduleIdList}}){{/moduleIdList_exists}}"      )      List<InterfaceInfoDTO> findInterfaceByModuleId(@Param("moduleIdList") List<Long> moduleIdList);

注意:其中{{^-first}}, {{/-first}}是用來拼接「,」的;‘{{this}}’中的斜杠視情況而加,如果list中是字元串就加,如果是整形則不必加斜杠。