Mybatis框架基礎之動態SQL
阿新 • • 發佈:2019-01-23
一、動態SQL
動態SQL標籤
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
1、if 根據條件包含 where 子句的一部分。根據條件判斷是否拼接值where語句中作為查詢條件。
<!-- 傳遞pojo綜合查詢使用者資訊 --> <select id="findUserList" parameterType="user" resultType="user"> select * from user where 1=1 <if test="id!=null"> and id=#{id} </if> <if test="username!=null and username!=''"> and username like '%${username}%' </if> </select>
2、choose (when, otherwise)
有時我們不想應用到所有的條件語句,而只想從中擇其一項。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。還是上面的例子,但是這次變為提供了“title”就按“title”查詢,提供了“author”就按“author”查詢的情形,若兩者都沒有提供,就返回所有符合條件的 BLOG(實際情況可能是由管理員按一定策略選出 BLOG 列表,而不是返回大量無意義的隨機結果)。
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>
3、trim (where, set) 如果查詢結果為空,那麼就慘了。所有可採用一下這種方式來避免查詢結果,去掉字首與字尾
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <trim prefix="WHERE" prefixOverrides="AND |OR "> <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </trim> </select> <update id="updateAuthorIfNecessary"> update Author <trim prefix="SET" suffixOverrides=","> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </trim> where id=#{id} </update>
4、 foreach
動態 SQL 的另外一個常用的操作需求是對一個集合進行遍歷,通常是在構建 IN 條件語句的時候。foreach 元素的功能非常強大,它允許你指定一個集合,宣告可以在元素體內使用的集合項(item)和索引(index)變數。它也允許你指定開頭與結尾的字串以及在迭代結果之間放置分隔符。這個元素是很智慧的,因此它不會偶然地附加多餘的分隔符。
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
5、其它指令:把共有的sql片段提取出來,以便更多方法公用。
二、關聯查詢
1、mapper.xml
<!-- 一對一:自動對映 -->
<select id="findOrdersByList" resultType="cn.study.pojo.CustomOrders">
select a.*, b.id uid, username, birthday, sex, address
from orders a, user b
where a.user_id = b.id
</select>
<!-- 一對一:手動對映 -->
<!--
id:resultMap的唯一標識
type:將查詢出的資料放入這個指定的物件中
注意:手動對映需要指定資料庫中表的欄位名與java中pojo類的屬性名稱的對應關係
-->
<resultMap type="cn.study.pojo.Orders" id="orderAndUserResultMap">
<!-- id標籤指定主鍵欄位對應關係
column:列,資料庫中的欄位名稱
property:屬性,java中pojo中的屬性名稱
-->
<id column="id" property="id"/>
<!-- result:標籤指定非主鍵欄位的對應關係 -->
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 這個標籤指定單個物件的對應關係
property:指定將資料放入Orders中的user屬性中
javaType:user屬性的型別
-->
<association property="user" javaType="cn.study.pojo.User">
<id column="uid" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersAsUser" resultMap="orderAndUserResultMap">
select a.*, b.id uid, username, birthday, sex, address
from orders a, user b
where a.user_id = b.id
</select>
<resultMap type="cn.study.pojo.User" id="userAndOrdersResultMap">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!-- 指定對應的集合物件關係對映
property:將資料放入User物件中的ordersList屬性中
ofType:指定ordersList屬性的泛型型別
-->
<collection property="ordersList" ofType="cn.study.pojo.Orders">
<id column="oid" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
</collection>
</resultMap>
<select id="findUserAndOrders" resultMap="userAndOrdersResultMap">
select a.*, b.id oid ,user_id, number, createtime
from user a, orders b where a.id = b.user_id
</select>
2、介面檔案
public List<CustomOrders> findOrdersByList();
public List<Orders> findOrdersAsUser();
public List<User> findUserAndOrders();
3、測試類
@Test
public void findOrdersByList(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<CustomOrders> list = mapper.findOrdersByList();
System.out.println(list.toString());
session.close();
}
@Test
public void findOrdersAsUser(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<Orders> list = mapper.findOrdersAsUser();
System.out.println(list.toString());
session.close();
}
@Test
public void findUserAndOrders(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findUserAndOrders();
System.out.println(list.toString());
session.close();
}