1. 程式人生 > 其它 >Mybatis之動態SQL語法詳解

Mybatis之動態SQL語法詳解

技術標籤:mybatis

Mybatis動態SQL

​ 1、sql_if & sql_where 判斷&OGNL表示式

	 <!-- 查詢員工,要求,攜帶了哪個欄位查詢條件就帶上這個欄位的值 -->
	 <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
	 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
	 	select * from tbl_employee
	 	<!-- where-->  
	 	<where>
		 	<!-- test:判斷表示式(OGNL),從引數中取值進行判斷,遇見特殊符號應該去寫轉義字元-->
		 	<if test="id!=null">
		 		id=#{id}
		 	</if>
            										<!--"&quot;&quot":轉義符號表示空值-->
		 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
		 		and last_name like #{lastName}
		 	</if>
		 	<if test="email!=null and email.trim()!=&quot;&quot;">
		 		and email=#{email}
		 	</if> 
		 	<!-- ognl會進行字串與數字的轉換判斷  "0"==0 -->
		 	<if test="gender==0 or gender==1">
		 	 	and gender=#{gender}
		 	</if>
	 	</where>
	 </select>

2、sql_trim自定義字串擷取(用的不多,根據需求選擇)

 <!--public List<Employee> getEmpsByConditionTrim(Employee employee);  -->
	 <select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
	 	select * from tbl_employee
	 	<!-- 後面多出的and或者or where標籤不能解決 
	 	prefix="":字首:trim標籤體中是整個字串拼串 後的結果。
	 			prefix給拼串後的整個字串加一個字首 
	 	prefixOverrides="":
	 			字首覆蓋: 去掉整個字串前面多餘的字元
	 	suffix="":字尾
	 			suffix給拼串後的整個字串加一個字尾 
	 	suffixOverrides=""
	 			字尾覆蓋:去掉整個字串後面多餘的字元
	 			
	 	-->
	 	<!-- 自定義字串的擷取規則 -->
	 	<trim prefix="where" suffixOverrides="and">
	 		<if test="id!=null">
		 		id=#{id} and
		 	</if>
		 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
		 		last_name like #{lastName} and
		 	</if>
		 	<if test="email!=null and email.trim()!=&quot;&quot;">
		 		email=#{email} and
		 	</if> 
		 	<!-- ognl會進行字串與數字的轉換判斷  "0"==0 -->
		 	<if test="gender==0 or gender==1">
		 	 	gender=#{gender}
		 	</if>
		 </trim>
	 </select>

3、sql_choose分支選擇

	 <!-- public List<Employee> getEmpsByConditionChoose(Employee employee); -->
	 <select id="getEmpsByConditionChoose" resultType="com.atguigu.mybatis.bean.Employee">
	 	select * from tbl_employee 
	 	<where>
	 		<!-- 如果帶了id就用id查,如果帶了lastName就用lastName查;只會進入其中一個!! -->
	 		<choose>
	 			<when test="id!=null">
	 				id=#{id}
	 			</when>
	 			<when test="lastName!=null">
	 				last_name like #{lastName}
	 			</when>
	 			<when test="email!=null">
	 				email = #{email}
	 			</when>
	 			<otherwise>
	 				gender = 0
	 			</otherwise>
	 		</choose>
	 	</where>
	 </select>

​ 4、sql_set與if結合的動態更新

	 <!--public void updateEmp(Employee employee);  -->
<!-- 方式一:Set標籤的使用 -->
	 <update id="updateEmp">
	 	update tbl_employee 
		<set>
			<if test="lastName!=null">
				last_name=#{lastName},
			</if>
			<if test="email!=null">
				email=#{email},
			</if>
			<if test="gender!=null">
				gender=#{gender}
			</if>
		</set>
		where id=#{id} 
      </update>
<!--方式二:Trim:更新拼串-->
	<update id="updateEmp">
		update tbl_employee 
     <!--
		prefix="":字首:trim標籤體中是整個字串拼串 後的結果。
	 			prefix給拼串後的整個字串加一個字首 
	 	suffixOverrides=""
	 			字尾覆蓋:去掉整個字串後面多餘的字元
		-->
		<trim prefix="set" suffixOverrides=",">
			<if test="lastName!=null">
				last_name=#{lastName},
			</if>
			<if test="email!=null">
				email=#{email},
			</if>
			<if test="gender!=null">
				gender=#{gender}
			</if>
		</trim>
		where id=#{id} 
	 </update>

6、MySQL下批量儲存的兩種方式

 <!-- 批量儲存 -->
	 <!--public void addEmps(@Param("emps")List<Employee> emps);  -->
	 <!--MySQL下批量儲存:可以foreach遍歷   mysql支援values(),(),()語法-->
	<insert id="addEmps">
	 	insert into tbl_employee(
	 		<include refid="insertColumn"></include>
	 	) 
		values
		<foreach collection="emps" item="emp" separator=",">
			(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
		</foreach>
	 </insert>
	 
	 <!-- 這種方式需要資料庫連線屬性allowMultiQueries=true;
		如:jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true
	 	這種分號分隔多個sql可以用於其他的批量操作(刪除,修改) -->
	 <insert id="addEmps">
	 	<foreach collection="emps" item="emp" separator=";">
	 		insert into tbl_employee(last_name,email,gender,d_id)
	 		values(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
	 	</foreach>
	 </insert> 

7、sql_內建引數 _parameter&_databaseld 與 bind繫結

<!-- 兩個內建引數:
	 	不只是方法傳遞過來的引數可以被用來判斷,取值。。。
	 	mybatis預設還有兩個內建引數:
	 	_parameter:代表整個引數
	 		單個引數:_parameter就是這個引數
	 		多個引數:引數會被封裝為一個map;_parameter就是代表這個map
	 	
	 	_databaseId:如果配置了databaseIdProvider標籤。
	 		_databaseId就是代表當前資料庫的別名oracle
	  -->
	  
	  <!--public List<Employee> getEmpsTestInnerParameter(Employee employee);  -->
	  <select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
	  		<!-- bind:可以將OGNL表示式的值繫結到一個變數中,方便後來引用這個變數的值 -->
	  		<!--<bind name="_lastName" value="'%'+lastName+'%'"/>不推薦使用,可以在傳值的時候直接附上%,那樣也比較靈活!-->
	  		<if test="_databaseId=='mysql'">
	  			select * from tbl_employee
	  			<if test="_parameter!=null">
	  				where last_name like #{lastName}
	  			</if>
	  		</if>
	  		<if test="_databaseId=='oracle'">
	  			select * from employees
	  			<if test="_parameter!=null">
	  				where last_name like #{_parameter.lastName}
	  			</if>
	  		</if>
	  </select>

8、sql抽取可重用的sql片段

<!-- 
	  	抽取可重用的sql片段。方便後面引用 
	  	1、sql抽取:經常將要查詢的列名,或者插入用的列名抽取出來方便引用
	  	2、include來引用已經抽取的sql:
	  	3、include還可以自定義一些property,sql標籤內部就能使用自定義的屬性
	  			include-property:取值的正確方式${prop},
	  			#{不能使用這種方式}
	  -->
	<insert id="addEmps">
       <!--insert into tbl_employee(last_name,email,gender,d_id)-->
	 	insert into tbl_employee(
	 		<include refid="insertColumn"></include><!--這裡可以引用下面的sql片段-->
	 	) 
		values
		<foreach collection="emps" item="emp" separator=",">
			(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
		</foreach>
	 </insert>

	  <sql id="insertColumn">
	  		<if test="_databaseId=='oracle'">
	  			employee_id,last_name,email
	  		</if>
	  		<if test="_databaseId=='mysql'">
	  			last_name,email,gender,d_id
	  		</if>
	  </sql>