[Mybatis] Dynamic SQL

Dynamic SQL is one of the very important and powerful functions of mybatis . We write sql ourselves and want to transform different SQL according to the different conditions passed in . When we spell SQL by ourselves, we should pay attention to whether there are more or less symbols and so on. Problems, or complex queries containing various judgments, are more troublesome.


Mybatis provides dynamic SQL tags written in SQL statements, and mybatis uses these tags to provide powerful dynamic SQL functions.

 

1. The if tag is used to judge whether the parameter value is empty, and the test attribute value conforms to the OGNL judgment expression


<select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
    select * from tbl_employee
	<where>
	<!--The parameter is String--!>
	<if test="id!=null">
		id=#{id}
	</if>
	<!-- ognl will convert strings and numbers to judge "0"==0 -->
	<if test="gender==0 or gender==1">
		and gender=#{gender}
	</if>
	<!--The parameter is pojo--!>
	<if test="employee.lastName == null or employee.lastName ='' ">
		and employee.lastName=#{lastname}
	</if>
	</where>		  
</select>

2. where tag, query condition, the main function is to simplify the writing of where condition judgment in SQL statement



<select id="getEmpsByconditionIf" resultType="com.atguigu.mybatis.bean.Employee">
	select * from tbl_employee
	<where>
	<if test="id!=null">
		id=#{id}
	</if>
	<if test="lastName!=null && lastName!=""">
		and last_name like #{lastName}
	</if>
	<if test="email!=null and email.trim()!=''">
		and email=#{email}
	</if>
	<!-- ognl will convert strings and numbers to judge "0"==0 -->
	<if test="gender==0 or gender==1">
		and gender=#{gender}
	</if>
	</where>  
</select> 


如果id为空,就判断lastName,如果where标签里的if全不成立,则不走where语句。

如果id为空,其他值不为空,打印出的SQL

select * fromtbl_employee WHERE last_name like ? and email=? and gender=?



where标签会自动将第一个条件后的and或者or忽略



3.trim标签自定义字符串截取。trim标签中是整个字符串拼串后的结果


trim4个属性:

prefix="":前缀:prefix给拼串后的整个字符串加一个前缀

prefixOverrides="":前缀覆盖:去掉整个字符串前边多余的字符

suffix="":后缀:给拼串后的整个字符串加一个后缀

suffixOverrides="":后缀覆盖:去掉整个字符串后边多余的字符


<select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
			select * from tbl_employee
			<!-- 后面多出的and或者or where标签不能解决 -->
			<!-- 自定义字符串的截取规则 -->
		<trim prefix="where" suffixOverrides="and">
			<if test="id!=null">
				id=#{id} and
			</if>
			<if test="lastName!=null && lastName!=""">
				last_name like #{lastName} and
			</if>
			<if test="email!=null and email.trim()!=''">
				email=#{email} and
			</if>
			<!-- ognl会进行字符串与数字的转换判断 "0"==0 -->
			<if test="gender==0 or gender==1">
				gender=#{gender}
			</if>
		</trim>

</select>


这样打印出来就会把条件后的and去掉

控制台打印结果:select * from tbl_employee where last_namelike ? and email=? and gender=?  

 


4.choose标签分支选择,从多个选项中选择一个。


choose标签按顺序判断内部when标签中的test条件是否成立,有一个成立,则choose结束。



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

测试方法:


public SqlSessionFactory getSqlSesssionFactory() throws IOException {
	String resource = "mybatis-config.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);
	return new SqlSessionFactoryBuilder().build(inputStream);
}
public void test07() throws IOException{
		
		SqlSessionFactory sqlSesssionFactory = getSqlSesssionFactory();
		SqlSession openSession = sqlSesssionFactory.openSession();
		try {
			EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
			Employee employee = new Employee(null,"letty","[email protected]","0");
			//测试choose
			List<Employee> getEmpsByConditionChoose= mapper.getEmpsByConditionChoose(employee);
			for (Employee emp : getEmpsByConditionChoose) {
				System.out.println(emp);
			}
			openSession.commit();
		} finally {
			openSession.close();
		}
	}


控制台打印信息:




5.set标签,与if结合的动态更新


<update id="updateEmp">
		update tbl_employee
		<!-- set标签的使用 -->
		<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>

set标签会自动把最后一个条件赋值语句后的逗号去掉,也就是gender=#{gender},后的逗号


控制台打印信息:



6.foreach标签遍历集合


foreach标签属性:


collection:指定要遍历的集合:

list类型的参数会特殊处理封装在map中,map的key就叫list

item:将当前遍历出的元素赋值给指定的变量

separator:元素之间的分隔符

open:遍历出所有结果拼接成一个开始的字符

close:遍历出所有结果拼接一个结束的字符

index:索引,遍历list的时候是索引

 遍历map的时候index表示的就map的key,item就的map的值

#{变量名}就能取出变量的值也就是当前遍历出的元素


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

测试方法:


@Test
public void test07() throws IOException{
	
	SqlSessionFactory sqlSesssionFactory = getSqlSesssionFactory();
	SqlSession openSession = sqlSesssionFactory.openSession();
	try {
		EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
		List<Employee> empsByConditionForeach=mapper.getEmpsByConditionForeach(Arrays.asList(1,2));
		for (Employee emp : empsByConditionForeach) {
			System.out.println(emp);
		}
	} finally {
		openSession.close();
	}
}


控制台信息:





7.foreach标签,mysql下foreach批量插入的两种方式


1


<!-- Mysql下批量保存,可以foreach遍历,mysql支持values(),(),()语法 -->
		<insert id="addEmps">
			INSERT INTO tbl_employee (
				last_name,
				email,
				gender,
				d_id
			)
			VALUES
			<foreach collection="emps" item="emp" separator=",">
				(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
			</foreach>
	
		</insert>


2


<!-- 这种方式需要数据库连接属性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>


测试方法:


@Test
public void testBatchSave() throws IOException {
	SqlSessionFactory sqlSesssionFactory = getSqlSesssionFactory();
	SqlSession openSession = sqlSesssionFactory.openSession();
	try {
		EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
		List<Employee> emps =new ArrayList<>();
		emps.add(new Employee(null,"zazh1","[email protected]","1",new Department(1)));
		emps.add(new Employee(null,"zzen1","[email protected]","1",new Department(2)));

		mapper.addEmps(emps);
		openSession.commit();
	} finally {
		// TODO: handle finally clause
	}
}


控制台信息:


INSERT INTOtbl_employee ( last_name, email, gender, d_id )VALUES(?,?,?,?) ; INSERT INTOtbl_employee ( last_name, email, gender, d_id )VALUES(?,?,?,?);








Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325727661&siteId=291194637