一文搞定mybatis各種標籤

select標籤

在 SQL 映射文件中 < select> 元素用於映射 SQL 的 select 語句,其示例代碼如下:

<!--根據uid查詢一個用戶信息 -->
<select id="selectUserById" parameterType="Integer" resultType="com.mybatis.po.MyUser">
    select * from user where uid = #{uid}
</select>

在上述示例代碼中,id 的值是唯一標識符,它接收一個 Integer 類型的參數,返回一個 MyUser 類型的對象,結果集自動映射到 MyUser 屬性。

< select> 元素除了有上述示例代碼中的幾個屬性以外,還有一些常用的屬性,如表 1 所示。

屬性名稱 描 述
id 它和 Mapper 的命名空間組合起來使用,是唯一標識符,供 MyBatis 調用
parameterType 表示傳入 SQL 語句的參數類型的全限定名或別名。它是一個可選屬性,MyBatis 能推斷出具體傳入語句的參數
resultType SQL 語句執行後返回的類型(全限定名或者別名)。如果是集合類型,返回的是集合元素的類型,返回時可以使用 resultType 或 resultMap 之一
resultMap 它是映射集的引用,與 < resultMap> 元素一起使用,返回時可以使用 resultType 或 resultMap 之一
flushCache 用於設置在調用 SQL 語句後是否要求 MyBatis 清空之前查詢的本地緩存和二級緩存,默認值爲 false,如果設置爲 true,則任何時候只要 SQL 語句被調用都將清空本地緩存和二級緩存
useCache 啓動二級緩存的開關,默認值爲 true,表示將査詢結果存入二級緩存中
timeout 用於設置超時參數,單位是秒(s),超時將拋出異常
fetchSize 獲取記錄的總條數設定
statementType 告訴 MyBatis 使用哪個 JDBC 的 Statement 工作,取值爲 STATEMENT(Statement)、 PREPARED(PreparedStatement)、CALLABLE(CallableStatement)
resultSetType 這是針對 JDBC 的 ResultSet 接口而言,其值可設置爲 FORWARD_ONLY(只允許向前訪問)、SCROLL_SENSITIVE(雙向滾動,但不及時更新)、SCROLLJNSENSITIVE(雙向滾動,及時更新)

使用 Map 接口傳遞多個參數

在實際開發中,查詢 SQL 語句經常需要多個參數,例如多條件查詢。當傳遞多個參數時,< select> 元素的 parameterType 屬性值的類型是什麼呢?在 MyBatis 中允許 Map 接口通過鍵值對傳遞多個參數。

假設數據操作接口中有個實現查詢陳姓男性用戶信息功能的方法:

public List< MyUser> selectAllUser(Map<String,Object> param);

此時,傳遞給映射器的是一個 Map 對象,使用它在 SQL 文件中設置對應的參數,對應 SQL 文件的代碼如下:

<!-- 查詢陳姓男性用戶信息 -->
<select id="selectAllUser" resultType="com.mybatis.po.MyUser">
    select * from user
    where uname like concat('%',#{u_name},'%')
    and usex = #{u_sex}
</select>

在上述 SQL 文件中,參數名 u_name 和 u_sex 是 Map 的 key。

爲了測試該示例,首先創建一個 Web 應用 mybatisDemo02,將 mybatisDemo01 應用的所有 JAR 包複製到 /WEB-INF/lib 下,同時將 mybatisDemo01 應用的 src 目錄下的所有包和文件複製到 mybatisDemo02 應用的 src 目錄下。

然後將 com.mybatis 包中的 SQL 映射文件 UserMapper.xml 中的“查詢所有用戶信息”的代碼片段修改爲上述“查詢陳姓男性用戶信息”的代碼片段,最後將 com.controller 包中 UserController 的代碼簡單修改即可運行測試類了。

com.controller 包中 UserController 的代碼片段如下:

@Controller("UserController")
public class UserController {
    private UserDao userDao;
    public void test(){
        ...
        //查詢多個用戶
        Map<String,Object> map = new HashMap<>();
        map.put("u_name","陳");
        map.put("u_sex","男");
        List<MyUser> list = userDao.seleceAllUser(map);
        for(MyUser myUser : list) {
            System.out.println(myUser);
        }
        ...
    }
}

Map 是一個鍵值對應的集合,使用者要通過閱讀它的鍵才能瞭解其作用。另外,使用 Map 不能限定其傳遞的數據類型,所以業務性不強,可讀性較差。如果 SQL 語句很複雜,參數很多,使用 Map 將很不方便。幸運的是,MyBatis 還提供了使用 Java Bean 傳遞多個參數的形式。

使用 Java Bean 傳遞多個參數

首先在 myBatisSemo02 應用的 src 目錄下創建一個名爲 com.pojo 的包,在包中創建一個 POJO 類 SeletUserParam,代碼如下:

package com.pojo;
public class SeletUserParam {
    private String u_name;
    private String u_sex;
    // 此處省略setter和getter方法
}

接着將 Dao 接口中的 selectAllUser 方法修改爲如下:

public List< MyUser> selectAllUser(SelectUserParam param);

然後將 com.mybatis 包中的 SQL 映射文件 UserMapper.xml 中的“查詢陳姓男性用戶信息”的代碼修改爲如下:

<select id="selectAllUser" resultType="com.po.MyUser" parameterType="com.pojo.SeletUserParam">
  select * from user
  where uname like concat('%',#{u_name},'%')
  and usex=#{u_sex}
</select>

最後將 com.controller 包中 UserController 的“查詢多個用戶”的代碼片段做如下修改:

SeletUserParam su = new SelectUserParam();
su.setU_name("陳");
su.setU_sex("男");
List<MyUser> list = userDao.selectAllUser(su);
for (MyUser myUser : list) {
    System.out.println(myUser);
}

在實際應用中是選擇 Map 還是選擇 Java Bean 傳遞多個參數應根據實際情況而定,一般建議選擇 Java Bean。

insert、update、delete和sql標籤

< insert>元素

< insert> 元素用於映射插入語句,MyBatis 執行完一條插入語句後將返回一個整數表示其影響的行數。它的屬性與 < select> 元素的屬性大部分相同,在本節講解它的幾個特有屬性。

  • keyProperty:該屬性的作用是將插入或更新操作時的返回值賦給 PO 類的某個屬性,通常會設置爲主鍵對應的屬性。如果是聯合主鍵,可以將多個值用逗號隔開。
  • keyColumn:該屬性用於設置第幾列是主鍵,當主鍵列不是表中的第 1 列時需要設置。如果是聯合主鍵,可以將多個值用逗號隔開。
  • useGeneratedKeys:該屬性將使 MyBatis 使用 JDBC 的 getGeneratedKeys()方法獲取由數據庫內部產生的主鍵,例如 MySQL、SQL Server 等自動遞增的字段,其默認值爲 false。

1)主鍵(自動遞增)回填

MySQL、SQL Server 等數據庫的表格可以採用自動遞增的字段作爲主鍵,有時可能需要使用這個剛剛產生的主鍵,用於關聯其他業務。

首先爲 com.mybatis 包中的 SQL 映射文件 UserMapper.xml 中 id 爲 addUser 的 < insert> 元素添加 keyProperty 和 useGeneratedKeys 屬性,具體代碼如下:

<!--添加一個用戶,成功後將主鍵值返回填給uid(po的屬性)-->
<insert id="addUser" parameterType="com.po.MyUser" keyProperty="uid" useGeneratedKeys="true">
  insert into user (uname,usex) values(#{uname},#{usex})
</insert>

然後在 com.controller 包的 UserController 類中進行調用,具體代碼如下:

// 添加一個用戶
MyUser addmu = new MyUser();
addmu.setUname("陳恆");
addmu.setUsex("男");
int add = userDao.addUser(addmu);
System.out.println("添加了" + add + "條記錄");
System.out.println("添加記錄的主鍵是" + addmu.getUid());

2)自定義主鍵

如果在實際工程中使用的數據庫不支持主鍵自動遞增(例如 Oracle),或者取消了主鍵自動遞增的規則,可以使用 MyBatis 的 < selectKey> 元素來自定義生成主鍵。具體配置示例代碼如下:

<!-- 添加一個用戶,#{uname}爲 com.mybatis.po.MyUser 的屬性值 -->
<insert id="insertUser" parameterType="com.po.MyUser">
    <!-- 先使用selectKey元素定義主鍵,然後再定義SQL語句 -->
    <selectKey keyProperty="uid" resultType="Integer" order="BEFORE">
    select if(max(uid) is null,1,max(uid)+1) as newUid from user)
    </selectKey>
    insert into user (uid,uname,usex) values(#{uid},#{uname},#{usex})
</insert>

在執行上述示例代碼時,< selectKey> 元素首先被執行,該元素通過自定義的語句設置數據表的主鍵,然後執行插入語句。

< selectKey> 元素的 keyProperty 屬性指定了新生主鍵值返回給 PO 類(com.po.MyUser)的哪個屬性。

  • order 屬性可以設置爲 BEFORE 或 AFTER。
  • BEFORE 表示先執行 < selectKey> 元素然後執行插入語句。
  • AFTER 表示先執行插入語句再執行 < selectKey> 元素。

< update>與< delete>元素

< update> 和 < delete> 元素比較簡單,它們的屬性和 < insert> 元素、< select> 元素的屬性差不多,執行後也返回一個整數,表示影響了數據庫的記錄行數。配置示例代碼如下:

<!-- 修改一個用戶 -->
<update id="updateUser" parameterType="com.po.MyUser">
    update user set uname = #{uname},usex = #{usex} where uid = #{uid}
</update>
<!-- 刪除一個用戶 -->
<delete id="deleteUser" parameterType="Integer">
    delete from user where uid = #{uid}
</delete>

< sql> 元素

< sql> 元素的作用在於可以定義 SQL 語句的一部分(代碼片段),以方便後面的 SQL 語句引用它,例如反覆使用的列名。

在 MyBatis 中只需使用 < sql> 元素編寫一次便能在其他元素中引用它。配置示例代碼如下:

<sql id="comColumns">id,uname,usex</sql>
<select id="selectUser" resultType="com.po.MyUser">
    select <include refid="comColumns"> from user
</select>

在上述代碼中使用 < include> 元素的 refid 屬性引用了自定義的代碼片段。

if標籤

開發人員通常根據需求手動拼接 SQL 語句,這是一個極其麻煩的工作,而 MyBatis 提供了對 SQL 語句動態組裝的功能,恰能解決這一問題。

MyBatis 的動態 SQL 元素與 JSTL 或 XML 文本處理器相似,常用 < if>、< choose>、< when>、< otherwise>、< trim>、< where>、< set>、< foreach> 和 < bind> 等元素。

動態 SQL 通常要做的事情是有條件地包含 where 子句的一部分,所以在 MyBatis 中 < if> 元素是最常用的元素,它類似於 Java 中的 if 語句。在 myBatisDemo03 應用中測試 < if> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用 if 元素根據條件動態查詢用戶信息-->
<select id="selectUserByIf" resultType="com.po.MyUser" parameterType="com.po.MyUser">
    select * from user where 1=1
    <if test="uname!=null and uname!=''">
        and uname like concat('%',#{uname},'%')
    </if >
    <if test="usex !=null and usex !=''">
        and usex=#{usex}
    </if >
</select>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public List<MyUser> selectUserByIf(MyUser user);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

// 使用 if 元素查詢用戶信息
MyUser ifmu=new MyUser();
ifmu.setUname ("張");
ifmu.setUsex ("女");
List<MyUser> listByif=userDao.selectUserByIf(ifmu);
System.out.println ("if元素================");
for (MyUser myUser:listByif) {
    System.out.println(myUser);
}

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

choose、when、otherwise標籤

有些時候不想用到所有的條件語句,而只想從中擇取一二,針對這種情況,MyBatis 提供了 < choose> 元素,它有點像 Java 中的 switch 語句。在 myBatisDemo03 應用中測試 < choose> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用choose、when、otherwise元素根據條件動態查詢用戶信息-->
<select id="selectUserByChoose" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
    select * from user where 1=1
    <choose>
        <when test="uname!=null and uname!=''">
            and uname like concat('%',#{uname},'%')
        </when>
        <when test="usex!=null and usex!=''">
            and usex=#{usex}
        </when>
        <otherwise>
            and uid > 10
        </otherwise>
    </choose>
</select>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public List<MyUser> selectUserByChoose(MyUser user);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

// 使用 choose 元素查詢用戶信息
MyUser choosemu=new MyUser();
choosemu.setUname("");
choosemu.setUsex("");
List<MyUser> listByChoose = UserDao.selectUserEyChoose(choosemu);
System.out.println ("choose 元素================");
for (MyUser myUser:listByChoose) {
    System.out.println(myUser);
}

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

trim、where、set標籤

< trim>元素

< trim> 元素的主要功能是可以在自己包含的內容前加上某些前綴,也可以在其後加上某些後綴,與之對應的屬性是 prefix 和 suffix。

可以把包含內容的首部某些內容覆蓋,即忽略,也可以把尾部的某些內容覆蓋,對應的屬性是 prefixOverrides 和 suffixOverrides。正因爲 < trim> 元素有這樣的功能,所以也可以非常簡單地利用 < trim> 來代替 < where> 元素的功能。

在 myBatisDemo03 應用中測試 < trim> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用trim元素根據條件動態查詢用戶信息-->
<select id="selectUserByTrim" resultType="com.po.MyUser"parameterType="com.po.MyUser">
    select * from user
    <trim prefix="where" prefixOverrides = "and | or">
        <if test="uname!=null and uname!=''">
            and uname like concat('%',#{uname},'%')
        </if>
        <if test="usex!=null and usex!=''">
            and usex=#{usex}
        </if>
    </trim>
</select>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public List<MyUser> selectUserByTrim(MyUser user);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

// 使用trim元素查詢用戶信息
MyUser trimmu=new MyUser();
trimmu.setUname ("張");
trimmu.setUsex("男");
List<MyUser> listByTrim=userDao.selectUserByTrim(trimmu);
System.out.println ("trim 元素=========================");
for (MyUser myUser:listByTrim) {
    System.out.println(myUser);
}

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

< where> 元素

< where> 元素的作用是會在寫入 < where> 元素的地方輸出一個 where 語句,另外一個好處是不需要考慮 < where> 元素裏面的條件輸出是什麼樣子的,MyBatis 將智能處理。如果所有的條件都不滿足,那麼 MyBatis 就會查出所有的記錄,如果輸出後是以 and 開頭的,MyBatis 會把第一個 and 忽略。

當然如果是以 or 開頭的,MyBatis 也會把它忽略;此外,在 < where> 元素中不需要考慮空格的問題,MyBatis 將智能加上。

在 myBatisDemo03 應用中測試 < where> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用where元素根據條件動態查詢用戶信息-->
<select id="selectUserByWhere" resultType="com.po.MyUser" parameterType="com.po.MyUser">
    select * from user
    <where>
        <if test="uname != null and uname ! = ''">
            and uname like concat('%',#{uname},'%')
        </if>
        <if test="usex != null and usex != '' ">
            and usex=#{usex}
        </if >
    </where>
</select>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public List<MyUser> selectUserByWhere(MyUser user);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

// 使用where元素查詢用戶信息
MyUser wheremu=new MyUser();
wheremu.setUname ("張");
wheremu.setUsex("男");
List<MyUser> listByWhere=userDao.selectUserByWhere(wheremu);
System.out.println ("where 元素=========================");
for (MyUser myUser:listByWhere) {
    System.out.println(myUser);
}

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

< set>元素

在動態 update 語句中可以使用 < set> 元素動態更新列。在 myBatisDemo03 應用中測試 < set> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用set元素動態修改一個用戶-->
<update id="updateUserBySet" parameterType="com.po.MyUser">     
    update user
    <set>
        <if test="uname!=null">uname=#{uname}</if>
        <if test="usex!=null">usex=#{usex}</if>
    </set>
    where uid=#{uid}
</update>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public int updateUserBySet(MyUser user);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

// 使用set元素查詢用戶信息
MyUser setmu=new MyUser();
setmu.setUid (1);
setmu.setUname("張九");
int setup=userDao.updateUserBySet(setmu);
System.out.println ("set 元素修改了"+setup+"條記錄");
System.out.println ("=========================")

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

foreach標籤

< foreach> 元素主要用在構建 in 條件中,它可以在 SQL 語句中迭代一個集合。

< foreach> 元素的屬性主要有 item、index、collection、open、separator、close。

  • item 表示集合中每一個元素進行迭代時的別名。
  • index 指定一個名字,用於表示在迭代過程中每次迭代到的位置。
  • open 表示該語句以什麼開始。
  • separator 表示在每次進行迭代之間以什麼符號作爲分隔符。
  • close 表示以什麼結束。

在使用 < foreach> 元素時,最關鍵、最容易出錯的是 collection 屬性,該屬性是必選的,但在不同情況下該屬性的值是不一樣的,主要有以下 3 種情況:

  • 如果傳入的是單參數且參數類型是一個 List,collection 屬性值爲 list。
  • 如果傳入的是單參數且參數類型是一個 array 數組,collection 的屬性值爲 array。
  • 如果傳入的參數是多個,需要把它們封裝成一個 Map,當然單參數也可以封裝成 Map。Map 的 key 是參數名,collection 屬性值是傳入的 List 或 array 對象在自己封裝的 Map 中的 key。

在 myBatisDemo03 應用中測試 < foreach> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用foreach元素查詢用戶信息-->
<select id="selectUserByForeach" resultType="com.po.MyUser" parameterType=
"List">
    select * from user where uid in
    <foreach item="item" index="index" collection="list"
    open="(" separator="," close=")">
        # {item}
    </foreach>
</select>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public List<MyUser> selectUserByForeach(List<Integer> listId);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

//使用foreach元素查詢用戶信息
List<Integer> listId=new ArrayList<Integer>();
listId.add(34);
listId.add(37);
List<MyUser> listByForeach = userDao.selectUserByForeach(listId);
System.out.println ("foreach元素================");
for(MyUser myUser : listByForeach) {
    System.out.println(myUser);
}

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

bind標籤

在進行模糊查詢時,如果使用“${}”拼接字符串,則無法防止 SQL 注入問題。如果使用字符串拼接函數或連接符號,但不同數據庫的拼接函數或連接符號不同。

例如 MySQL 的 concat 函數、Oracle 的連接符號“||”,這樣 SQL 映射文件就需要根據不同的數據庫提供不同的實現,顯然比較麻煩,且不利於代碼的移植。幸運的是,MyBatis 提供了 < bind> 元素來解決這一問題。

在 myBatisDemo03 應用中測試 < bind> 元素,具體過程如下:

1)添加 SQL 映射語句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射語句:

<!--使用bind元素進行模糊查詢-->
<select id="selectUserByBind" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
    <!-- bind 中的 uname 是 com.po.MyUser 的屬性名-->
    <bind name="paran_uname" value="'%' + uname + '%'"/>
        select * from user where uname like #{paran_uname}
</select>

2)添加數據操作接口方法

在 com.dao 包的 UserDao 接口中添加如下數據操作接口方法:

public List<MyUser> selectUserByBind(MyUser user);

3)調用數據操作接口方法

在 com.controller 包的 UserController 類中添加如下程序調用數據操作接口方法。

// 使用bind元素查詢用戶信息
MyUser bindmu=new MyUser();
bindmu.setUname ("張");
List<MyUser> listByBind=userDao.selectUserByBind(bindmu);
System.out.println ("bind 元素=========================");
for (MyUser myUser:listByBind) {
    System.out.println(myUser);
}

4)測試動態 SQL 語句

運行 com.controller 包中的 TestController 主類,測試動態 SQL 語句。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章