1. 程式人生 > 實用技巧 >mybatis複習筆記----關於標籤

mybatis複習筆記----關於標籤

關於sql操作

一 、定義SQL語句

  • 【select】
    屬性介紹:
     id :唯一的識別符號.
     parameterType:傳給此語句的引數的全路徑名或別名 例:com.test.poso.User或user
     resultType :語句返回值型別或別名。注意,如果是集合,那麼這裡填寫的
     是集合的泛型,而不是集合本身(resultType 與resultMap 不能並用)
   例子:
     sql:
      <select id="userList" parameterType="user" resultType="User">
        select * from user where name =#{name}
      </select>
  • 【insert】
    屬性介紹:
      id :唯一的識別符號
      parameterType:傳給此語句的引數的全路徑名或別名 例:com.test.poso.User
  • 【delete】
    例子:
    <delete id="deleteUser" parameterType="int"> 
      delete from user 
      where id = #{id} 
    </delete>
  • 【update】
      類似於insert

二、配置物件屬性與查詢結果集

  • 【resultMap】
    • 建立SQL查詢結果欄位與實體屬性的對映關係資訊
    • 查詢的結果集轉換為java物件,方便進一步操作
    • 將結果集中的列與java物件中的屬性對應起來並將值填充進去
    • 注意:與java物件對應的列不是資料庫中表的列名,而是查詢後結果集的列名
例:
<resultMap id="getStudentRM" type="EStudnet">
    <id property="id" column="ID"/>
    <result property="studentName" column="Name"/>
    <result property="studentAge" column="Age"/>
</resultMap>
<select id="getStudent" resultMap="getStudentRM">
    SELECT ID, Name, Age
    FROM TStudent
</select>

resultMap標籤屬性:
    id:該resultMap的標誌
    type:返回值的類名,此例中返回EStudnet類
resultMap標籤下的子標籤:
    id:用於設定主鍵欄位與領域模型屬性的對映關係,此處主鍵為ID,對應id。
    result:用於設定普通欄位與領域模型屬性的對映關係

【association】 一對一
【collection】 一對多
上面兩個標籤在resultmap中使用,可以通過巢狀結果集(即在標籤裡再通過result標籤來對應屬性),也可以通過另一介面方法查詢後獲得結果集。

resultMap標籤自定義結果集

聯合查詢以及association通過巢狀結果集的使用

collection通過呼叫其他介面方法使用
相關屬性:

select:表示呼叫另一個介面的查詢方法
column:將哪一列的值傳遞過去作為另一介面方法的引數 , 可以傳遞一個map型別的引數,例如:column="key1=column1, key2=column2}"
property:查詢結果返回後封裝到當前pojo哪一個屬性。
fetchType: 設定延遲載入 ="lzay"

【discriminator】
鑑別器:mybatis可以使用discriminator判斷某列的值,然後根據某列的值改變封裝行為封裝Employee:
如果查出的是女生:就把部門資訊查詢出來,否則不查詢;如果是男生,把last_name這一列的值賦值給email;

例如:
<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpDis">
    <id column="id" property="id" / >
    <result column="last_name " property= "LastName"/>
    <result column="email" property="email"/ >
    <result column="gender" property="gender"/ >
    <discriminator javaType="string" column="gender">
        <!--女生resultType :指定封裝的結果型別﹔不能缺少。resultMap-->
        <case value="0" resultType= "com.atguigu.mybatis.bean. Emp
            <association property="dept" select="com.atguigu.mybatis.dao.DepartmentMapper" column="d_id"></association>
        </case>
        <!--男生;如果是男生,把last_name這一列的值賦值給email; -->
        <case value="1" resultType="com.atguigu.mybatis.bean.Em . Empl
             <id column="id" property="id"/>
             <result column="Last_name" property="LastName" />
             <result column= "last_name" pPoperty="emaiL" />
             <result column= "gender" property="gender" />
        </case>
    </discriminator>
</resultMap>

三、動態拼接SQL標籤

  • 【if】
    通常用於WHERE語句中,通過判斷引數值來決定是否使用某個查詢條件, 他也經常用於UPDATE語句中判斷是否更新某一個欄位,還可以在INSERT語句中用來判斷是否插入某個欄位的值
例:
<select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST       
    WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</select> 

但是此時如果studentName是null或空字串,此語句很可能報錯或查詢結果為空。此時我們使用if動態sql語句先進行判斷,如果值為null或等於空字串,我們就不進行此條件的判斷。

修改為:
<select id=" getStudentListLikeName " parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
    <if test="studentName!=null and studentName!='' ">     
        WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
    </if>     
</select>    
  • 【foreach】
    主要用於構建in條件,他可以在sql中對集合進行迭代。如下:
  <delete id="deleteBatch"> 
    delete from user where id in
    <foreach collection="array" item="id" index="index" open="(" close=")" separator=",">
      #{id}
    </foreach>
  </delete>
   假如說引數為----int[] ids = {1,2,3,4,5}----那麼列印之後的SQL如下:
  delete form user where id in (1,2,3,4,5)
  foreach屬性釋義:
   collection :collection屬性值有三個(分別是list、array、map),分別對應的引數型別為(List、陣列、map集合);上面傳的引數為陣列,所以值為array,但是如果介面在傳遞引數時使用了@Param註解,則可以使用自己定義的名稱
   item : 表示在迭代過程中每一個元素的別名
   index :表示在迭代過程中每次迭代到的位置(下標)
   open :字首
   close :字尾
   separator :分隔符,表示迭代時每個元素之間以什麼分隔
   我們通常可以將之用到批量刪除、新增等操作中。
  • 【choose】
    從多個選項中選擇一個。MyBatis提供了choose 元素,按順序判斷when中的條件出否成立,如果有一個成立,則choose結束。
    當choose中所有when的條件都不滿則時,則執行 otherwise中的sql。
    類似於Java 的switch 語句,choose為switch,when為case,otherwise則為default。if是與(and)的關係,而choose是或(or)的關係。
例:
<select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBLST      
    <where>     
        <choose>     
            <when test="studentName!=null and studentName!='' ">     
                    ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
            </when>     
            <when test="studentSex!= null and studentSex!= '' ">     
                    ST.STUDENT_SEX = #{studentSex}      
            </when>     
            <when test="studentBirthday!=null">     
                   ST.STUDENT_BIRTHDAY = #{studentBirthday}      
            </when>     
            <when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">     
                   ST.CLASS_ID = #{classEntity.classID}      
            </when>     
            <otherwise>     
                   1=1 
            </otherwise>     
        </choose>     
    </where>     
</select>     

四、格式化輸出

  • 【where】
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
        WHERE 
        <if test="studentName!=null and studentName!='' ">     
            AND ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
        </if>     
        <if test="studentSex!= null and studentSex!= '' ">     
            AND ST.STUDENT_SEX = #{studentSex}      
        </if>     
</select>     

如果上面例子,引數studentName為null或’’,則或導致此sql組合成“WHERE AND”之類的關鍵字多餘的錯誤SQL。
這時我們可以使用where動態語句來解決。這個“where”標籤會知道如果它包含的標籤中有返回值的話,它就插入一個‘where’。此外,如果標籤返回的內容是以AND 或OR 開頭的,則它會剔除掉。
上面例子修改為:

<!-- 查詢學生list,like姓名,=性別 -->     
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
    <where>     
        <if test="studentName!=null and studentName!='' ">     
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
        </if>     
        <if test="studentSex!= null and studentSex!= '' ">     
            AND ST.STUDENT_SEX = #{studentSex}      
        </if>     
    </where>     
</select>     
  • 【set】
    當在update語句中使用if標籤時,如果前面的if沒有執行,則或導致逗號多餘錯誤。
    使用set標籤可以將動態的配置SET 關鍵字,和剔除追加到條件末尾的任何不相關的逗號。
    沒有使用if標籤時,如果有一個引數為null,都會導致錯誤,如下示例:
<!-- 更新學生資訊 -->     
<update id="updateStudent" parameterType="StudentEntity">     
    UPDATE STUDENT_TBL      
       SET STUDENT_TBL.STUDENT_NAME = #{studentName},      
           STUDENT_TBL.STUDENT_SEX = #{studentSex},      
           STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
           STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
     WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
</update>     

使用set+if標籤修改後,如果某項為null則不進行更新,而是保持資料庫原值。如下示例:

<!-- 更新學生資訊 -->     
<update id="updateStudent" parameterType="StudentEntity">     
    UPDATE STUDENT_TBL      
    <set>     
        <if test="studentName!=null and studentName!='' ">     
            STUDENT_TBL.STUDENT_NAME = #{studentName},      
        </if>     
        <if test="studentSex!=null and studentSex!='' ">     
            STUDENT_TBL.STUDENT_SEX = #{studentSex},      
        </if>     
        <if test="studentBirthday!=null ">     
            STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
        </if>     
        <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">     
            STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
        </if>     
    </set>     
    WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
</update>     
  • 【trim】
    trim(拼接字串)是更靈活的去處多餘關鍵字的標籤,他可以實踐where和set的效果。
trim標籤相關屬性說明:
    prefix=""             字首----trim標籤體中是整個字串拼串後的結果。prefix給拼串後的整個字串加一個字首
    prefixOverrides=""    字首覆蓋----去掉整個字串前面多餘的什麼字元
    suffix=""             字尾----suffix給拼串後的整個字串加一個後輟
    suffixOverrides=" "   字尾覆蓋----去掉整個字串後面多餘的什麼字元

where例子的等效trim語句:

<!-- 查詢學生list,like姓名,=性別 -->     
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
    <trim prefix="WHERE" prefixOverrides="AND|OR">     
        <if test="studentName!=null and studentName!='' ">     
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
        </if>     
        <if test="studentSex!= null and studentSex!= '' ">     
            AND ST.STUDENT_SEX = #{studentSex}      
        </if>     
    </trim>     
</select>  

set例子的等效trim語句:

<!-- 更新學生資訊 -->     
<update id="updateStudent" parameterType="StudentEntity">     
    UPDATE STUDENT_TBL      
    <trim prefix="SET" suffixOverrides=",">     
        <if test="studentName!=null and studentName!="">     
            STUDENT_TBL.STUDENT_NAME = #{studentName},
        </if>     
        <if test="studentSex!=null and studentSex!=" ">     
            STUDENT_TBL.STUDENT_SEX = #{studentSex}, 
        </if>     
        <if test="studentBirthday!=null ">     
            STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
        </if>     
        <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">     
            STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
        </if>
    </trim>     
    WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
</update>     

五、配置關聯關係

  • 【association】標籤
    一對一
    association通常用來對映一對一的關係,例如,有個類user,對應的實體類如下:(getter,setter方法省略)
private String id;//主鍵
private String userName;//使用者姓名

有個類Article,對應的實體類如下:

private String id;//主鍵
private String articleTitle;//文章標題
private String articleContent;//文章內容

如果我想查詢一個使用者的時候,也查到他寫的一篇文章,可以怎樣寫呢?在類user加入一個屬性article

   private String id;//主鍵
   private String userName;//使用者姓名
   private Article article;//新增的文章屬性

2、mapper.xml 我在user類的mapper.xml這樣配置


<resultMap id="userResultMap" type="test.mybatis.entity.User">
    <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
    <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
    //這裡把user的id傳過去
    <-- 屬性:
        select:表示呼叫另一個介面的查詢方法
        column:將那一列的值傳遞過去作為另一介面方法的引數
        property:查詢結果返回後封裝到當前pojo哪一個屬性。
      -->
    <association property="article" column="id" select="test.mybatis.dao.articleMapper.selectArticleByUserId"/>//test.mybatis.dao.articleMapper為名稱空間
</resultMap>

同時,我的article對應的xml這樣寫:

<resultMap id="articleResultMap" type="test.mybatis.entity.Article">
    <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
    <result column="articleTitle" property="articleTitle" jdbcType="VARCHAR" javaType="java.lang.String"/>
    <result column="articleContent" property="articleContent" jdbcType="VARCHAR" javaType="java.lang.String"/>
</resultMap>
  (當然,這裡還有查詢user表的語句,省略)

同時,在article對應的xml有這樣的select語句:

<select id="selectArticleByUserId" parameterType="java.lang.String" resultMap="ArticleResultMap">
    select * 
    from tb_article where userId=#{userId} 
</select>
  • 【collection】標籤
    一對多
    實體類增加對應屬性
private String id;//主鍵
private String userName;//使用者姓名
private List<Article> articleList;

userMapper.xml這樣配置

<resultMap id="userResultMap" type="test.mybatis.entity.User">
    <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
    <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
    //這裡把user的id傳過去
    <collection property="articleList" column="id" select="test.mybatis.dao.articleMapper.selectArticleListByUserId" />
</resultMap>
以下省略,類同,Mybatis會把結果封裝成List型別。

如果我還想通過Article表另一張表,比如文章中有個fk_id,也可以像上面這樣重複配置,把fk_id當做與另一張表關聯的引數,那時就可以通過使用者查到文章,查到文章關聯的另一張表了。

六、標籤
【bind】
可以將OGNL表示式的值繫結到一個變數中,方便後來引用這個變數的值

屬性:
name:相當於變數名
value:變數值,可以動態拼接,即可以寫ognl表示式
使用時,直接使用變數即可,

【sql】
更多用於寫sql語句的一部分,就像寫在配置檔案中的sql常量

【include】
用於引用常量,也可以定義屬性property,
sql標籤內部就能使用自定義的屬性
但取值的正確方式是${prop},不能使用#{prop}這種方式

參考:https://blog.csdn.net/weixin_40950778/article/details/78655288

全域性配置檔案中的一些標籤

  • 【properties】標籤
    引入外部properties配置檔案的內容;
屬性:
1---resource:引入類路徑下的資源
2---url:引入網路路徑或者磁碟路徑下的資源
  • 【settings】標籤
    用於設定mybatis的執行時行為
    例如:快取、懶載入、駝峰命名策略等等等。
  • 【typeAliases】標籤
    對javabean進行重新命名,重新命名後在介面對應配置檔案.xml中返回型別填寫時可以不用填寫全限定類名,不過推薦填寫全限定類名
    注意:如果用package 進行重新命名,若指定包下的子包包含和父包一樣類名的類,會報錯。
    1----對單個進行重新命名
例如:
<typeAliases>
    <typeAlias alias="Author" type="domain.blog.Author" />
    <typeAlias alias="Blog" type="domain.blog.Blog" />
    <typeAlias alias="Comment" type="domain.blog.Comment"/>
    <typeAlias alias="Post" type="domain.blog.Post" />
    <typeAlias alias="Section" type="domain.blog.section"/>
    <typeAlias alias="Tag" type="domain.blog . Tag" />
</typeAliases>

2----對多個進行重新命名
多個重新命名就是指定包名,預設命名為類名小寫

例如:
<typeAliases>
    <package name="domain.blog" />
</typeAliases>

3----也可以在實體類上通過註解@alias實現類重新命名

  • 【databaseIdProvider】標籤
    mybatis根據不同的資料庫廠商執行不同的執行sql
例如:
<databaseIdProvider type="DB_VENDOR">
    <! --為不同的資料庫廠商起別名–->
    <property name="MysQL " value= "mysql" />
    <property name="Oracle" value="oracle" / >
</databaseIdProvider>

在slq標籤裡通過databaseId="databaseIdProvider標籤下資料庫取的名稱"指定

例如:
<select id="getEmpById" resultType="com.xiaoai.empUser" databaseId="mysql">
    select *
    from tbl_employee 
    where id = #{id}
</select>
  • 【mapper】標籤
    引入介面對應slq對映檔案.xml
屬性:
resource引用類路徑下的sql對映檔案
url 引用網路路徑或磁碟下的sql對映檔案
class 引用(註冊)介面全限定類名: 1-如果用註解,就是引入介面類。2-如果是對映檔案,對映檔案必須和介面同名,並且放在介面同一目錄下;