业务场景:在我们生活中很多业务常常遇到动态搜索的情况,比如搜索民宿,根据位置,价格,面积等等情况动态搜索,参数等信息可以根据我们需求改变,这里就涉及到了我们Mybatis常说的动态SQL。
Mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。
Mybatis提供了动态SQL,也就是可以根据用户提供的参数,动态决定查询语句依赖的查询条件或SQL语句的内容。
标签名 | 解释 |
---|---|
if | 单条件分支判断 |
choose, when, otherwise | 多条件分支判断 |
where | 处理sql条件接拼where |
set | 处理sql条件接拼set |
foreach | 循环操作 |
trim | 处理sql条件拼接 |
sql语句
CREATE TABLE `stu` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`age` int(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
sql-if标签
需求1:查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询
/**
查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询
*/
public List<Stu> queryLikeByName(String name);
<!--查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询-->
<select id="queryLikeByName" resultType="javabean.Stu" parameterType="string">
select * from stu where sex = '男'
<if test="value!= null and value !=''">
and name like concat('%',#{name},'%')
</if>
</select>
//查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询
@Test
public void queryLikeByName() {
List<Stu> list = mapper.queryLikeByName("四");
for(Stu stu : list){
System.out.println(stu);
}
}
sql-choose, when, otherwise标签
choose,when,otherwise 相当于java中的 if, else if() ,Switch 的逻辑
如果其中的一个when 成立,则后的都不执行,如果所有when的都不成立,那么就执行otherwise
也就是谁在前面谁优先
需求2:查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找
/**
* 查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找
*/
public List<Stu> queryByLikeNameAndAge(@Param("name") String name , @Param("age") Integer age);
<!--查询男性用户,如果输入了 姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找-->
<select id="queryByLikeNameAndAge" resultType="javabean.Stu">
select * from stu where sex = '男'
<choose>
<when test="name!= null and name !=''">
and `name` like concat('%',#{name},'%')
</when>
<when test="age != null and age !=''">
and age like concat('%',#{age},'%')
</when>
<otherwise>
and id = 2
</otherwise>
</choose>
</select>
//查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找
@Test
public void queryByLikeNameAndAge(){
List<Stu> list = this.mapper.queryByLikeNameAndAge("张", 1);
for(Stu stu : list){
System.out.println(stu);
}
}
sql-where标签
where标签代替 sql中的where关键字
需求3:查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询
/**
* 查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询
*/
public List<Stu> queryByAllUserLikeNameAndAge(@Param("name") String name , @Param("age") Integer age);
<!--查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询-->
<select id="queryByAllUserLikeNameAndAge" resultType="javabean.Stu">
select * from stu
<where>
<if test="name != null and name!=''">
name like concat('%',#{name},'%')
</if>
<if test="age != null and age!=''">
and age like concat('%',#{age},'%')
</if>
</where>
</select>
//查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询-
@Test
public void queryByAllUserLikeNameAndAge(){
List<Stu> list = this.mapper.queryByAllUserLikeNameAndAge("四", 1);
for(Stu stu : list){
System.out.println(stu);
}
}
sql-set标签
set标签代替 sql中set关键字
需求4:如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age
/**
* 如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age
*/
public Integer updateByNameOrAge(@Param("name") String name , @Param("age") Integer age , @Param("id") Integer id);
<!--如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age-->
<update id="updateByNameOrAge">
update stu
<set>
<if test="name != null and name!=''">
name = #{name},
</if>
<if test="age != null and age!=''">
age = #{age}
</if>
</set>
where id = #{id}
</update>
//如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age
@Test
public void updateByNameOrAge(){
Integer integer = this.mapper.updateByNameOrAge("小明", 26, 2);
System.out.println(integer);
}
sql-foreach标签
需求5:按照多个id查询用户信息 Select * from t_user where id in(1,2,3)
/**
* 按照多个id查询用户信息
* @param ids
* @return
*/
public List<Stu> queryIds(@Param("ids") int[] ids);
<!--按照多个id查询用户信息-->
<!--
collection:接受的是一个集合
item: 表示遍历的就量
open: 字符串拼接的开头
close: 字符串拼接的结尾
separator: 每一个变量拼接的分隔符
-->
<select id="queryIds" resultType="javabean.Stu">
select * from stu where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
// 按照多个id查询用户信息
@Test
public void queryIds(){
int[] arr ={1,2};
List<Stu> list = this.mapper.queryIds(arr);
for(Stu stu : list){
System.out.println(stu);
}
}
sql-trim标签
trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某写后缀,与之对应的属性是prefix和suffix;
可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides
属性 | 描述 |
---|---|
prefix | 给sql语句拼接的前缀 |
suffix | 给sql语句拼接的后缀 |
prefixOverrides | 去除sq语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sq语句的开头为"AND”,trim标签将会去除该”AND" |
suffixOverrides | 去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定 |
prefix用法
/**
* 查询所有,如果输入姓名,按姓名查询,如果输入性别,就按性别来查询
*/
public List<Stu> queryNameAndSexTrim(@Param("name") String name , @Param("sex") String sex);
<!--查询所有,如果输入姓名,按姓名查询,如果输入性别,就按性别来查询-->
<select id="queryNameAndSexTrim" resultType="javabean.Stu">
select * from stu
/*加前缀,去掉第一个前缀*/
<trim prefix="where" prefixOverrides="and">
<if test="name != null and name !=''">
and name = #{name}
</if>
<if test="sex != null and sex !=''">
and sex = #{sex}
</if>
</trim>
</select>
//查询所有,如果输入姓名,按姓名查询,如果输入性别,就按性别来查询
@Test
public void queryNameAndSexTrim(){
List<Stu> list = this.mapper.queryNameAndSexTrim("张", "男");
for(Stu stu : list){
System.out.println(stu);
}
}
suffix用法
/**
* 如果名字信息不是null,则修改名字, 如果sex不为null,同时也修改null
*/
public Integer updateByNameOrAgeTrim(@Param("name") String name , @Param("sex") String sex , @Param("id") Integer id);
<!--如果名字信息不是null,则修改名字, 如果sex不为null,同时也修改null-->
<update id="updateByNameOrAgeTrim">
update stu
<trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
<if test="name != null and name !=''">
name = #{name},
</if>
<if test="sex != null and sex !=''">
sex = #{sex},
</if>
</trim>
</update>
//如果名字信息不是null,则修改名字, 如果sex不为null,同时也修改null
@Test
public void updateByNameOrAgeTrim(){
Integer integer = this.mapper.updateByNameOrAgeTrim("小江", "男", 2);
System.out.println(integer);
}
点个赞再走吧!!!!!