Mybatis动态 sql用法

本文介绍了Mybatis中动态SQL的使用,包括在映射器配置文件中通过if、choose、when等标签实现动态查询,并重点讲解了动态SQL的"三剑客"——trim标签的用途。同时,对比了注解方式实现动态SQL,尽管注解简化了代码,但在复杂场景下不如XML灵活。最后,作者分享了学习动态SQL的心得体会,以及编程带来的成就感。

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

上回书说到,mybatis解决了jdbc连接数据库时的四个问题,在上周博客结尾的时候笔者说,可以用动态sql语法以及通过@注解的方式来使调用的sql语句变成动态,使用的时候会更加灵活,这次就来详细阐述一下动态sql语句究竟怎么用。

一、映射器配置文件实现动态sql语句

我们一切的学习目的都是为了以后的工作(赚小钱钱),一个项目可能需要的需求也在变化,而在设计的时候考虑到这些变化,会给我们节省很多时间和经历。

就拿查询来说,项目的需求可能有单查,多查,或者查询几个信息其他的信息不需要显示,这时候我们不可能出现一个新需求就写一个新的类所以就需要我们动态sql语句登场了。

1.动态sql语句查询

在写查询时,可预想到很多不同的需求,以下图学生表为例,其中有五种属性,分别为编号、姓名、性别、班级.

 如果按照不同的需求,像上一周一样用映射器写sql语句,就会很麻烦,就像下图

// 查询
		// 全查
	public List<Student> findAllStudent();
	
		// 根据id查询
	public Student findStudentBySid(int sid);
	
	// 找到学生的个数
	public int findStudentCount();
	
	// 所有学生的名字
	public List<String> findAllStudentName();
	
	// 根据性别获取学生信息
	public List<Student>  findStudentBySex(String sex);

这样就很麻烦,所以可以在xml文件中写sql语句时加上条件,如下

	<select id="findStudentWhere" resultType="Student" parameterType="Student">
		select sid,sname,birthday,ssex,classid from student
		
		<where>  1=1
			<if test="ssex != null">
			    and	ssex = #{ssex}
			</if>
			<if test="classid != 0">
				and	classid = #{classid}
			</if>
		</where>  
	</select>

上图使用的是if语句,将student表中的五种属性都列出来,然后再where条件判断后加上if语句,只要满足if中的语句,就会自动转变sql语句格式,为了满足全查需求,再where后加上“1=1”这种结果为true的条件,这样不会冲突。

查询语句除了if语句,还可以使用choose和when标签,当条件满足时,运行sql语句,如下图显示。

<select id="findStudentChoose" resultType="Student" parameterType="Student">
		 <include refid="stusql"></include> where 1=1
		<choose>
			<when test="sname != null"> and sname = #{sname} </when>
			<when test="birthday != null"> and birthday = #{birthday} </when>
			<when test="ssex != null"> and ssex = #{ssex} </when>
			<when test="classid != 0"> and classid = #{classid} </when>
			<!-- default -->
			<otherwise> and sid = 20 </otherwise>
		</choose>
	</select>

而其中的otherwise标签是在前面的when元素都没满足的时候使用。

2.动态sql语句中的“三剑客”

有了标签,在使用动态sql语句进行增,删,改,查,就容易很多了,不过由于在不同情况下,sql语句的fuhao例如“()”和“;”与“,”以及and,or,set容易产生错误,这时就需要用到一个新的标签 trim,请看下方代码。

<insert id="addStudent" parameterType="Student">
		insert into student 
		<trim prefix="(" suffixOverrides="," suffix=")">
			<if test="sname != null">
				sname,
			</if>
			<if test="birthday != null">
				birthday,
			</if>
			<if test="ssex != null">
				ssex,
			</if>
			<if test="classid != 0">
				classid,
			</if>
		</trim>
		
		 values
		 <trim prefix="(" suffixOverrides="," suffix=")">
			<if test="sname == null">
				#{sname},
			</if>
			<if test="birthday != null">
				#{birthday},
			</if>
			<if test="ssex != null">
				#{ssex},
			</if>
			<if test="classid != 0">
				#{classid},
			</if>
		</trim>

这是一个动态sql语句实现新增,其中的trim标签有三个属性,分别是prefix,suffixOverrides,suffix。他们分别承担着不同的任务。

prefix负责拼接,例如新增需要拼接values以及“(”,删除需要拼接where。

suffixOverrides负责忽略掉最后一个元素的的后缀标点,例如上图,只需要新增姓名、性别的话,性别ssex后的“,”就需要去掉,这时suffixOverrides就可以去掉这个碍事的元素

 而suffix负责收尾,给最后一个元素加上“)”。

有了这“三剑客”,就不用担心出错了。

二、注解实现动态sql语句(了解一下)

而注解也是实现mybatis中sql语句的一大利器,省略了xml文件,直接以注解的形式实现sql语句的增删改查,如下图:

	// 查找所有的学生 
	@Select("select * from student")
	public List<Student> findAllStudent();
	
	@Select("select * from student where sid = #{v}")
	public Student findStudentBySid(int sid);

不过如果用注解的形式实现动态sql语句,我的评价是,用过的人都知道,🐕都不用。

你们随意感受下

	@Select("<script>"
			+ "select * from tab_student"
			+ "<where>"
			+ "<if test =\"ssex != null\" >and ssex = #{ssex}</if>"
			+ "<if test =\"classid != 0\" >and classid = #{classid}</if>"
			+ "</where>"
			+ "</script>"
			)
	public List<Student> findStudentScript(Student s );

看的我头疼,上这节课的时候要不是迫于彭老师的淫威我真的快困死了,所以听人劝吃饱饭,复杂的sql语句还是老老实实写xml文件吧,真不麻烦。

三、总结

mybatis中的动态sql语句是一个很实用的功能,也很关键,学到这里需要用心。

最近这几天写代码越写越顺溜了,虽然每周的周测都考得不咋好(QAQ)。

写完代码成功运行出来没有抛异常的时候,真的有种别样的成就感。

最近听了一出老戏《未央宫斩韩信》,唱到伍子胥夜出昭关出樊城,一夜白头,不禁回忆起以前大学时在图书馆读的《伍子胥列传》与《吴越春秋》,想起那个须发皆败,吴地吹箫乞食的伍子胥。

人生就像过昭关,过的了昭关还有潼关、武关、大散关,还有娄山关、函谷关、嘉峪关,关关难过关关过。

我现在这条路一点也不好走,后面会遇到很多的问题和困难,不过不要紧,我头发已经白了,没什么大不了的,关山难越,沧海难度,不过没关系,穷且益坚,不坠青云。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值