【Mybatis】DynamicSQL

if 判斷

if標籤裏的test 是判斷傳入的參數java

和where標籤結合

where 標籤能夠自動把前面的and給去除mysql

<!-- 查詢員工,要求,攜帶了哪一個字段查詢條件就帶上這個字段的值 -->
	 <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
	 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
	 	select * from tbl_employee
	 	<!-- where -->
	 	<where>
		 	<!-- test:判斷表達式(OGNL) OGNL參照PPT或者官方文檔。 c:if test 從參數中取值進行判斷 碰見特殊符號應該去寫轉義字符: &&: -->
		 	<if test="id!=null">
		 		id=#{id}
		 	</if>
		 	<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>

查詢:sql

Employee employee = new Employee(null, "Admin", null, null);

查詢的時候若是某些條件沒帶可能sql拼裝會有問題(好比第一個id沒有就會多一個and),解決辦法:
一、給where後面加上1=1,之後的條件都and xxx.
二、mybatis使用where標籤來將全部的查詢條件包括在內。
mybatis就會將where標籤中拼裝的sql,多出來的and或者or去掉
可是where只會去掉第一個多出來的and或者or。



數據庫

和set標籤結合

更新操做 可能會多, 放進set標籤 set就會解決mybatis

<!--public void updateEmp(Employee employee); -->
	 <update id="updateEmp">
	 	<!-- Set標籤的使用 -->
	 	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 字符串截取

trim 代替where

  1. where標籤只能解決前面多出來的and,若是咱們把 and都寫後面,就要用到trim標籤代替where標籤oracle

  2. trim的屬性:app

    • prefix="":前綴:trim標籤體中是整個字符串拼串 後的結果。
      prefix給拼串後的整個字符串加一個前綴
    • prefixOverrides="":
      前綴覆蓋: 去掉整個字符串前面多餘的字符
    • suffix="":後綴
      suffix給拼串後的整個字符串加一個後綴
    • suffixOverrides=""
      後綴覆蓋:去掉整個字符串後面多餘的字符

    經過這些屬性咱們就能夠自定義字符串的截取規則ide

  3. 查詢員工,要求,攜帶了哪一個字段查詢條件就帶上這個字段的值測試

    <!--public List<Employee> getEmpsByConditionTrim(Employee employee); -->
    	 <select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
    	 	select * from tbl_employee
    	 	<!-- 自定義字符串的截取規則 -->
    	 	<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>

trim代替set

<!-- Trim:更新拼串-->
			update tbl_employee 
			<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>

choose(when,otherwise) 分支選擇

需求:若是帶了id就用id查,若是帶了lastName就用lastName查;只會進入其中一個ui

<!-- 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>

foreach

集合遍歷

collection:指定要遍歷的集合: (在接口中定義方法時入參加上@param(「ids」) 能夠 指定遍歷集合的名字,這樣collection 就能夠直接寫這個註解指定的名字了)

  • list類型的參數會特殊處理封裝在map中,map的key就叫list

  • item:將當前遍歷出的元素賦值給指定的變量

  • separator:每一個元素之間的分隔符

  • open:遍歷出全部結果拼接一個開始的字符

  • close:遍歷出全部結果拼接一個結束的字符

  • index:索引。
    遍歷list的時候是index就是索引,item就是當前值
    遍歷map的時候index表示的就是map的key,item就是map的值

  • #{變量名}就能取出變量的值也就是當前遍歷出的元素
    xml文件

<!--public List<Employee> getEmpsByConditionForeach(@param("ids")List<Integer> ids); -->
	 <select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee">
	 	select * from tbl_employee
	 	<foreach collection="ids" item="item_id" separator="," open="where id in(" close=")">
	 		#{item_id}
	 	</foreach>
	 </select>

測試的java代碼

List<Employee> list = mapper.getEmpsByConditionForeach(Arrays.asList(1,2));
			for (Employee emp : list) { 
				System.out.println(emp);
			}

批量保存

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>

測試代碼:

@Test
	public void testBatchSave() throws IOException{ 
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		try{ 
			EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
			List<Employee> emps = new ArrayList<>();
			emps.add(new Employee(null, "smith0x1", "smith0x1@atguigu.com", "1",new Department(1)));
			emps.add(new Employee(null, "allen0x1", "allen0x1@atguigu.com", "0",new Department(1)));
			mapper.addEmps(emps);
			openSession.commit();
		}finally{ 
			openSession.close();
		}
	}

內置參數

兩個內置參數:
不僅是方法傳遞過來的參數能夠被用來判斷,取值。。。
mybatis默認還有兩個內置參數:

  1. _parameter:表明整個參數
    單個參數:_parameter就是這個參數
    多個參數:參數會被封裝爲一個map;_parameter就是表明這個map

  2. _databaseId:若是配置了databaseIdProvider標籤。
    _databaseId就是表明當前數據庫的別名oracle

<!--public List<Employee> getEmpsTestInnerParameter(Employee employee); -->
	  <select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">

	  		<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>

bind 綁定

<!-- bind:能夠將OGNL表達式的值綁定到一個變量中,方便後來引用這個變量的值 -->
	  		<bind name="_lastName" value="'%'+lastName+'%'"/>

sql標籤 抽取可重用的sql片斷

sql標籤抽取可重用的sql片斷。方便後面引用
一、sql抽取:常常將要查詢的列名,或者插入用的列名抽取出來方便引用
二、include來引用已經抽取的sql:
三、include還能夠自定義一些property,sql標籤內部就能使用自定義的屬性
include-property:取值的正確方式${prop},
#{不能使用這種方式}




<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>

用這個sql字段

<insert id="addEmps">
	 	insert into tbl_employee(
	 		<include refid="insertColumn">
			 <property name="testColomn" value="abc"/>
			 </include>
	 	) 
		values
		<foreach collection="emps" item="emp" separator=",">
			(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
		</foreach>
	 </insert>
相關文章
相關標籤/搜索