• Mybatis学习笔记6:动态sql


    1、简介、环境搭建


    2、if判断&ONGL

    <!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 -->
    	 <!-- 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>
    

    3、where查询条件

    如果第一个查询条件为空,第一个and就会报错,这是的处理解决方案
    方案1:加上where 1=1

    方案2:mybatis推荐的where标签

    <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拼装会有问题
    //1、给where后面加上1=1,以后的条件都and xxx.
    //2、mybatis使用where标签来将所有的查询条件包括在内。mybatis就会将where标签中拼装的sql,多出来的and或者or去掉
    //where只会去掉第一个多出来的and或者or。
    所以用where的话一定要把and放在前面
    变换一下形式,where只会去掉第一个多出来的and或者or。这样还会出问题

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

    5、choose(when,otherwise)分支标签

    • choose (when, otherwise):分支选择;带了break的swtich-case
    	如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个
    
    <!-- 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>
    

    6、set与if结合

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

    7、foreach遍历集合

     <!--public List<Employee> getEmpsByConditionForeach(List<Integer> ids);  -->
    	 <select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee">
    	 	select * from tbl_employee
    	 	<!--
    	 		collection:指定要遍历的集合:
    	 			list类型的参数会特殊处理封装在map中,map的key就叫list
    	 		item:将当前遍历出的元素赋值给指定的变量
    	 		separator:每个元素之间的分隔符
    	 		open:遍历出所有结果拼接一个开始的字符
    	 		close:遍历出所有结果拼接一个结束的字符
    	 		index:索引。遍历list的时候是index就是索引,item就是当前值
    	 				      遍历map的时候index表示的就是map的key,item就是map的值
    	 		
    	 		#{变量名}就能取出变量的值也就是当前遍历出的元素
    	 	  -->
    	 	<foreach collection="ids" item="item_id" separator=","
    	 		open="where id in(" close=")">
    	 		#{item_id}
    	 	</foreach>
    	 </select>
    

    8、foreach批量插入








     <!-- 批量保存 -->
    	 <!--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;
    	 	这种分号分隔多个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> -->
    

    9、oracel批量插入、保存

     <!-- Oracle数据库批量保存: 
    	 	Oracle不支持values(),(),()
    	 	Oracle支持的批量方式
    	 	1、多个insert放在begin - end里面
    	 		begin
    			    insert into employees(employee_id,last_name,email) 
    			    values(employees_seq.nextval,'test_001','test_001@atguigu.com');
    			    insert into employees(employee_id,last_name,email) 
    			    values(employees_seq.nextval,'test_002','test_002@atguigu.com');
    			end;
    		2、利用中间表:
    			insert into employees(employee_id,last_name,email)
    		       select employees_seq.nextval,lastName,email from(
    		              select 'test_a_01' lastName,'test_a_e01' email from dual
    		              union
    		              select 'test_a_02' lastName,'test_a_e02' email from dual
    		              union
    		              select 'test_a_03' lastName,'test_a_e03' email from dual
    		       )	
    	 -->
    	 <insert id="addEmps" databaseId="oracle">
    	 	<!-- oracle第一种批量方式 -->
    	 	<!-- <foreach collection="emps" item="emp" open="begin" close="end;">
    	 		insert into employees(employee_id,last_name,email) 
    			    values(employees_seq.nextval,#{emp.lastName},#{emp.email});
    	 	</foreach> -->
    	 	
    	 	<!-- oracle第二种批量方式  -->
    	 	insert into employees(
    	 		<!-- 引用外部定义的sql -->
    	 		<include refid="insertColumn">
    	 			<property name="testColomn" value="abc"/>
    	 		</include>
    	 	)
    	 			<foreach collection="emps" item="emp" separator="union"
    	 				open="select employees_seq.nextval,lastName,email from("
    	 				close=")">
    	 				select #{emp.lastName} lastName,#{emp.email} email from dual
    	 			</foreach>
    	 </insert>
    

    10、内置参数 parameter&databaseid &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>
    

    推荐传递,不推荐bind

    11、抽取可重用sql片段

    <!-- 
    	  	抽取可重用的sql片段。方便后面引用 
    	  	1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
    	  	2、include来引用已经抽取的sql:
    	  	3、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>
    



  • 相关阅读:
    MySQL如何监测是否命中索引? mysql执行计划解读
    mysql修改用户密码的方法及命令
    php7 安装rabbitmq 扩展 amqp扩展
    HAProxy的高级配置选项-Web服务器状态监测
    HAProxy 配置SSL
    nginx request_body 为空 没有参数 ;关于client_max_body_size client_body_buffer_size配置
    mysql 存储过程 函数的 导入导出
    postman设置客户端证书
    python字符串和列表之间相互转换
    python 发邮件 带附件 给多人发邮件
  • 原文地址:https://www.cnblogs.com/xidianzxm/p/12444695.html
Copyright © 2020-2023  润新知