動態SQL
什麼是動態SQL?
MyBatis的官方文件中是這樣介紹的?
動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。
使用動態 SQL 並非一件易事,但藉助可用於任何 SQL 對映語句中的強大的動態 SQL 語言,MyBatis 顯著地提升了這一特性的易用性。
如果你之前用過 JSTL 或任何基於類 XML 語言的文字處理器,你對動態 SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時間瞭解大量的元素。藉助功能強大的基於 OGNL 的表示式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現在要學習的元素種類比原來的一半還要少。
換句話說,我們可以根據傳入引數的不同,來執行不同的查詢條件。
IF標籤:
如何使用?
我們首先建立一個Mapper介面,起名為:UserMapper
,並增加一個方法
public interface UserMapper {
public List<User> findByCondition(User user);
}
同時建立一個xml檔案,起名為UserMapper.xml
然後編寫SQL
<mapper namespace="com.dxh.dao.UserMapper">
<select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User">
SELECT * FROM user where 1=1
<where>
<if test="id != null">
id = #{id}
</if>
</where>
</select>
</mapper>
這個SQL的意思是:
- 當id不為null的時候執行的SQL是:
SELECT * FROM user where id = #{id}
- 當id為null的時候執行的SQL是
SELECT * FROM user where 1=1
很明顯我們可以看到where 1=1
是多餘的,因此我們可以這樣寫:
<select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User">
SELECT * FROM user where 1=1
<where>
<if test="id != null">
id = #{id}
</if>
</where>
</select>
測試:
編寫一個測試類:
package com.dxh.test;
import com.dxh.dao.UserMapper;
import com.dxh.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestMain {
@Test
public void test1() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
List<User> byCondition = mapper.findByCondition(user);
for (User user1 : byCondition) {
System.out.println(user1);
}
System.out.println("======");
User user2 = new User();
List<User> byCondition2 = mapper.findByCondition(user2);
for (User user3 : byCondition2) {
System.out.println(user3);
}
}
}
我們執行兩次mapper.findByCondition()
,分別傳入user和user2,一個的id有被賦值,一個沒有,最後的結果為:
User{id=1, username='lucy'}
======
User{id=1, username='lucy'}
User{id=2, username='李四'}
User{id=3, username='zhaowu'}
foreach標籤:
當我們需要查詢出 id為1、2、3時應該怎麼做? SQL應該這樣寫:SELECT * FROM user where id in (1,2,3)
。那麼使用mybatis的foreach標籤應該如何使用?
如何使用?
在UserMapper
介面中增加一個方法: List<User> findByIds(int[] arr);
public List<User> findByIds(int[] arr);
在UserMapper.xml
中編寫:
<select id="findByIds" parameterType="list" resultType="com.dxh.pojo.User">
SELECT * FROM user
<where>
<foreach collection="array" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
我們可以看到,foreach中我們使用到了5個值:
- collection 這裡就是寫我們傳入的型別,如果是陣列就是
array
,如果是集合就是list
- open 我們之前說到
SELECT * FROM user where id in (1,2,3)
正確的SQL應該這樣寫,那麼open就是填寫我們需要拼接的前半部分 - close 填寫我們需要拼接的後半部分
- item 我們需要遍歷的值是id,所以就填寫id
- separator
......where id in (1,2,3)
1,2,3之間用,
分割。
測試:
@Test
public void test2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int[] arr={1,3};
List<User> byCondition = mapper.findByIds(arr);
for (User user1 : byCondition) {
System.out.println(user1);
}
}
輸出結果:
User{id=1, username='lucy'}
User{id=3, username='zhaowu'}
正確~
最後
這裡只是介紹了兩個經常使用的標籤,mybatis中還有很多標籤,比如choose、when、otherwise、trim、set
等等
值得一說的是Mybatis的官方網站中已經支援中文了,母語看著更舒服~