Mybatis动态 sql用法

什么是动态SQL?

        根据不同条件拼接 SQL 语句,实现对数据库更准确的操作。

为什么会有动态SQL?

        因为在我们的网页中,很多功能都是不能写死的,先不说会增加我的工作量,更会影响我们代码的效率。

        以下列网站的功能为例,那么多查询条件,一个一个写都要写几十条,更别说把他们组合起来做查询了!!!

 如何使用动态SQL?

        两种方式:

        ①映射器XML配置文件

        ②注解

映射器XML配置文件使用动态SQL

        if:单条件分支判断:< if test ="条件"> 满足条件的语句</if>

<select id="findoneStudent" resultMap="stu_class_map" parameterType="student">
	<!-- 利用反射对象,让resultType知道我们需要的类型Class.forName("com.mysql.cj.jdbc.Driver")--> 
	<!-- parameterType=传入参数的类型 ,有传入参数的时候用--> 
select * from student where 1=1
<if test="ssex!=null">
and ssex =#{ssex} 
    <!--如果条件成立则将标签包裹的sql语句拼接,不满足则直接忽略,继续往下执行-->
</if>
<if test="classid!=0">
and classid=#{classid} 
</if>
</select>

    使用if  if时,因为sql语句的拼接,导致每句sql语句前面都要加个连接关键字and,但是这时候如果第一个条件为空时,直接拼接后面带and的语句,就会出现运行错误。可以在where前面加个恒成立1=1,拼接后面的sql;之后所有的sql语句都要加上and;   

choose :多条件分支判断,等 同于 java 的 switch 。

 <select id="findonechose" resultMap="stu_class_map" parameterType="student">
 <include refid="stu_find"></include> where 1=1
 	<choose>
 <when test="ssex!=null">
 and ssex=#{ssex}
 </when>
 <when test="classid!=0">
 and classid=#{classid}
 </when>
 <otherwise>
 and sname="奥特曼"
<!--当以上when全不满足则执行otherwise里的代码-->
<!--我很可以有多个,otherwise只能有一个-->
 </otherwise>
 	</choose>
 </select>

where:自动拼接where,去and或者or

如果我们第一条的查询条件全部为空时

select * from student where
<if test="ssex!=null">
and ssex =#{ssex} 
</if>
<!--如何我们的这段代码不用1=1的这种办法处理,且if里面为null时,我们的sql语句就会出错-->
<!--就会变成这个样子:select * from student where  -->

这时候可以用我们的where处理

<select id="findwhere" resultMap="stu_class_map" parameterType="student">
    select * from student
      <where>
 	        <if test="ssex!=null">
 	            and ssex =#{ssex} 
 	        </if>
 	        <if test="classid!=0">
 	            and classid=#{classid} 
 	        </if>
     </where>
     <!--where 只会在至少有一条sql语句被拼接时才会加入,也会自动帮我们去的开头的and,or-->
</select>

set:类似于where,主要是用在新增中 ,会在第一条拼接的语句中自动加上set关键字,并去除,(逗号)

<update id="//updateStudent"   parameterType="com.ape.bean.Student">
 update student
 <set>
 <if test="sname!=null">sname=#{sname},</if>
 <if test="ssex!=null">ssex=#{ssex},</if>
 <if test="birthday!=null">birthday=#{birthday},</if>
 <if test="classid!=0">classid=#{classid},</if>
 </set>
 <where>sid=#{sid}</where>
 </update>

<!--在包含的语句前输出一个 set,
然后如果包含的语句是以逗号结束的话将会
把该逗号忽略。有了 set 元素就可以动态的更
新那些修改了的字段-->

trim:万能标签,可代替任意元素标签,进行自定义的拼接,去除;


<trim prefix="(" suffixOverrides="," suffix=")">
    <if test="sname!=null">sname,</if>
</trim>
<!--里面有两组标签属性
prefix--开头加上什么,prefixOverrides--开头去掉什么
suffix--结尾加上什么,suffixOverrides--结尾去掉什么-->

<!--修改-->
<update id="updateStudent"   parameterType="Student">
 update student
 <trim prefix="set" suffixOverrides=",">
 <if test="sname!=null">sname=#{sname},</if>
 <if test="ssex!=null">ssex=#{ssex},</if>
 <if test="birthday!=null">birthday=#{birthday},</if>
 <if test="classid!=0">classid=#{classid},</if>
</trim>
 <where>sid=#{sid}</where>
 </update>


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

foreach:循环

<!--foreach循环-->
<foreach collection="list" item="n" open="(" close=")"separator=",">
	#{n}
</foreach>
<!--foreach标签里的参数:
collection :传入集合类型list,数组类型:array,或者其他别名
item="n":接参(可写任意)
open="(" 开头加上什么
close=")结尾加上什么
separator=","分隔符是什么;-->

例:
<select id="findbyList"   resultMap="stu_class_map"  parameterType="Student" >
select * from student where sid in
<foreach collection="list" item="n" open="(" close=")" separator=",">
	#{n}
</foreach>
 </select>

bind:取别名,在 动态sql里充当处理模糊查询的作用。

<bind name="mh" value="_parameter+'%'"/>
<!--name=要取的名字-->
value=_parameter     _parameter就是我们要传入的值,可以在这里做拼接
<!--使用时,只需要填入给标签取的名字-->
select * from student where sname like #{mh}


例:
 </select>
 <select id="1findBymh" resultMap="stu_class_map" parameterType="String">
 <bind name="mh" value="_parameter+'%'"/>
 select * from student where sname like #{mh}
 </select>

sql片段:不是完整的sql语句
<sql id="">    sql片段,字段</sql>
使用
<include id="sqlid">sqll片段</include>
可以代替写入的sql片段

<sql id="stu_find">
select * from student
</sql>


 <select id="findallStudent"   resultMap="stu_class_map"  >
<include refid="stu_find"></include> left join class on student.classid=class.classid;
 </select>


输出之后 sql语句就会变成
select * from student left join class on student.classid=class.classid;


<include refid="stu_find"></include>会代替我们自定义的sql片段


注解中使用动态sql

一,查询

@Select("select * from student ")
public List<Student> findAllStu();

解决多参的问题可以用@Param注解取别名,然后再sql语句中使用别名


二,新增

@Insert("insert into student(sname,ssex,birthday,classid) values(sname,ssex,birthday,classid)")
    @Options(keyProperty = "sid", useGeneratedKeys = true)
    public int addStudent(Student s);
主键回填问题可以用@Options注解

三,
单表联查,1v1
普通联查发现,主表下面的副标是空值,因为没有做映射;我们在xml文件的时候是用resultMap标签完成的,但是在注释里我们使用Results

@Results({
    @Result(column ="classid",property = "classid"),
    @Result(column ="classid",one = @One(select ="com.ape.Mapper.BjMapper.findBjbyclassid"),property ="bj")

    })
    @Select("select * from student")
    public List<Student> findStuandClass();


做联查映射关系,column=主表的关联字段,one注解=@one (selec=t获取一个字符串(通过该字符串获取带参数的对象)),
这里需要创建一个接口,写一个获取该对象的方法
select=该接口的类路径.方法

最后赋值给prepery"对象";
prepery对象就是我们要做映射的对象。最终会把coulumn字段映射给prepery对象对应的属性,这时候,主表的映射就没了,需要自己再声明一次
,注释的sql语句没有联查 语法,不能left,join,right;

四,多表联查

一对多:

关键字用many@Many,其他地方跟一对一基本一样 
,many注解=@Many (selec=t获取一个字符串(通过该字符串获取带参数的对象)),

用方法写 sql语句:



@UpdateProvider(type = tclei.class,method = "updt")
	public int updateTecher(Teacher t);

//type=类映射,写有sql语句的方法的类名,
//methd=类里面的方法名
	
	class tclei{
		public String updt(Teacher t) {
//sql方法参数的类型必须跟方法入参的类型一样
			String sql="update teacher set ";
			if (t.getTname()!=null) {
				sql+="tname=#{tname}";
			}
			if (t.getTname()!=null) {
				sql+=",";
			}
			
			if (t.getTbirthday()!=null) {
				sql+="Tbirthday=#{Tbirthday}";
			}
			if (t.getTbirthday()!=null) {
				sql+=",";
			}
			
			if (t.getTsex()!=0) {
				sql+="Tsex=#{Tsex}";
			}
			if (t.getTsex()!=0) {
				sql+=",";
			}
			
			if (t.getTaddress()!=null) {
				sql+="Taddress=#{Taddress}";
			}
			if (t.getTaddress()!=null) {
				sql+=",";
			}
			
			if (t.getTemail()!=null) {
				sql+="Temail=#{Temail}";
			}
			//sql=sql.substring(0, sql.length()-1);
			sql+=" where tid=#{tid}";
			return sql;}
	}

SQL方法的过度:构造器,就是SQL方法的升级版
构造器SQL
return new SQL( ) {  {  
SECECT(可以写多个select,会自动拼接里面的内容)
FROM
if
WHERE
if
} }
多个判断用WHERE隔开,WHERE会自动拼接and

删除

@DeleteProvider(type = DelTea.class,method = "deleteTeacher")
	public int deleteTeacher( Teacher t);
//type:类名
//method:方法名

class DelTea{
     /返回值必须是String类型
	public String deleteTeacher( Teacher t) {
	return new SQL() {{
		DELETE_FROM("teacher");
		if (t.getTid()!=0) {	
			WHERE("tid=#{tid}");
		}else {
			WHERE("tid=0");
		}
		
	}}.toString();
	}
}


 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis动态SQL是一种基于OGNL表达式的技术,可以在SQL语句中实现一些逻辑判断。总体上,MyBatis动态SQL主要包含以下几类语句: 1. if语句:用于简单的条件判断。 2. choose语句(相当于Java语言中的switch):包含when和otherwise子句,类似于JSTL中的choose语句。 3. trim语句:在包含的内容上添加前缀或后缀,可以用于动态地拼接SQL语句。 4. where语句:主要用于简化SQL语句中的where条件判断,能够智能地处理and和or,防止多余导致语法错误。 5. set语句:主要用于更新操作。 6. foreach语句:在实现MyBatis的in语句查询时特别有用。 以上是MyBatis动态SQL的几种主要用法,可以根据具体需求选择适合的方式来编写动态SQL语句。 MyBatis Dynamic SQL是一个与MyBatis配套的项目,它解决了MyBatis动态SQL方面的一些缺点,并提供了更灵活、强大的动态SQL功能。该项目可以帮助开发人员更方便地编写复杂的SQL语句,提高开发效率。你可以在官方文档中了解更多关于MyBatis Dynamic SQL的信息。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [真正的Mybatis动态sqlMyBatis Dynamic SQL](https://blog.csdn.net/qq_36534560/article/details/119931287)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [mybatis动态sql及分页](https://blog.csdn.net/hjzhzhshhs/article/details/125241823)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值