SSM笔记-动态SQL

本文详细介绍了MyBatis中的动态SQL标签,包括if、where、trim、choose、set、foreach、内置参数、bind和sql标签的使用方法和注意事项,帮助理解如何在SQL语句中灵活构建查询条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、if标签
1)使用<if test="">标签,其中test的值就是判断的语句,要使用OGNL写
2)<if test=""></if>中间写需要动态设置的sql,如:<if test="id!=null">id=#{id}</if>,其中#{id}的id和test里面用到的id是从参数中获取的(test里面的id不用写#{XX}来获取)
3)遇到特殊符号要改用转义字符,如:&&可以用&amp;&amp;代替,也可以用and代替,但是''只能用&quot;&quot;代替或者直接用
4)在OGNL语句中可以:
①访问对象属性
②调用方法 (如:类方法、java原生的方法)
③调用静态属性/方法
④调用构造方法
⑤使用运算符
⑥使用逻辑运算符
5)OGNL会自动进行字符串和数字的转换判断
6)<if test=""></if>中间的sql使用like条件的时候不支持在sql里面写%%,应该在传入值的时候设置好,不然sql就会变成 select * from info where id=数值 and name like '%' 数值 '%';

2、where标签
1)作用:当sql上一个条件不存在,而下一个条件有and或者or开头的时候会出错,这个时候可以使用where标签来动态地去掉sql中没用的and或者or
2)用法:使用<where>标签包着需要动态去掉没用and或者or的标签和语句
3)注意:<where>标签只会处理语句前面的and或者or,而不去处理后面的and或者or

3、trim标签(平常用的不多)
1)作用:解决where标签中,每个条件后面多出来的and或者or,或者用于自定义字符串截取
2)注意:不能跟where标签一起用
3)用法:<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
①prefix :前缀,给整个需要拼接的字符串后面添加一个前缀(如: sql的条件语句前面加一个where)
②prefixOverrides:前缀覆盖,去掉整个字符串前面多余的字符(如:去掉sql的条件语句前面的and或者or)
③suffix :后缀,给拼接字符串后的整个字符串加一个后缀(如:每个sql的条件语句后面加一个and或者or)
④suffixOverrides:后缀覆盖,去掉整个字符串后面多余的字符串(如:去掉sql的条件语句后面的and或者or)

4、choose标签
1)作用:类似java中的if(){}else if(){}else{},满足条件的话就使用条件内的东西
2)用法:
<when>标签 :相当于if或者else if
<otherwise>标签 :相当于else
③同一个choose标签里面使用的时候就相当于if(){}else if(){}else{}
3)注意:是在动态给sql添加搜索条件的时候用的

5、set标签
1)作用:当sql使用set关键字的时候可以用这个标签代替,会自动替换掉语句后面无用的逗号
2)用法:使用更新语句时,使用set标签包着需要更新的字段语句即可
3)注意:
①只会替换语句后面多余的逗号
②更新之后记得要提交,不然mybatis会执行回滚操作(即:SqlSession.commit())

6、foreach标签
1)作用:在需要批量操作的时候可以用foreach来告诉mybatis需要拼接的参数值是什么
2)用法:
①在接口类的方法里面使用@Param指定该数组类型的数据的属性名
②在mapper配置文件中使用foreach标签
③调用测试
3)注意:要在接口类的方法的入参里面制定该数组类型数据的属性名
4)标签的属性对应作用:
①collection :指定需要便利的集合(接口类的接口方法@Param修饰的入参)
②item :将当前遍历出来的元素赋值给使用item指定的变量中(下面的sql字段可以直接使用#{item指定的属性名}来获取对应的值)
③separator :元素之间的分隔符(搜索的时候需要用逗号,所以这里写逗号)
④open :指定遍历最终结果字符串的开头的字符串(只要是需要拼接的字符串前面的内容都可以写进去)
⑤close :指定遍历最终结果字符串的结尾的字符串(只要是需要拼接的字符串后面的内容都可以写进去)

7、内置参数
1)mybatis默认的两个内置参数,可以在mapper配置文件中当做已有参数来使用
2)_parameter :代表整个参数,即mapper方法的入参,可以是单个数据,可以是一个参数集合
3)_databaseId :如果在全局mybatis配置中有配置databaseIdProvider标签,_databaseId代表的是数据库的别名

8、bind标签
1)作用:使用该标签在mapper配置文件的语句中,绑定OGNL表达式的值到某个变量中(如:模糊搜索时,like后面的值前后需要加百分号,这个时候就使用bind标签定义新的模糊搜索条件值)
2)用法:在<select><update><insert><delete>标签里面使用<bind>标签,其中name的值为修改后赋值给sql语句使用的参数名,value为需要的对应参数的OGNL表达式的值

9、sql标签
1)作用:把比较繁杂而且能重用的部分sql语句使用该标签单独定义,在需要重用的地方调用,以达到sql片段重用的效果
2)用法:在mapper配置文件中使用<sql>标签定义需要重复使用的sql片段,在需要使用的地方使用<include>标签调用指定的<sql>标签值,以达到sql重用的效果

10、mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<properties resource="dbConfig.properties"></properties>
	
	<settings>
		<setting name="logImpl" value="STDOUT_LOGGING" />
	</settings>
	
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	
	<databaseIdProvider type="DB_VENDOR">
		<property name="MySQL" value="mysql"/>
	</databaseIdProvider>
	
	<mappers>
		<mapper resource="InfoMapper.xml" />
	</mappers>
</configuration>

11、InfoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.ssmtest.InfoMapper">
	<select id="getByConditionIFWHERE"  resultType="com.demo.ssmtest.Info">
		select * from info
		<where>
			<if test="id!=null">
				id=#{id}
			</if>
			<if test="name!=null and name!=''">
				and name like #{name}
			</if>
			<if test="password!=null and password.trim()!=''">
				and password like #{password}
			</if>
			<if test="description!=null &amp;&amp; description.trim()!=&quot;&quot;">
				and description like #{description}
			</if>
			<if test="detailId==1 or detailId==2">
				and detailId=#{detailId}
			</if>
		</where>
	</select>
	<select id="getByConditionCHOOSE"  resultType="com.demo.ssmtest.Info">
		select * from info
		<where>
			<choose>
				<when test="id!=null">
					id=#{id}
				</when>
				<when test="name!=null and name!=''">
					name like #{name}
				</when>
				<otherwise>
					detailId=#{detailId}
				</otherwise>
			</choose>
		</where>
	</select>
	<update id="updateById">
		update info
		<set>
			<if test="name!=null and name!=''">
				name=#{name},
			</if>
			<if test="password!=null and password.trim()!=''">
				password=#{password},
			</if>
			<if test="description!=null &amp;&amp; description.trim()!=&quot;&quot;">
				description=#{description},
			</if>
			<if test="detailId==1 or detailId==2">
				detailId=#{detailId}
			</if>
		</set>
		where id=#{id}
	</update>
	<select id="getEmpsByConditionForeach"  resultType="com.demo.ssmtest.Info">
		select * from info
		<foreach collection="ids" item="loop_id" separator="," open="where id in(" close=")">
			#{loop_id}
		</foreach>
	</select>
	<select id="getByInnerParameter"  resultType="com.demo.ssmtest.Info">
		<if test="_databaseId=='mysql'">
			select * from info
			<where>
				<if test="_parameter!=null">
					<if test="id!=null">
						id=#{id}
					</if>
				</if>
			</where>
		</if>
	</select>
	<select id="getByBindName"  resultType="com.demo.ssmtest.Info">
		<bind name="percent_name" value="'%'+name+'%'"/>
		select * from info
		<where>
			<if test="name!=null and name!=''">
				name like #{percent_name}
			</if>
		</where>
	</select>
	<select id="getByIdTestSqlTag"  resultType="com.demo.ssmtest.Info">
		select
		<include refid="selectColumn"></include>
		from info where id = #{id}
	</select>
	<sql id="selectColumn">
		id,name,password,description,detailId
	</sql>
</mapper>

12、dbConfig.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/mybatis
jdbc.username=root
jdbc.password=

13、Info.java

package com.demo.ssmtest;


public class Info {

	Integer id;
	String name;
	String password;
	String description;
	Integer detailId;
	
	public Info() {
		super();
	}

	public Info(Integer id, String name, String password, String description, Integer detailId,String action) {
		super();
		this.id = id;
		if("select".equals(action)){
			if(name!=null&&!"".equals(name)){
				this.name = "%"+name+"%";
			}
			if(password!=null&&!"".equals(password)){
				this.password = "%"+password+"%";
			}
			if(description!=null&&!"".equals(description)){
				this.description = "%"+description+"%";
			}
			if(detailId!=null&&!"".equals(detailId)){
				this.detailId = detailId;
			}
		}else{
			if(name!=null&&!"".equals(name)){
				this.name = name;
			}
			if(password!=null&&!"".equals(password)){
				this.password = password;
			}
			if(description!=null&&!"".equals(description)){
				this.description = description;
			}
			if(detailId!=null&&!"".equals(detailId)){
				this.detailId = detailId;
			}
		}
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Integer getDetailId() {
		return detailId;
	}

	public void setDetailId(Integer detailId) {
		this.detailId = detailId;
	}

	@Override
	public String toString() {
		return "Info [id=" + id + ", name=" + name + ", password=" + password + ", description=" + description
				+ ", detailId=" + detailId + "]";
	}
}

14、InfoMapper.java

package com.demo.ssmtest;

import java.util.List;

import org.apache.ibatis.annotations.Param;

public interface InfoMapper {

	public List<Info> getByConditionIFWHERE(Info info);
	public List<Info> getByConditionCHOOSE(Info info);
	public Integer updateById(Info info);
	public List<Info> getEmpsByConditionForeach(@Param("ids")List<Integer> ids);
	public List<Info> getByInnerParameter(Info info);
	public List<Info> getByBindName(Info info);
	public List<Info> getByIdTestSqlTag(int id);
}

15、TestMain.java

package com.demo.ssmtest;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class TestMain {
	
	
	public static void main(String[] args) throws Exception {
		test();
	}

	public static void test() throws Exception {
		
		
		String resource = "mybatis.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			
			//动态SQL
			/*
			if标签
				1、使用<if test="">标签,其中test的值就是判断的语句,要使用OGNL写
				2、<if test=""></if>中间写需要动态设置的sql,如:<if test="id!=null">id=#{id}</if>,其中#{id}的id和test里面用到的id是从参数中获取的(test里面的id不用写#{XX}来获取)
				3、遇到特殊符号要改用转义字符,如:&&可以用&amp;&amp;代替,也可以用and代替,但是''只能用&quot;&quot;代替或者直接用
				4、在OGNL语句中可以:
					①访问对象属性
					②调用方法 (如:类方法、java原生的方法)
					③调用静态属性/方法
					④调用构造方法
					⑤使用运算符
					⑥使用逻辑运算符
				5、OGNL会自动进行字符串和数字的转换判断
				6、<if test=""></if>中间的sql使用like条件的时候不支持在sql里面写%%,应该在传入值的时候设置好,不然sql就会变成 select * from info where id=数值 and name like '%' 数值 '%';
			where标签
				1、作用:当sql上一个条件不存在,而下一个条件有and或者or开头的时候会出错,这个时候可以使用where标签来动态地去掉sql中没用的and或者or
				2、用法:使用<where>标签包着需要动态去掉没用and或者or的标签和语句
				3、注意:<where>标签只会处理语句前面的and或者or,而不去处理后面的and或者or
			trim标签(平常用的不多)
				1、作用:解决where标签中,每个条件后面多出来的and或者or,或者用于自定义字符串截取
				2、注意:不能跟where标签一起用
				3、用法:<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
					①prefix			:前缀,给整个需要拼接的字符串后面添加一个前缀(如: sql的条件语句前面加一个where)
					②prefixOverrides:前缀覆盖,去掉整个字符串前面多余的字符(如:去掉sql的条件语句前面的and或者or)
					③suffix			:后缀,给拼接字符串后的整个字符串加一个后缀(如:每个sql的条件语句后面加一个and或者or)
					④suffixOverrides:后缀覆盖,去掉整个字符串后面多余的字符串(如:去掉sql的条件语句后面的and或者or)
			 */
			InfoMapper queryMapper = openSession.getMapper(InfoMapper.class);
			//Info info = new Info(1,"na","aa","ddd",2,"select");
			Info info = new Info(1,null,null,null,null,"select");
			List<Info> rs_info = queryMapper.getByConditionIFWHERE(info);
			if(rs_info.size()==0){
				System.out.println("rs_info null");
			}else{
				for(Info in: rs_info){
					System.out.println("rs_info "+in.toString());
				}
			}
			/*
			choose标签
				1、作用:类似java中的if(){}else if(){}else{},满足条件的话就使用条件内的东西
				2、用法:
					①<when>标签		:相当于if或者else if
					②<otherwise>标签	:相当于else
					③同一个choose标签里面使用的时候就相当于if(){}else if(){}else{}
				3、注意:是在动态给sql添加搜索条件的时候用的
			*/
			Info infoCHOOSE = new Info(1,null,null,null,null,"select");
			//Info infoCHOOSE = new Info(null,"na",null,null,null,"select");
			//Info infoCHOOSE = new Info(null,null,null,null,2,"select");
			List<Info> rs_infoCHOOSE = queryMapper.getByConditionCHOOSE(info);
			if(rs_infoCHOOSE.size()==0){
				System.out.println("rs_infoCHOOSE null");
			}else{
				for(Info in: rs_infoCHOOSE){
					System.out.println("rs_infoCHOOSE "+in.toString());
				}
			}
			/*
			set标签
				1、作用:当sql使用set关键字的时候可以用这个标签代替,会自动替换掉语句后面无用的逗号
				2、用法:使用更新语句时,使用set标签包着需要更新的字段语句即可
				3、注意:
					①只会替换语句后面多余的逗号
					②更新之后记得要提交,不然mybatis会执行回滚操作(即:SqlSession.commit())
			*/
			Info update_Info = new Info(1,"nameeeeeeee","ggggddddggg","qqqqqqq",1,"update");
			int update_Index = queryMapper.updateById(update_Info);
			openSession.commit();
			System.out.println("update_Index:"+update_Index);
			
			/*
			foreach标签
				1、作用:在需要批量操作的时候可以用foreach来告诉mybatis需要拼接的参数值是什么
				2、用法:
					①在接口类的方法里面使用@Param指定该数组类型的数据的属性名
					②在mapper配置文件中使用foreach标签
					③调用测试
				3、注意:要在接口类的方法的入参里面制定该数组类型数据的属性名
				4、标签的属性对应作用:
					①collection	:指定需要便利的集合(接口类的接口方法@Param修饰的入参)
					②item		:将当前遍历出来的元素赋值给使用item指定的变量中(下面的sql字段可以直接使用#{item指定的属性名}来获取对应的值)
					③separator	:元素之间的分隔符(搜索的时候需要用逗号,所以这里写逗号)
					④open		:指定遍历最终结果字符串的开头的字符串(只要是需要拼接的字符串前面的内容都可以写进去)
					⑤close		:指定遍历最终结果字符串的结尾的字符串(只要是需要拼接的字符串后面的内容都可以写进去)
			*/
			List<Info> rs_Foreach = queryMapper.getEmpsByConditionForeach(Arrays.asList(1,2));
			if(rs_Foreach.size()==0){
				System.out.println("rs_Foreach null");
			}else{
				for(Info in: rs_Foreach){
					System.out.println("rs_Foreach "+in.toString());
				}
			}
			
			/*
			内置参数
				1、mybatis默认的两个内置参数,可以在mapper配置文件中当做已有参数来使用
				2、_parameter	:代表整个参数,即mapper方法的入参,可以是单个数据,可以是一个参数集合
				3、_databaseId	:如果在全局mybatis配置中有配置databaseIdProvider标签,_databaseId代表的是数据库的别名
			*/
			List<Info> rs_InnerParam = queryMapper.getByInnerParameter(new Info(1,null,null,null,null,"select"));
			if(rs_InnerParam.size()==0){
				System.out.println("rs_InnerParam null");
			}else{
				for(Info in: rs_InnerParam){
					System.out.println("rs_InnerParam "+in.toString());
				}
			}
			
			/*
			bind标签
				1、作用:使用该标签在mapper配置文件的语句中,绑定OGNL表达式的值到某个变量中(如:模糊搜索时,like后面的值前后需要加百分号,这个时候就使用bind标签定义新的模糊搜索条件值)
				2、用法:在<select><update><insert><delete>标签里面使用<bind>标签,其中name的值为修改后赋值给sql语句使用的参数名,value为需要的对应参数的OGNL表达式的值
			*/
			Info infoBind = new Info(null,"ee",null,null,null,"bind");
			List<Info> rs_infoBind = queryMapper.getByBindName(infoBind);
			if(rs_infoBind.size()==0){
				System.out.println("rs_infoBind null");
			}else{
				for(Info in: rs_infoBind){
					System.out.println("rs_infoBind "+in.toString());
				}
			}
			
			/*
			sql标签
				1、作用:把比较繁杂而且能重用的部分sql语句使用该标签单独定义,在需要重用的地方调用,以达到sql片段重用的效果
				2、用法:在mapper配置文件中使用<sql>标签定义需要重复使用的sql片段,在需要使用的地方使用<include>标签调用指定的<sql>标签值,以达到sql重用的效果
			*/
			List<Info> rs_infoSqlTag = queryMapper.getByIdTestSqlTag(1);
			if(rs_infoSqlTag.size()==0){
				System.out.println("rs_infoSqlTag null");
			}else{
				for(Info in: rs_infoSqlTag){
					System.out.println("rs_infoSqlTag "+in.toString());
				}
			}
			
		} finally {
			openSession.close();
		}

	}
}

16、项目目录
项目目录

17、demo
https://download.youkuaiyun.com/download/qq_22778717/10718718

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值