1. 程式人生 > >【程式設計踩坑】--mybatis篇

【程式設計踩坑】--mybatis篇

updateByPrimaryKeySelective

updateByPrimaryKey

前者只是更新新的model中不為空的欄位。

後者則會將為空的欄位在資料庫中置為NULL。
updateByPrimaryKeySelective會對欄位進行判斷再更新(如果為Null就忽略更新),如果你只想更新某一欄位,可以用這個方法。

updateByPrimaryKey對你注入的欄位全部更新

以上是從別處拷貝過來的,不問出處,純屬當做例項

兩段解釋的是同一個問題:updateByPrimaryKey與updateByPrimaryKeySelective函式,且都有提到為空。

不過有種人雲亦云之感,要探究本質還需檢視本源(原始碼)

那麼為空是什麼?

    為null

   為空字串

  為null和為空字串(胡扯,不可能)

  為null或空字串

貼上原始碼

BaseUpdateProvider.java
    /**
     * 通過主鍵更新不為null的欄位
     *
     * @param ms
     * @return
     */
    public String updateByPrimaryKeySelective(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
        sql.append(SqlHelper.updateSetColumns(entityClass, null, true, isNotEmpty()));
        sql.append(SqlHelper.wherePKColumns(entityClass));
        return sql.toString();
    }
---------------------------------------------------------------------------
    public boolean isNotEmpty() {
        return mapperHelper.getConfig().isNotEmpty();
    }

    /**
     * 對於一般的getAllIfColumnNode,是否判斷!='',預設不判斷
     */
    private boolean notEmpty = false;

    public boolean isNotEmpty() {
        return notEmpty;
    }
------------------------------------------------------------------------------
 <!--&lt;!&ndash; spring與mybatis整合配置,掃描所有dao &ndash;&gt;-->
    <!--<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"-->
    <!--p:basePackage="com.landi.dao"-->
    <!--p:sqlSessionFactoryBeanName="sqlSessionFactory"/>-->
    <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.landi.dao"/>
        <property name="properties">
            <value>
                mappers=com.landi.common.MyMapper
                notEmpty=true
                style=normal
            </value>
        </property>

// 配置屬性可以改變notEmpty的值
    String notEmpty = properties.getProperty("notEmpty");
    if (StringUtil.isNotEmpty(notEmpty)) {
        this.notEmpty = notEmpty.equalsIgnoreCase("TRUE");
    }
   /**
     * update set列
     *
     * @param entityClass
     * @param entityName  實體對映名
     * @param notNull     是否判斷!=null
     * @param notEmpty    是否判斷String型別!=''
     * @return
     */
    public static String updateSetColumns(Class<?> entityClass, String entityName, boolean notNull, boolean notEmpty) {
        StringBuilder sql = new StringBuilder();
        sql.append("<set>");
        //獲取全部列
        Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
        //當某個列有主鍵策略時,不需要考慮他的屬性是否為空,因為如果為空,一定會根據主鍵策略給他生成一個值
        for (EntityColumn column : columnList) {
            if (!column.isId() && column.isUpdatable()) {
                if (notNull) {
                    sql.append(SqlHelper.getIfNotNull(entityName, column, column.getColumnEqualsHolder(entityName) + ",", notEmpty));
                } else {
                    sql.append(column.getColumnEqualsHolder(entityName) + ",");
                }
            }
        }
        sql.append("</set>");
        return sql.toString();
    }
 /**
     * 判斷自動!=null的條件結構
     *
     * @param entityName
     * @param column
     * @param contents
     * @param empty
     * @return
     */
    public static String getIfNotNull(String entityName, EntityColumn column, String contents, boolean empty) {
        StringBuilder sql = new StringBuilder();
        sql.append("<if test=\"");
        if (StringUtil.isNotEmpty(entityName)) {
            sql.append(entityName).append(".");
        }
        sql.append(column.getProperty()).append(" != null");
        if (empty && column.getJavaType().equals(String.class)) {
            sql.append(" and ");
            if (StringUtil.isNotEmpty(entityName)) {
                sql.append(entityName).append(".");
            }
            sql.append(column.getProperty()).append(" != '' ");
        }
        sql.append("\">");
        sql.append(contents);
        sql.append("</if>");
        return sql.toString();
    }

mybatis 中isNull, isNotNull與isEmpty, isNotEmpty標籤用於動態sql的判斷

在mybatis中isNull用於判斷引數是否為Null,isNotNull相反

isEmpty判斷引數是否為Null或者空,滿足其中一個條件則其true
isNotEmpty相反,當引數既不為Null也不為空時其為true

 判斷之後做相對應的表示式操作

通過下面的程式碼可以看到假如用isNotEmpty的時候頁面假如有值,現在改成空的字串資料庫是不會有效果的,因為isNotEmpty判斷的是null和“”這兩個屬性,所以就不會進這個方法。

  <select id="countAgencyName" resultType="java.lang.Integer" parameterType="map">
    update agency a
    <set>
        <if test="map.ageName!= null and map.ageName!=''">
          a.ageName = #{map.ageName},
        </if>   
    </set>

    <where>
        <if test="map.ageId != null and map.ageId !=''">
          AND a.ageId = #{map.ageId}
        </if>
    </where>
  </select>

假如要用的話必須用isNotnull這個值判斷null,而不判斷“”,所以最後會把有值的改成空的字串的。

  <select id="countAgencyName" resultType="java.lang.Integer" parameterType="map">
    update agency a
    <set>
        <if test="map.ageName!= null">
          a.ageName = #{map.ageName},
        </if>   
    </set>
  </select>

注意:更新多個欄位,set語句之後一定別忘記加逗號。set標記已經自動把最後一個逗號給去掉了

public String updateByPrimaryKey(MappedStatement ms) {
    Class<?> entityClass = getEntityClass(ms);
    StringBuilder sql = new StringBuilder();
    sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
    sql.append(SqlHelper.updateSetColumns(entityClass, null, false, false));
    sql.append(SqlHelper.wherePKColumns(entityClass));
    return sql.toString();
}

相關推薦

程式設計--mybatis

updateByPrimaryKeySelective updateByPrimaryKey 前者只是更新新的model中不為空的欄位。 後者則會將為空的欄位在資料庫中置為NULL。 updateByPrimaryKeySelective會對欄位進行判斷再更新(如果為

常見USB調試安裝失敗(Installation failed with message INSTALL_CANCELED_BY_USER)

mes 需要 現在 com 錯誤 .cn www all 問題: 【參考】http://www.cnblogs.com/liushilin/p/6553918.html 問題:在USB安裝調試(小米手機),出現如下錯誤 解決:1.小米手機解決辦法見參考。登錄小米賬號

日常ButterKnife:Attribute value must be constant

Attribute value must be constant 在搜尋Attribute value must be constant後得到這樣的說明: Injection does not work in library projects 意為

RNReact-native 0.45版本以上出現 boost_1_63_0.tar.gz等錯誤

請先下載第三方依賴檔案 下下來後請放置到 ~/.rncache 目錄 比如你可以開啟終端,輸入 # 井號表示註釋,不要複製井號開頭的句子 # 進入~目錄,即使用者目錄 cd ~

360安全瀏覽器“極速模式”和“兼容模式”,套路還是bug?

html 一個 另一個 地址 不生效 bug rom 論壇 val 分享踩坑點: 項目中需要兼容360安全瀏覽器,大家當然都希望用極速模式打開網站,但是發現總是被兼容模式打開 網址類似 aa.xx.dd.com 網上找了很多地方,有以下兩種方法 1.<m

angularJS 1.X版本中 ng-bind 指令多空格展示

ext 數據庫查詢 sci 接收 可能 color 最終 數據 目的 做項目的時候遇到的問題 1、問題描述   用戶在表單某個值輸入多個空格,例如:A B,保存至服務器   在列表查詢頁面中使用bg-bind的指令單向綁定,結果展示位A B,連續的空格被替換

Kafka系列之一消費者拉不出數據

dex -c 通知 還得 gin div 消費 發現 拉取 一、Bug背景 因業務需要,我們部署了兩個Kafka集群。Kafka集群A的版本號為:0.11.0.1,Kafka集群B的版本號為0.9.0.1。 因兩個Kafka集群的版本號不一致,嘗試了

ELK6.0已取消filebeat配置document_type

document_type elk logstash filebeat 一、起因 ?在使用ELK5.5的時候,如果遇到需要在同一臺機器上收集不同類型的日誌,比如:同時收集一臺機器上的java log和nginx log!而又需要分別存儲到不同索引的時候,我們會在filebeat的prospec

echarts記錄2.複選框+動態隱藏、顯示資料

第一節的例子裡我將ajax請求返回的所有資料都載入成了餅狀圖,但是實際應用中我們可能並不需要全部顯示,可能需要做一個多選框選擇需要的name再傳給後臺……然而我也不想修改sql。 於是就考慮在前端控制啦,後端只需要無腦一次查出全部的資料,讓前端折騰吧~使用者點哪裡我就顯示哪

程式設計之美初賽2015 待填

初賽第一場 題目1 : 彩色的樹 時間限制:2000ms 單點時限:1000ms 記憶體限制:256MB 描述 給定一棵n個節點的樹,節點編號為1, 2, …, n。樹中有n - 1條邊,任意兩個節點間恰好有一條路徑。這是一棵彩色的樹,每個節點恰好可以染一

阿里雲ECS清除隱藏的挖礦程式

問題描述: 一臺阿里雲伺服器,收到連續告警CPU使用量已經大於95%。但這臺機器上面使用中的業務只有一個不常使用的MySQL,其他就沒有了,正常情況下CPU是不可能達到這麼高的。檢視告警資訊,發現有被植入挖礦程式,可疑程式檔案路徑為 /usr/lib/libiacpkmn.so.3 排查過程

為base64編碼的圖片生成截圖不顯示

問題 在effevo中設定個人頭像時,會有無法顯示的情況,還不穩定重現,終於抓到問題原因,下面分享下解決方法 解決方法 先看下原始寫法 var imgBase64='data:image/png;base64,iVBORw0KGgoAAAANSU

SpingMVC靜態資源無法訪問問題解決

看了網上很多解決方案都沒有成功 最後按自己的方案解決了 之前用 <mvc:default-servlet-handler/> 之前用這個配置不成功 改用resouces配置 在sping-web.xml 檔案下配置如下屬性  <mvc:res

MySQL時間索引失效

專案中查時間資料段資料時,發現查詢時間很長,RDS查了一下執行計劃: 各列解析說明: id:表示執行的順序,id的值相同時,執行順序是從上到下,id的值不同時,id的值越大,優先順序越高,越先執行 select_type: 1、SIMPLE表示不包含子查詢和un

Kylin 之旅kylin sum() avg() 無法返回預期的結果

在使用kylin 的時候遇到了avg()函式無法求出預期值的情況,通過檢查發現sum()函式也無法得出預期值,所以通過查詢多方資料找到了問題所在 sum() 函式與avg() 函式無法返回正確的結果 之前使用select語句求和的時候遇到了

Android 使用 Jenkins 實現自動化打包流程&

引言 每個Android開發應該都有經歷過正在碼程式碼的時候突然被打斷要求打個啥啥環境啥啥配置的安裝包,然後就得暫存程式碼、切換分支、更改配置、等待build、balabala……往大了說就是浪費時間消耗員工價值對公司的不負責(胡扯),往小了說就是這TMD真的

React記三React項目報錯Can't perform a React state update on an unmounted component

-o clas sha ces ESS eventbus event log back 意思為:我們不能在組件銷毀後設置state,防止出現內存泄漏的情況 分析出現問題的原因: 我這裏在組件加載完成的鉤子函數裏調用了一個EventBus的異步方法,如果監聽到異步方法,則

React記一React項目中禁用瀏覽器雙擊選中文字的功能

一個 art 文字 star reac return 禁用 tar htm 常規項目,我們只需要給標簽加一個onselectstart事件,return false就可以 例: <div onselectstart="return false;"

報錯 non-static method xxx() cannot be referenced from a static context

bye not ont ODB 原因 con cannot ood ren 今天測試代碼時遇到 Error:(6, 55) java: non-static method sayGoodbye() cannot be referenced from a static

聯合主鍵情況下,JPA非主鍵設定自動增長無效

開發十年,就只剩下這套架構體系了! >>>