MyBatis教程[7]----xml映射配置補充

本篇文章針對前面沒有講到的XML映射配置文件做一個補充說明。

1. selectKey自動生成主鍵

對於不支持自動生成主鍵列的數據庫和可能不支持自動生成主鍵的 JDBC 驅動,MyBatis 有另外一種方法來生成主鍵。

這裏有一個簡單(也很傻)的示例,它可以生成一個隨機 ID(不建議實際使用,這裏只是爲了展示 MyBatis 處理問題的靈活性和寬容度):

<insert id="insert">
    <selectKey keyProperty="id" resultType="int" order="BEFORE">
        SELECT FLOOR(RAND()*10000) AS id
    </selectKey>
    INSERT INTO `user`(`id`,`name`, `phone`, `birthday`) VALUES (#{id}, #{u.name}, #{u.phone}, #{u.birthday})
</insert>

單元測試:

@Test
void insert() throws ParseException {
    User user = new User();
    user.setName("啊隨");
    user.setPhone("11111111111");
    user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-18"));

    userMapper.insert(user);
}

運行結果:
在這裏插入圖片描述
並不建議這樣做,畢竟絕大多數數據庫都有自增主鍵的功能,不需要更沒必要自動生成一個隨機數來當作id。這裏只是演示一下selectKey標籤還有這種用法。

屬性 描述
keyProperty selectKey 語句結果應該被設置到的目標屬性。如果生成列不止一個,可以用逗號分隔多個屬性名稱。
keyColumn 返回結果集中生成列屬性的列名。如果生成列不止一個,可以用逗號分隔多個屬性名稱。
resultType 結果的類型。通常 MyBatis 可以推斷出來,但是爲了更加準確,寫上也不會有什麼問題。MyBatis 允許將任何簡單類型用作主鍵的類型,包括字符串。如果生成列不止一個,則可以使用包含期望屬性的 Object 或 Map。
order 可以設置爲 BEFORE 或 AFTER。如果設置爲 BEFORE,那麼它首先會生成主鍵,設置 keyProperty 再執行插入語句。如果設置爲 AFTER,那麼先執行插入語句,然後是 selectKey 中的語句 - 這和 Oracle 數據庫的行爲相似,在插入語句內部可能有嵌入索引調用。
statementType 和前面一樣,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 類型的映射語句,分別代表 Statement, PreparedStatement 和 CallableStatement 類型。

2. 返回主鍵id

在實際應用中,常常需要返回insert語句的主鍵id。配置起來很簡單,只需:

  • 指定insert標籤的useGeneratedKeys屬性爲true
  • 指定insert標籤的keyProperty屬性所對應的實體類的屬性名
  • 指定insert標籤的keyColumn屬性所對應的數據表的字段名
<insert id="insertAndGetId" parameterType="com.yky.springboot.entities.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        INSERT INTO `user`(`name`, `phone`, `birthday`) VALUES (#{u.name}, #{u.phone}, #{u.birthday})
</insert>

返回的主鍵id會直接注入到user對象中。

@Test
void insertAndGetId() throws ParseException {
    User user = new User();
    user.setName("id返回");
    user.setPhone("11111111111");
    user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-18"));

    userMapper.insertAndGetId(user);
    System.out.println(user.getId());
}

3. sql標籤代碼重用

可以使用sql標籤將多個地方會用到的代碼抽取出來。

<sql id="allColumn">
	`id`, `name`, `phone`, `birthday`
</sql>

直接使用include標籤進行引用

<select id="selectById" resultType="User" >
   SELECT 
        <include refid="allColumn"></include>
   FROM `user` WHERE id = #{id}
</select>

4. 佔位符與字符串替換

前面我們用了很多次#{}佔位符,默認情況下,使用 #{} 參數語法時,MyBatis 會創建 PreparedStatement 參數佔位符,並通過佔位符安全地設置參數(就像使用 ? 一樣)。 這樣做更安全,更迅速,通常也是首選做法,不過有時你就是想直接在 SQL 語句中直接插入一個不轉義的字符串。這時就需要用到${}了。

比如:

ORDER BY ${columnName}

那什麼時候用 ${} 呢?當SQL語句中的表名/列名需要動態生成時,則需要用到 ${}。因爲表名/列名需要直接替換進SQL語句,而不能經過轉義。

在這裏舉一個使用字符串替換的例子:

映射接口:

/**
 * 根據列名和改列所對應的值匹配
 * @param columnName 列名
 * @param value 值
 * @return
 */
List<User> selectByColumn(@Param("columnName") String columnName,@Param("value") String value);

xml映射配置:

<select id="selectByColumn" resultType="User">
    SELECT 
    <include refid="allColumn"></include>
    FROM `user`
    WHERE ${columnName} = #{value}
</select>

單元測試代碼:

@Test
void selectByColumn() {
    List<User> users = userMapper.selectByColumn("name", "小明");

    System.out.println(users);
}

Mybatis不推薦我們這樣做,因爲這種用法會導致潛在的SQL注入攻擊。如果非要這樣用,推薦對輸入的參數進行校驗,以防止非法SQL語句被執行。

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