1. 程式人生 > >【Mybatis】MyBatis之動態SQL(六)

【Mybatis】MyBatis之動態SQL(六)

aslist 當前 public 不能 var int nts email tle

  MyBatis 的強大特性之一便是它的動態 SQL,本章介紹動態 SQL

  查看本章,請先閱讀【Mybatis】MyBatis對表執行CRUD操作(三)。

  本例表結構

1 CREATE TABLE `employee` (
2   `id` int(11) NOT NULL AUTO_INCREMENT,
3   `last_name` varchar(255) DEFAULT NULL,
4   `gender` char(1) DEFAULT NULL,
5   `email` varchar(255) DEFAULT NULL
6   PRIMARY KEY (`id`)
7
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

if

  if標簽:用於邏輯判斷,其中test屬性,填寫的是判斷表達式(OGNL)

  示例

  1、EmployeeMapper新增Sql如下:

 1 <!-- if:判斷 -->
 2 <select id="testConditionIf"
 3     resultType="com.hd.test.pojo.Employee">
 4     select id, last_name lastName, gender from employee
 5     <!-- 
 6
test:判斷表達式(OGNL) OGNL參照PPT或者官方文檔。 7 c:if test 從參數中取值進行判斷 遇見特殊符號應該去寫轉義字符: &&: 8 9 --> 10 where 1 = 1 11 <if test="id != null"> 12 AND id = #{id} 13 </if> 14 <!-- 表達式中,字符串使用‘‘單引號引起來 --> 15 <if test="lastName != null and lastName.trim() != ‘‘"
> 16 AND last_name = #{lastName} 17 </if> 18 <!-- ognl會進行字符串與數字的轉換判斷 "0"==0 --> 19 <if test="gender==0 or gender==1"> 20 AND gender = #{gender} 21 </if> 22 <!-- 轉義字符: &amp;&amp; == && &quot;&quot; == ""--> 23 <if test="email != null &amp;&amp; lastName!=&quot;&quot;"> 24 AND email = #{email} 25 </if> 26 </select>

  2、EmployeeMapper接口中,新增方法

1 public List<Employee> testConditionIf(Employee employee);

  3、測試方法

 1 @Test
 2 public void test001() throws IOException {
 3     
 4     InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
 5     SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 6     
 7     SqlSession session = sessionFactory.openSession();
 8     
 9     try {
10         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
11         List<Employee> list = mapper.testConditionIf(new Employee(null, "0", null));
12         System.out.println(list.size());
13         for (Employee employee : list) {
14             System.out.println(list);
15         }
16     } catch (Exception e) {
17         e.printStackTrace();  
18     } finally {
19         session.close();
20     }
21 }

  4、執行結果

    技術分享圖片

choose

  有時我們不想應用到所有的條件語句,而只想從中擇其一項。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。

  示例

  1、EmployeeMapper新增Sql如下:

 1 <!-- choose -->
 2 <select id="testConditionChoose" resultType="com.hd.test.pojo.Employee">
 3     select id, last_name lastName, gender from employee
 4     where 1 = 1
 5     <choose>
 6         <when test="id != null">
 7             AND id = #{id}
 8         </when>
 9         <when test="lastName != null">
10             AND last_name = #{lastName}
11         </when>
12         <when test="gender != null">
13             AND gender = #{gender}
14         </when>
15         <when test="email != null">
16             AND email = #{email}
17         </when>
18         <otherwise>
19             AND 1 = 1
20         </otherwise>
21     </choose>
22 </select>

  2、EmployeeMapper接口中,新增方法

1 public List<Employee> testConditionChoose(Employee employee);

  3、測試方法  

 1 @Test
 2 public void test002() throws IOException {
 3     
 4     InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
 5     SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 6     
 7     SqlSession session = sessionFactory.openSession();
 8     
 9     try {
10         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
11         List<Employee> list = mapper.testConditionChoose(new Employee(1, null, null, null));
12         System.out.println(list.size());
13         for (Employee employee : list) {
14             System.out.println(list);
15         }
16     } catch (Exception e) {
17         e.printStackTrace();  
18     } finally {
19         session.close();
20     }
21 }

  4、執行結果

    技術分享圖片

where

  where標簽:用於編寫帶where條件的sql,配合if標簽使用,它會自動去除首個AND前綴。

  示例

  1、EmployeeMapper新增Sql如下:

 1 <!-- if + where -->
 2 <select id="testConditionIfWhere"
 3     resultType="com.hd.test.pojo.Employee">
 4     select id, last_name lastName, gender from employee
 5     <where>
 6         <if test="id != null">
 7             AND id = #{id}
 8         </if>
 9         <if test="lastName != null and lastName.trim() != ‘‘">
10             AND last_name = #{lastName}
11         </if>
12         <if test="gender==0 or gender==1">
13             AND gender = #{gender}
14         </if>
15         <if test="email != null &amp;&amp; lastName!=&quot;&quot;">
16             AND email = #{email}
17         </if>
18     </where>
19 </select>

  2、EmployeeMapper接口中,新增方法

1 public List<Employee> testConditionIfWhere(Employee employee);

  3、測試方法

 1 @Test
 2 public void test003() throws IOException {
 3     
 4     InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
 5     SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 6     
 7     SqlSession session = sessionFactory.openSession();
 8     
 9     try {
10         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
11         List<Employee> list = mapper.testConditionIfWhere(new Employee("小紅", "1", null));
12         System.out.println(list.size());
13         for (Employee employee : list) {
14             System.out.println(list);
15         }
16     } catch (Exception e) {
17         e.printStackTrace();  
18     } finally {
19         session.close();
20     }
21 }

  4、執行結果

    技術分享圖片

trim

  trim標簽:可以去掉字符串的首尾字符串,以及在字符串前後添加前後綴

  示例

  1、EmployeeMapper新增Sql如下:

 1 <select id="testConditionIfTrim" resultType="com.hd.test.pojo.Employee">
 2     select id, last_name lastName, gender from employee
 3     <!-- 後面多出的and或者or where標簽不能解決 
 4         prefix="":前綴:trim標簽體中是整個字符串拼串 後的結果。 prefix給拼串後的整個字符串加一個前綴 
 5         prefixOverrides="": 前綴覆蓋: 去掉整個字符串前面多余的字符 
 6         suffix="":後綴 suffix給拼串後的整個字符串加一個後綴 
 7         suffixOverrides="" 後綴覆蓋:去掉整個字符串後面多余的字符 -->
 8     <trim prefix="where" prefixOverrides="AND">
 9         <if test="id != null">
10             AND id = #{id}
11         </if>
12         <if test="lastName != null">
13             AND last_name = #{lastName}
14         </if>
15         <if test="gender != null">
16             AND gender = #{gender}
17         </if>
18         <if test="email != null">
19             AND email = #{email}
20         </if>
21     </trim>
22 </select> 

  2、EmployeeMapper接口中,新增方法

1 public List<Employee> testConditionIfTrim(Employee employee); 

  3、測試方法

 1 @Test
 2 public void test004() throws IOException {
 3     
 4     InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
 5     SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 6     
 7     SqlSession session = sessionFactory.openSession();
 8     
 9     try {
10         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
11         List<Employee> list = mapper.testConditionIfTrim(new Employee(1, null, null, null));
12         System.out.println(list.size());
13         for (Employee employee : list) {
14             System.out.println(list);
15         }
16     } catch (Exception e) {
17         e.printStackTrace();  
18     } finally {
19         session.close();
20     }
21 }

  4、執行結果

    技術分享圖片

    

foreach

  動態 SQL 的另外一個常用的操作需求是對一個集合進行遍歷,通常是在構建 IN 條件語句的時候

  示例

  1、EmployeeMapper新增Sql如下: 

 1 <!-- foreach -->
 2 <select id="testConditionForeach" resultType="com.hd.test.pojo.Employee">
 3     select id, last_name lastName, gender from employee
 4     <!--
 5          collection:指定要遍歷的集合:
 6              list類型的參數會特殊處理封裝在map中,map的key就叫list
 7          item:將當前遍歷出的元素賦值給指定的變量
 8          separator:每個元素之間的分隔符
 9          open:遍歷出所有結果拼接一個開始的字符
10          close:遍歷出所有結果拼接一個結束的字符
11          index:索引。遍歷list的時候是index就是索引,item就是當前值
12                        遍歷map的時候index表示的就是map的key,item就是map的值
13          
14          #{變量名}就能取出變量的值也就是當前遍歷出的元素
15        -->
16     <foreach collection="ids" item="id" separator="," open="where id in (" close=")" >
17         #{id}
18     </foreach>
19 </select>

  2、EmployeeMapper接口中,新增方法

1 public List<Employee> testConditionForeach(@Param("ids")List<Integer> ids);

  3、測試方法

 1 @Test
 2 public void test005() throws IOException {
 3     
 4     InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
 5     SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 6     
 7     SqlSession session = sessionFactory.openSession();
 8     
 9     try {
10         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
11         List<Employee> list = mapper.testConditionForeach(Arrays.asList(1, 2, 3, 4));
12         System.out.println(list.size());
13         for (Employee employee : list) {
14             System.out.println(list);
15         }
16     } catch (Exception e) {
17         e.printStackTrace();  
18     } finally {
19         session.close();
20     }
21 } 

  4、執行結果

    技術分享圖片

set

  set 元素會動態前置 SET 關鍵字,同時也會刪掉無關的逗號,因為用了條件語句之後很可能就會在生成的 SQL 語句的後面留下這些逗號

  示例

  1、EmployeeMapper新增Sql如下: 

 1 <!-- set -->
 2 <update id="testConditionSet">
 3     update employee 
 4     <set>
 5         <if test="lastName != null">
 6             last_name = #{lastName},
 7         </if>
 8         <if test="gender != null">
 9             gender = #{gender},
10         </if>
11         <if test="email != null">
12             email = #{email},
13         </if>
14     </set>
15     where id = #{id}
16 </update> 

  2、EmployeeMapper接口中,新增方法

1 public boolean testConditionSet(Employee employee);

  3、測試方法

 1 @Test
 2 public void test006() throws IOException {
 3     
 4     InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
 5     SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 6     
 7     SqlSession session = sessionFactory.openSession();
 8     
 9     try {
10         EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
11         boolean f = mapper.testConditionSet(new Employee(1, "小白", "1", null));
12         System.out.println(f);
13         session.commit();
14     } catch (Exception e) {
15         e.printStackTrace();  
16     } finally {
17         session.close();
18     }
19 }

  4、執行結果

    技術分享圖片

bind

  bind 元素可以從 OGNL 表達式中創建一個變量並將其綁定到上下文。比如:

1 <select id="testConditionBind" resultType="Blog">
2     <bind name="pattern" value="‘%‘ + keyword + ‘%‘" />
3     SELECT * FROM employee  WHERE last_name LIKE #{pattern}
4 </select>

sql

  可以用來包含其他sql

1 <sql id="selectSql">select id, last_name lastName, gender from employee</sql>
2     
3 <select id="testConditionInclude" resultType="com.hd.test.pojo.Employee">
4     <include refid="selectSql"></include>
5     where id = 1
6 </select>

Mybatis中2個內置參數 _parameter和_databaseId

【Mybatis】MyBatis之動態SQL(六)