1. 程式人生 > 實用技巧 >mybatis動態查詢得相關點

mybatis動態查詢得相關點

1、

<resultMap id="BaseResultMap" type="com.ccssoft.entity.physical.Metype">
        <id column="ID" jdbcType="BIGINT" property="id" />
        <result column="VERSION" jdbcType="INTEGER" property="version" />
        <result column="NAME" jdbcType="VARCHAR" property="name" />
        <result column="
MODEL" jdbcType="VARCHAR" property="model" /> <result column="CATEGORY" jdbcType="BIGINT" property="category" /> </resultMap> <sql id="Base_Column_List"> ME.ID, ME.VERSION, ME.NAME, ME.MODEL, ME.CATEGORY </sql> <select id="pageFindAllMetypeSelective
" resultMap="BaseResultMap" > SELECT DISTINCT <include refid="Base_Column_List"/> FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID=MDL.METYPEID WHERE 1=1 <if test="name!=null and name!=''"> -- AND ME.NAME LIKE concat'%'||#{name}||'
%' AND ME.NAME LIKE CONCAT('%',CONCAT(#{name},'%')) </if> <if test="ip!=null and ip!=''"> AND MDL.IPADDRESS LIKE CONCAT('%',CONCAT(#{ip},'%')) </if> <if test="emsId!=null and emsId.size()>0"> AND MDL.EMSID IN <foreach collection="emsId" item="item" open="(" close=")" separator=","> #{item} </foreach> </if> <if test="deviceType!=null and deviceType.size()>0"> AND MDL.DEVICETYPE IN <foreach collection="deviceType" item="devicetp" separator="," close=")" open="("> #{devicetp,jdbcType=BIGINT} </foreach> </if> ORDER BY ME.ID DESC </select>

這是一個寫動態mybatis得一個例子,就這個例子我做一下總結:

  1. resultMap中是一個類所有的屬性,只是因為返回得是集合型別,所以這樣更方便一點,也可以將資料庫中得欄位和實體類中得屬性對應起來,手動結合。

  resultMap比較強大,這裡借鑑別人得(https://www.cnblogs.com/kenhome/p/7764398.html)。resultMap可以將多個表中得資料對映到一個結果集當中。

    這裡又出來一個問題:對映得結果怎麼接:百度和問了別人這裡又倆種方法接:

      1、一種是新建一個物件去接,和返回得屬性一一對應得。

      2、返回list這種得,但是這種得不利於後期得維護,很可能找不到返回得是什麼。不直觀。

    

<!--column不做限制,可以為任意表的欄位,而property須為type 定義的pojo屬性-->
<resultMap id="唯一的標識" type="對映的pojo物件">
  <id column="表的主鍵欄位,或者可以為查詢語句中的別名欄位" jdbcType="欄位型別" property="對映pojo物件的主鍵屬性" />
  <result column="表的一個欄位(可以為任意表的一個欄位)" jdbcType="欄位型別" property="對映到pojo物件的一個屬性(須為type定義的pojo物件中的一個屬性)"/>
  <association property="pojo的一個物件屬性" javaType="pojo關聯的pojo物件">
    <id column="關聯pojo物件對應表的主鍵欄位" jdbcType="欄位型別" property="關聯pojo物件的主席屬性"/>
    <result  column="任意表的欄位" jdbcType="欄位型別" property="關聯pojo物件的屬性"/>
  </association>
  <!-- 集合中的property須為oftype定義的pojo物件的屬性-->
  <collection property="pojo的集合屬性" ofType="集合中的pojo物件">
    <id column="集合中pojo物件對應的表的主鍵欄位" jdbcType="欄位型別" property="集合中pojo物件的主鍵屬性" />
    <result column="可以為任意表的欄位" jdbcType="欄位型別" property="集合中的pojo物件的屬性" />  
  </collection>
</resultMap>

 其中如果:

<resultMap id="BasePlusResultMap" type="com.meikai.shop.entity.TShopSku">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
    <result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
    <collection property="attributes" ofType="com.meikai.shop.entity.TShopAttribute" > 
        <id column="AttributeID" jdbcType="BIGINT" property="id" />
        <result column="attribute_NAME" jdbcType="VARCHAR" property="attributeName" />
    </collection>
</resultMap>
複製程式碼

這裡倆個表的實體類裡面屬性都是id命名的,但是表裡面的不是同一個欄位,如果在表裡是同一個欄位的話會報錯。

這裡的

<association>是所一對一的關係,也就是在這個實體類裡面定義了其一對一的類:private User user;
 <collection>是一對多的關係,也就是這個實體類裡定義返回一個類的集合:private List<User> users;
這個和連線是不一樣的,這個叫關聯對映,那個叫連線。這樣寫可以得到一個全新的對映物件。

如果collection標籤是使用巢狀查詢,格式如下:

 <collection column="傳遞給巢狀查詢語句的欄位引數" property="pojo物件中集合屬性" ofType="集合屬性中的pojo物件" select="巢狀的查詢語句" > 
 </collection>

注意:<collection>標籤中的column:要傳遞給select查詢語句的引數,如果傳遞多個引數,格式為column= ” {引數名1=表字段1,引數名2=表字段2} ;

  1. 當有外部表連線時
      SELECT DISTINCT
            <include refid="Base_Column_List"/>
            FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID=MDL.METYPEID

    可以指定表,給表一個別名。並且要把倆個表通過什麼連線要寫。

  2. java中的long對應資料庫中的bigint,但是要大寫,這裡如果是在<resultMap>標籤裡的話jdbcType=“BIGINT”,但是如果不在標籤裡可以這樣寫
    #{devicetp,jdbcType=BIGINT}  //這裡不用寫雙引號,

    因為在這裡是倆張表查,在前面只指定了前一張表的jdbc型別,沒有指定另外一張的,所以要指定,否則會報錯。

  3. <sql>裡面的程式碼時共用的程式碼。
  4. 如果這裡寫動態的資料庫程式碼就是會生成日誌的時候寫出一個
     SELECT count(0) FROM (SELECT DISTINCT ME.ID, ME.VERSION, ME.NAME, ME.MODEL, ME.CATEGORY FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID = MDL.METYPEID WHERE 1 = 1 AND ME.NAME LIKE CONCAT('%', CONCAT(?, '%')) AND MDL.DEVICETYPE IN (?, ?, ?, ?, ?, ?, ?, ?)) table_count 

    這裡的前面的東西是自動的。

  5.  <if test="ip!=null and ip!=''">
                AND MDL.IPADDRESS LIKE CONCAT('%',CONCAT(#{ip},'%'))
            </if>

    這裡的ip是傳過來的值,然而如果我們查的是另外一個表的東西的話,可以寫上

    MDL.IPADDRESS    這樣的東西,只要和傳過來的東西比較就行。這裡要判斷不為null也不為沒有資料
  6. 動態查詢連線的話用這樣寫
    CONCAT('%',CONCAT(#{ip},'%'))  

  7. <if test="emsId!=null and emsId.size()>0">
                AND MDL.EMSID IN
                <foreach collection="emsId" item="item" open="(" close=")" separator=",">
                #{item}
                </foreach>
            </if>

    這裡要先判斷是不是null再判斷size(),否則可能裡賣弄都是幾個空,也有大小,但是已經滿足了條件,就進去了。
    collection屬性是寫傳過來的List集合的物件名 item可以自己取名。

  8. where 1=1在動態資料庫查詢中的作用?(https://blog.csdn.net/u012195214/article/details/73522489
    參考了別人的。可以預防動態後面都不成立的時候sql語句不對,一般裡面有and,動態的不成立還行,成立的話and會拼接。
    這裡可以消除and就是用<WHERE>標籤,這下我也懂了where和其標籤的不同之處了