mybatis設計大介面的坑以及做法

夜-NULL(zmc)發表於2020-10-30

先說一些注意事項:

1.注:mybatis一個mapper.java檔案只能對應一個mapper.xml檔案,所以不能一個mapper.java對應兩個xml(一個預設的,一個自己擴充的)

2.注:如果表中有欄位是text,selectByExample是不能返回該欄位的,最終結果該欄位為null;如需返回,則使用selectByExampleWithBLOBs方法

3.注:updateByExampleWithBLOBs使用的時候需要注意,需要傳入全部的欄位進行替換,否則會覆蓋成null

4.注:自定義的mapper方法,如果引數一個可以不寫 @Param,如果多個引數,則引數名前必須寫上,如果是example也需要寫上@Param

 

一個大查詢介面的設計:

1.一個查詢介面要能夠支援所有的表

傳入的引數定義:

//指定表
  @JsonProperty("table")
  private String table;

//指定查詢條件
  @JsonProperty("query")
  private JSONObject query;

//指定返回屬性
  @JsonProperty("fields_return")
  private List<String> fieldsReturn;

  @JsonProperty("limit")
  private Integer limit;

  @JsonProperty("start")
  private Integer start;

  @JsonProperty("order")
  private String order;

注:更新與查詢設計類似,不再贅述

設計介面如下:所有impl實現該介面(類似於責任鏈)

public interface DbService<TRes> {
    /**
     * 獲取表中資料
     * @param req
     * @return
     */
    List<TRes> get(DbQueryReq req);

    /**
     * 更新表中資料
     * @param req
     * @return
     */
    void update(DbUpdateReq req);

    /**
     * 新增表中資料
     * @param req
     * @return
     */
    void add(DbAddReq req);

    /**
     * 刪除後表中資料
     * @param req
     * @return
     */
    void delete(DbDeleteReq req);
}

 

2.傳入/返回 的json為下劃線,接收的物件為駝峰

接收和返回的類欄位全部加上註解:

@JsonProperty("id")
private String id;

 

3.返回值必須設計成Object,返回的時候fastjson會將值為null的key直接遮蔽,不返回,需要做到支援返回null

/**
     * 該配置將駝峰轉化為下劃線
     *
     * SerializerFeature.WriteMapNullValue 將NULL值返回
     */
    static SerializeConfig serializeConfig = new SerializeConfig();
    static {
        serializeConfig.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
    }


返回的時候使用以上兩個配置:

jsons = NotNull.getList(Res).stream().map(r -> JSONObject.parseObject(JSON.toJSONString(r, serializeConfig, SerializerFeature.WriteMapNullValue))).collect(Collectors.toList());

4.更新的時候只傳入要更新的欄位可以使用updateByExampleSelective,如果需要set 屬性 為null,則無法支援了,該如何支援?

xml:

<update id="updateColumnByExampleSelective" parameterType="map">
    update paas_host
    <set>
      <foreach collection="map.entrySet()"  item="item" index="key" separator=",">
        ${key} =  #{item}
      </foreach>
    </set>
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>


Java:

/**
     * 自定義update方法
     * 實現更新欄位可選
     * 可set列為null
     * update的查詢條件為所有欄位且可為null
     * @param map
     * @param example
     * @return
     */
    void updateColumnByExampleSelective(@Param("map") Map<String, Object> map, @Param("example") DbExample example);

 

5.查詢的時候需要查詢某列為null,需要如何支援?

// get\update\delete的查詢複用以下方法:


    private boolean setSearchExample(JSONObject query, DbExample.Criteria criteria) {

        boolean hasValidQuery = false;
        if(query != null){
            if(query.containsKey("ids")){
                hasValidQuery = true;
                if(query.getJSONArray("ids") != null){
                    List<Integer> ids = JSONObject.parseArray(query.getJSONArray("ids").toJSONString(), Integer.class);
                    criteria.andIdIn(ids);
                } else {
                    criteria.andIdIsNull();
                }
            }
            if(query.containsKey("id")){
                hasValidQuery = true;
                if(query.getInteger("id") != null){
                    criteria.andIdEqualTo(query.getInteger("id"));
                } else {
                    criteria.andIdIsNull();
                }
            }          

        }
        return hasValidQuery;
    }

6.如何設計支援大介面的指定返回值?-----暫未找到好的方案

 

 

 

相關文章