1. 程式人生 > >Mybatis框架基礎之動態SQL

Mybatis框架基礎之動態SQL

一、動態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();
	}