六、mybatis动态sql讲解

一、动态sql

使用jdbc或者其他框架,很多时候需要去拼装sql,这是一个麻烦的事情。

        例如:一个多筛选条件的页面,需要根据筛选的条件去查询所符合条件的数据,使用hibernate需要在类中一个个条件的去判断,来选择sql拼装,由于是在类中当新增筛选条件时需要去类中修改并且重新编译方可生效。

        而mybatis提供对sql 语句动态的组装能力,而且它只有几个基本元素,十分简单明了,大量的判断都可以在mybatis的映射xml文件里面配置,以达到许多我们需要大量代码才能实现的功能,大大减少了我们编写代码的工作量,这体现了mybatis的灵活性高度可配置和可维护性。

        mybatis也可以在注解中配置sql,但是由于注解中配置功能受限,对于复杂的sql而言可读性很差,所以使用较少,并且使用注解的方式sql是写在java类中,每次修改都需要编译。



二、mybatis元素介绍与使用

mybatis中有哪些元素?
元素:if 、choose when otherwise 、trim 、foreach 、where 、set 、bind
属性: test

下面就来一 一介绍这些元素的作用

  1. if 元素
    是最常用的元素,用于判断语句,相当于java中的if效果,只不过没有else。它常常与test属性结合在一起使用,可以多个if结合在一起使用。
		
		<select id="queryStudentAll" parameterType="student" resultType="student">
			select * from student
			where 1=1
			
			<if test="stuName != null and stuName != ''">
				and stu_name = #{stuName}
			if>
			<if test="age != null">
					and age > #{age}
			if>
		select>

缺点: 需要手动在动态sql前面写上一个 where 1=1 条件

  1. choose when otherwise
    这个就相当于java中的 switch case 效果一样。当所有条件不满足时需要有一个默认条件
  		
  		<select id="queryStudentChoose" parameterType="student" resultType="student">
  					select * from student where 1=1
  					<choose>
  						<when test="grade != null and grade != ''">
  							and grade = #{grade}
  						when>
  						<when test="email != null and email != '' ">
  						    and email like '%${email}%'
  						when>
  						<otherwise>
  							and id > 2	
  						otherwise>
  					choose>
  		select>
 		

缺点:同 if 需要在前面手动添加一个 where条件。
注:只有一个条件会生效

  1. where 元素
    由于上面的两种元素都需要在前面添加一个默认的where 条件,避免这种情况所有有了where元素,可以结合多种元素一起使用,在where元素内 alt+/ 会有提示

  		<select id="queryStudentWhere" parameterType="student" resultType="student">
			select * from student 
			<where>
					<if test="email != null and email != ''">
						 and email like '%${email}%'
					if>
					<if test="grade != null and grade != ''">
  							and grade = #{grade}
  					if>
			where>
		select>

  1. trim 元素

  		<select id="queryStudentTrim" parameterType="student" resultType="student">
			select * from student 
			<trim prefix="where" prefixOverrides="and" >
					<if test="email != null and email != ''">
						 and email like '%${email}%'
					if>
					<if test="grade != null and grade != ''">
  						 and grade = #{grade}
  					if>
			trim>
		select>

  1. set元素
    这个元素用于更新操作,当然trim也可以完成这个操作
		
		<update id="updateStudentInfo" parameterType="student" >
				update student
				<set>
						<if test="stuName != null and stuName != ''">
								stu_name=#{stuName},
						if>
						<if test="age != null">
								age=#{age},
						if>
						<if test="email != null and email != ''">
								email=#{email},
						if>
						<if test="grade != null and grade != ''">
								grade=#{grade}
						if>
				set>
				where id=#{id}
		update>
		
		

  1. foreach 元素
    用于处理参数是集合、数组类型的数据

		<select id="queryStudentInfoByIn" parameterType="int" resultType="student">
			select * from student where id in
			<foreach collection="list" item="item" index="index" separator="," open="(" close=")">
				#{item}
			foreach>
		select>	

  1. bind 元素
    用于处理参数,为参数添加一些修饰

		<select id="queryStudentInfoByBind" parameterType="student" resultType="student">
			<bind name="pattern" value="'%' + email + '%'"/>
			select * from student where email like #{pattern}
		select>

注意bind标签中参数不是 #{email } 这么取得,直接属性名就可 email

一般不会这么使用bind元素来达到上面的效果,上面主要是用于 拼接 %%

示例一: $ 处理,$不会预编译参数,会直接去参数字面值

					<if test="email != null and email != ''">
						 and email like '%${email}%'
					if>

如下日志,发现并没有为email参数占位符? ,而是直接取值拼装
2019-07-31 15:53:46 DEBUG mybatis.sql.com.cjy.mybatis.dao.StudentMapper.queryStudentWhere - ==>  Preparing: select * from student WHERE email like '%xiaoming%' and grade = ? 

示例二: || 拼接

		 <select id="queryPersonByIdAndLikeNames" resultMap="baseResult" >
		 		select <include refid="baseColumns"/>
		 		from person where id = #{id} and user_name like '%' || #{userName}
		 select>

示例三:使用concat函数处理

					<if test="email != null and email != ''">
						 and email like concat('%' ,#{email} ,'%')
					if>

注意:上面几种拼接sql %% 的方式需要注意使用的数据库。


优势:当一张表有特别多的字段时,我们只需要更新其中的某几个字段,使用hibernate框架的话由于映射关系会更新所有字段。
mybatis就不一样,有了动态sql的拼接,只需要更新其中满足条件的值即可。

demo地址 : https://github.com/chenjy512/mybatis-demo/tree/master/source-mybatis-05dynamic_SQL

你可能感兴趣的:(mybatis)