MyBatis動態SQL(認真看看, 之後寫SQL就爽多了)

(給Java技術江湖加星標,提升Java技能)html

轉自:博客園,做者:阿進得寫字檯 www.cnblogs.com/homejim/p/9909657.html面試

0 一塊兒來學習 mybatissql

你想不想來學習 mybatis? 學習其使用和源碼呢?數據庫

MyBatis 使人喜歡的一大特性就是動態 SQL。在使用 JDBC 的過程當中, 根據條件進行 SQL 的拼接是很麻煩且很容易出錯的。MyBatis 動態 SQL 的出現, 解決了這個麻煩。數組

MyBatis經過 OGNL 來進行動態 SQL 的使用的。mybatis

目前, 動態 SQL 支持如下幾種標籤app

<figure data-block="true" data-editor="fj6sl" data-offset-key="e7aul-0-0" contenteditable="false">ide

</figure>函數

1 數據準備學習

爲了後面的演示, 建立了一個 Maven 項目 mybatis-dynamic, 建立了對應的數據庫和表

<pre data-offset-key="9am2l-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="9am2l-0-0"> DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `student_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '編號', `name` varchar(20) DEFAULT NULL COMMENT '姓名', `phone` varchar(20) DEFAULT NULL COMMENT '電話', `email` varchar(50) DEFAULT NULL COMMENT '郵箱', `sex` tinyint(4) DEFAULT NULL COMMENT '性別', `locked` tinyint(4) DEFAULT NULL COMMENT '狀態(0:正常,1:鎖定)', `gmt_created` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '存入數據庫的時間', `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改的時間', `delete` int(11) DEFAULT NULL, PRIMARY KEY (`student_id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='學生表'; </pre>

</pre>

對應的項目結構

<figure data-block="true" data-editor="fj6sl" data-offset-key="c7r9v-0-0" contenteditable="false">

</figure>

2 if 標籤

if 標籤是咱們最常使用的。在查詢、刪除、更新的時候極可能會使用到。必須結合 test 屬性聯合使用。

2.1 在 WHERE 條件中使用 if 標籤

這是常見的一種現象, 咱們在進行按條件查詢的時候, 可能會有多種狀況。

2.1.1 查詢條件

根據輸入的學生信息進行條件檢索

  1. 當只輸入用戶名時, 使用用戶名進行模糊檢索;

  2. 當只輸入性別時, 使用性別進行徹底匹配;

  3. 當用戶名和性別都存在時, 用這兩個條件進行查詢匹配查詢。

2.1.2 動態 SQL

接口函數

<pre data-offset-key="9gkef-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="9gkef-0-0"> /** * 根據輸入的學生信息進行條件檢索 * 1\. 當只輸入用戶名時, 使用用戶名進行模糊檢索; * 2\. 當只輸入郵箱時, 使用性別進行徹底匹配 * 3\. 當用戶名和性別都存在時, 用這兩個條件進行查詢匹配的用 * [@param](https://my.oschina.net/u/2303379) student * [@return](https://my.oschina.net/u/556800) */ List<Student> selectByStudentSelective(Student student); </pre>

</pre>

對應的動態 SQL

<pre data-offset-key="2091b-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="2091b-0-0"> <select id="selectByStudentSelective" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student"> select <include refid="Base_Column_List" /> from student where 1=1 <if test="name != null and name !=''"> and name like concat('%', #{name}, '%') </if> <if test="sex != null"> and sex=#{sex} </if> </select> </pre>

</pre>

在此 SQL 語句中, where 1=1 是多條件拼接時的小技巧, 後面的條件查詢就能夠都用 and 了。

同時, 咱們添加了 if 標籤來處理動態 SQL

<pre data-offset-key="45jmf-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="45jmf-0-0"> <if test="name != null and name !=''"> and name like concat('%', #{name}, '%') </if> <if test="sex != null"> and sex=#{sex} </if> </pre>

</pre>

此 if 標籤的 test 屬性值是一個符合 OGNL 的表達式, 表達式能夠是 true 或 false。若是表達式返回的是數值, 則0爲 false, 非 0 爲 true;

2.1.3 測試

<pre data-offset-key="3jdef-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="3jdef-0-0"> [@Test](https://my.oschina.net/azibug) public void selectByStudent() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student search = new Student(); search.setName("明"); System.out.println("只有名字時的查詢"); List<Student> studentsByName = studentMapper.selectByStudentSelective(search); for (int i = 0; i < studentsByName.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByName.get(i), ToStringStyle.MULTI_LINE_STYLE)); } search.setName(null); search.setSex((byte) 1); System.out.println("只有性別時的查詢"); List<Student> studentsBySex = studentMapper.selectByStudentSelective(search); for (int i = 0; i < studentsBySex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsBySex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } System.out.println("姓名和性別同時存在的查詢"); search.setName("明"); List<Student> studentsByNameAndSex = studentMapper.selectByStudentSelective(search); for (int i = 0; i < studentsByNameAndSex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByNameAndSex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

只有名字時的查詢, 發送的語句和結果

<figure data-block="true" data-editor="fj6sl" data-offset-key="e45i6-0-0" contenteditable="false">

</figure>

查詢的條件只發送了

<pre data-offset-key="fla1n-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="fla1n-0-0"> where 1=1 and sex=? </pre>

</pre>

姓名和性別同時存在的查詢,發送的語句和結果

<figure data-block="true" data-editor="fj6sl" data-offset-key="44mfs-0-0" contenteditable="false">

</figure>

查詢條件

<pre data-offset-key="7caff-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="7caff-0-0"> where 1=1 and name like concat('%', ?, '%') and sex=? </pre>

</pre>

2.2 在 UPDATE 更新列中使用 if 標籤

有時候咱們不但願更新全部的字段, 只更新有變化的字段。

2.2.1 更新條件

只更新有變化的字段, 空值不更新。

2.2.1 動態 SQL

接口方法

<pre data-offset-key="6cbqa-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="6cbqa-0-0"> /** * 更新非空屬性 */ int updateByPrimaryKeySelective(Student record); </pre>

</pre>

對應的 SQL

<pre data-offset-key="cpgar-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="cpgar-0-0"> <update id="updateByPrimaryKeySelective" parameterType="com.homejim.mybatis.entity.Student"> update student <set> <if test="name != null"> `name` = #{name,jdbcType=VARCHAR}, </if> <if test="phone != null"> phone = #{phone,jdbcType=VARCHAR}, </if> <if test="email != null"> email = #{email,jdbcType=VARCHAR}, </if> <if test="sex != null"> sex = #{sex,jdbcType=TINYINT}, </if> <if test="locked != null"> locked = #{locked,jdbcType=TINYINT}, </if> <if test="gmtCreated != null"> gmt_created = #{gmtCreated,jdbcType=TIMESTAMP}, </if> <if test="gmtModified != null"> gmt_modified = #{gmtModified,jdbcType=TIMESTAMP}, </if> </set> where student_id = #{studentId,jdbcType=INTEGER} </pre>

</pre>

2.2.3 測試

<pre data-offset-key="bt52s-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="bt52s-0-0"> [@Test](https://my.oschina.net/azibug) public void updateByStudentSelective() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student student = new Student(); student.setStudentId(1); student.setName("明明"); student.setPhone("13838438888"); System.out.println(studentMapper.updateByPrimaryKeySelective(student)); sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

結果以下

<figure data-block="true" data-editor="fj6sl" data-offset-key="3k8ck-0-0" contenteditable="false">

</figure>

2.3 在 INSERT 動態插入中使用 if 標籤

咱們插入數據庫中的一條記錄, 不是每個字段都有值的, 而是動態變化的。在這時候使用 if 標籤, 可幫咱們解決這個問題。

2.3.1 插入條件

只有非空屬性才插入。

2.3.2 動態SQL

接口方法

<pre data-offset-key="80btv-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="80btv-0-0"> /** * 非空字段才進行插入 */ int insertSelective(Student record); </pre>

</pre>

對應的SQL

<pre data-offset-key="fr1m9-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="fr1m9-0-0"> <insert id="insertSelective" parameterType="com.homejim.mybatis.entity.Student"> insert into student <trim prefix="(" suffix=")" suffixOverrides=","> <if test="studentId != null"> student_id, </if> <if test="name != null"> `name`, </if> <if test="phone != null"> phone, </if> <if test="email != null"> email, </if> <if test="sex != null"> sex, </if> <if test="locked != null"> locked, </if> <if test="gmtCreated != null"> gmt_created, </if> <if test="gmtModified != null"> gmt_modified, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="studentId != null"> #{studentId,jdbcType=INTEGER}, </if> <if test="name != null"> #{name,jdbcType=VARCHAR}, </if> <if test="phone != null"> #{phone,jdbcType=VARCHAR}, </if> <if test="email != null"> #{email,jdbcType=VARCHAR}, </if> <if test="sex != null"> #{sex,jdbcType=TINYINT}, </if> <if test="locked != null"> #{locked,jdbcType=TINYINT}, </if> <if test="gmtCreated != null"> #{gmtCreated,jdbcType=TIMESTAMP}, </if> <if test="gmtModified != null"> #{gmtModified,jdbcType=TIMESTAMP}, </if> </trim> </insert> </pre>

</pre>

這個 SQL 你們應該很熟悉, 畢竟是自動生成的。

2.3.3 測試

<pre data-offset-key="alu1j-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="alu1j-0-0"> [@Test](https://my.oschina.net/azibug) public void insertByStudentSelective() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student student = new Student(); student.setName("小飛機"); student.setPhone("13838438899"); student.setEmail("xiaofeiji@qq.com"); student.setLocked((byte) 0); System.out.println(studentMapper.insertSelective(student)); sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

對應的結果

<figure data-block="true" data-editor="fj6sl" data-offset-key="88cv7-0-0" contenteditable="false">

</figure>

SQL 中, 只有非空的字段才進行了插入。

3 choose 標籤

choose when otherwise 標籤能夠幫咱們實現 if else 的邏輯。

一個 choose 標籤至少有一個 when, 最多一個otherwise

下面是一個查詢的例子。

3.1 查詢條件

假設 name 具備惟一性, 查詢一個學生

  • 當 studen_id 有值時, 使用 studen_id 進行查詢;

  • 當 studen_id 沒有值時, 使用 name 進行查詢;

  • 不然返回空

3.2 動態SQL

接口方法

<pre data-offset-key="91gm8-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="91gm8-0-0"> /** * - 當 studen_id 有值時, 使用 studen_id 進行查詢; * - 當 studen_id 沒有值時, 使用 name 進行查詢; * - 不然返回空 */ Student selectByIdOrName(Student record); </pre>

</pre>

對應的SQL

<pre data-offset-key="509ds-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="509ds-0-0"> <select id="selectByIdOrName" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student"> select <include refid="Base_Column_List" /> from student where 1=1 <choose> <when test="studentId != null"> and student_id=#{studentId} </when> <when test="name != null and name != ''"> and name=#{name} </when> <otherwise> and 1=2 </otherwise> </choose> </select> </pre>

</pre>

3.3 測試

<pre data-offset-key="11f6d-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="11f6d-0-0"> @Test public void selectByIdOrName() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student student = new Student(); student.setName("小飛機"); student.setStudentId(1); Student studentById = studentMapper.selectByIdOrName(student); System.out.println("有 ID 則根據 ID 獲取"); System.out.println(ToStringBuilder.reflectionToString(studentById, ToStringStyle.MULTI_LINE_STYLE)); student.setStudentId(null); Student studentByName = studentMapper.selectByIdOrName(student); System.out.println("沒有 ID 則根據 name 獲取"); System.out.println(ToStringBuilder.reflectionToString(studentByName, ToStringStyle.MULTI_LINE_STYLE)); student.setName(null); Student studentNull = studentMapper.selectByIdOrName(student); System.out.println("沒有 ID 和 name, 返回 null"); Assert.assertNull(studentNull); sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

有 ID 則根據 ID 獲取,結果

<figure data-block="true" data-editor="fj6sl" data-offset-key="alfl1-0-0" contenteditable="false">

</figure>

沒有 ID 則根據 name 獲取

<figure data-block="true" data-editor="fj6sl" data-offset-key="7lads-0-0" contenteditable="false">

</figure>

沒有 ID 和 name, 返回 null

<figure data-block="true" data-editor="fj6sl" data-offset-key="8ei83-0-0" contenteditable="false">

</figure>

4 trim(set、where)

這三個其實解決的是相似的問題。如咱們在寫前面的[在 WHERE 條件中使用 if 標籤] SQL 的時候, where 1=1 這個條件咱們是不但願存在的。

4.1 where

4.1.1 查詢條件

根據輸入的學生信息進行條件檢索。

  1. 當只輸入用戶名時, 使用用戶名進行模糊檢索;

  2. 當只輸入性別時, 使用性別進行徹底匹配

  3. 當用戶名和性別都存在時, 用這兩個條件進行查詢匹配查詢

不使用 where 1=1。

4.1.2 動態 SQL

很顯然, 咱們要解決這幾個問題

  • 當條件都不知足時:此時 SQL 中應該要不能有 where , 不然致使出錯

  • 當 if 有條件知足時:SQL 中須要有 where, 且第一個成立的 if 標籤下的 and | or 等要去掉

這時候, 咱們可使用 where 標籤。

接口方法

<pre data-offset-key="5pn3l-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="5pn3l-0-0"> /** * 根據輸入的學生信息進行條件檢索 * 1\. 當只輸入用戶名時, 使用用戶名進行模糊檢索; * 2\. 當只輸入郵箱時, 使用性別進行徹底匹配 * 3\. 當用戶名和性別都存在時, 用這兩個條件進行查詢匹配的用 */ List<Student> selectByStudentSelectiveWhereTag(Student student); </pre>

</pre>

對應的 SQL

<pre data-offset-key="bg0gn-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="bg0gn-0-0"> <select id="selectByStudentSelectiveWhereTag" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student"> select <include refid="Base_Column_List" /> from student <where> <if test="name != null and name !=''"> and name like concat('%', #{name}, '%') </if> <if test="sex != null"> and sex=#{sex} </if> </where> </select> </pre>

</pre>

4.1.3 測試

<pre data-offset-key="u5cv-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="u5cv-0-0"> @Test public void selectByStudentWhereTag() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student search = new Student(); search.setName("明"); System.out.println("只有名字時的查詢"); List<Student> studentsByName = studentMapper.selectByStudentSelectiveWhereTag(search); for (int i = 0; i < studentsByName.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByName.get(i), ToStringStyle.MULTI_LINE_STYLE)); } search.setSex((byte) 1); System.out.println("姓名和性別同時存在的查詢"); List<Student> studentsBySex = studentMapper.selectByStudentSelectiveWhereTag(search); for (int i = 0; i < studentsBySex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsBySex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } System.out.println("姓名和性別都不存在時查詢"); search.setName(null); search.setSex(null); List<Student> studentsByNameAndSex = studentMapper.selectByStudentSelectiveWhereTag(search); for (int i = 0; i < studentsByNameAndSex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByNameAndSex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

只有名字時的查詢, 有 where

<figure data-block="true" data-editor="fj6sl" data-offset-key="e1m3v-0-0" contenteditable="false">

</figure>

姓名和性別同時存在的查詢, 有 where

<figure data-block="true" data-editor="fj6sl" data-offset-key="6a4fk-0-0" contenteditable="false">

</figure>

姓名和性別都不存在時查詢, 此時,where 不會再出現了。

4.2 set

set 標籤也相似, 在 [2.2 在 UPDATE 更新列中使用 if 標籤] 中, 若是咱們的方法 updateByPrimaryKeySelective 沒有使用

4.3 trim

set 和 where 其實都是 trim 標籤的一種類型, 該兩種功能均可以使用 trim 標籤進行實現。

4.3.1 trim 來表示 where

如以上的 where 標籤, 咱們也能夠寫成

<pre data-offset-key="7vpvm-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="7vpvm-0-0"> <trim prefix="where" prefixOverrides="AND |OR"> </trim> </pre>

</pre>

表示當 trim 中含有內容時, 添加 where, 且第一個爲 and 或 or 時, 會將其去掉。而若是沒有內容, 則不添加 where。

4.3.2 trim 來表示 set

相應的, set 標籤能夠以下表示

<pre data-offset-key="1nsj6-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="1nsj6-0-0"> <trim prefix="SET" suffixOverrides=","> </trim> </pre>

</pre>

表示當 trim 中含有內容時, 添加 set, 且最後的內容爲 , 時, 會將其去掉。而沒有內容, 不添加 set

4.3.3 trim 的幾個屬性

  • prefix: 當 trim 元素包含有內容時, 增長 prefix 所指定的前綴

  • prefixOverrides: 當 trim 元素包含有內容時, 去除 prefixOverrides 指定的 前綴

  • suffix: 當 trim 元素包含有內容時, 增長 suffix 所指定的後綴

  • suffixOverrides:當 trim 元素包含有內容時, 去除 suffixOverrides 指定的後綴

5 foreach 標籤

foreach 標籤能夠對數組, Map 或實現 Iterable 接口。

foreach 中有如下幾個屬性

  • collection: 必填, 集合/數組/Map的名稱.

  • item: 變量名。即從迭代的對象中取出的每個值

  • index: 索引的屬性名。當迭代的對象爲 Map 時, 該值爲 Map 中的 Key.

  • open: 循環開頭的字符串

  • close: 循環結束的字符串

  • separator: 每次循環的分隔符

其餘的比較好理解, collection 中的值應該怎麼設定呢?

跟接口方法中的參數相關。

1. 只有一個數組參數或集合參數

默認狀況:集合collection=list, 數組是collection=array

推薦:使用 @Param 來指定參數的名稱, 如咱們在參數前@Param("ids"), 則就填寫 collection=ids

2. 多參數

多參數請使用 @Param 來指定, 不然SQL中會很不方便

3. 參數是Map

指定爲 Map 中的對應的 Key 便可。其實上面的 @Param 最後也是轉化爲 Map 的。

4. 參數是對象

使用屬性.屬性便可。

5.1 在 where 中使用 foreach

在 where條件中使用, 如按id集合查詢, 按id集合刪除等。

5.1.1 查詢條件

咱們但願查詢用戶 id 集合中的全部用戶信息。

5.1.2 動態 SQL

函數接口

<pre data-offset-key="elr7c-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="elr7c-0-0"> /** * 獲取 id 集合中的用戶信息 * @param ids * @return */ List<Student> selectByStudentIdList(List<Integer> ids); </pre>

</pre>

對應 SQL

<pre data-offset-key="6el8p-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="6el8p-0-0"> <select id="selectByStudentIdList" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from student where student_id in <foreach collection="list" item="id" open="(" close=")" separator="," index="i"> #{id} </foreach> </select> </pre>

</pre>

5.1.3 測試

<pre data-offset-key="23tgn-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="23tgn-0-0"> @Test public void selectByStudentIdList() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); List<Integer> ids = new LinkedList<>(); ids.add(1); ids.add(3); List<Student> students = studentMapper.selectByStudentIdList(ids); for (int i = 0; i < students.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(students.get(i), ToStringStyle.MULTI_LINE_STYLE)); } sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

結果

<figure data-block="true" data-editor="fj6sl" data-offset-key="dp836-0-0" contenteditable="false">

</figure>

5.2 foreach 實現批量插入

能夠經過foreach來實現批量插入。

5.2.1 動態SQL

接口方法

<pre data-offset-key="5f91k-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="5f91k-0-0"> /** * 批量插入學生 */ int insertList(List<Student> students); </pre>

</pre>

對應的SQL

<pre data-offset-key="3kh82-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="3kh82-0-0"> <insert id="insertList"> insert into student(name, phone, email, sex, locked) values <foreach collection="list" item="student" separator=","> ( #{student.name}, #{student.phone},#{student.email}, #{student.sex},#{student.locked} ) </foreach> </insert> </pre>

</pre>

5.2.2 測試

<pre data-offset-key="341t-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="341t-0-0"> @Test public void insertList() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); List<Student> students = new LinkedList<>(); Student stu1 = new Student(); stu1.setName("批量01"); stu1.setPhone("13888888881"); stu1.setLocked((byte) 0); stu1.setEmail("13888888881@138.com"); stu1.setSex((byte) 1); students.add(stu1); Student stu2 = new Student(); stu2.setName("批量02"); stu2.setPhone("13888888882"); stu2.setLocked((byte) 0); stu2.setEmail("13888888882@138.com"); stu2.setSex((byte) 0); students.add(stu2); System.out.println(studentMapper.insertList(students)); sqlSession.commit(); sqlSession.close(); } </pre>

</pre>

結果

<figure data-block="true" data-editor="fj6sl" data-offset-key="fjm8v-0-0" contenteditable="false">

</figure>

6 bind 標籤

bind 標籤是經過 OGNL 表達式去定義一個上下文的變量, 這樣方便咱們使用。

如在 selectByStudentSelective 方法中, 有以下

<pre data-offset-key="9fnl-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="9fnl-0-0"> <if test="name != null and name !=''"> and name like concat('%', #{name}, '%') </if> </pre>

</pre>

在 MySQL 中, 該函數支持多參數, 但在 Oracle 中只支持兩個參數。那麼咱們可使用 bind 來讓該 SQL 達到支持兩個數據庫的做用

<pre data-offset-key="54brb-0-0"> <pre data-block="true" data-editor="fj6sl" data-offset-key="54brb-0-0"> <if test="name != null and name !=''"> <bind name="nameLike" value="'%'+name+'%'"/> and name like #{nameLike} </if> </pre>

</pre>

更改後的查詢結果以下

<figure data-block="true" data-editor="fj6sl" data-offset-key="44orl-0-0" contenteditable="false">

</figure>

關注公衆號【Java技術江湖】後回覆「PDF」便可領取200+頁的《Java工程師面試指南》

強烈推薦,幾乎涵蓋全部Java工程師必知必會的知識點,無論是複習仍是面試,都很實用。

<figure data-block="true" data-editor="fj6sl" data-offset-key="f90kr-0-0" contenteditable="false">

</figure>

<figure data-block="true" data-editor="fj6sl" data-offset-key="9dnop-0-0" contenteditable="false">

</figure>

相關文章
相關標籤/搜索