动态sql

动态SQL

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了

解决 拼接SQL语句字符串时的痛点问题。

7.1 if

if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之,

标签中的内容不会执行

<!--List<Emp> getEmpListByCondition(Emp emp);-->

<select id="getEmpListByMoreTJ" resultType="Emp">

select * from t_emp where 1=1

<if test="ename != '' and ename != null">

and ename = #{ename}

</if>

<if test="age != '' and age != null">

and age = #{age}

</if>

<if test="sex != '' and sex != null">

and sex = #{sex}

</if>

</select>

7.2 where

where和if一般结合使用:

(1)若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

(2)若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余

的and去掉

注意:where标签不能去掉条件最后多余的and

<select id="getEmpListByMoreTJ2" resultType="Emp">

select * from t_emp

<where>

<if test="ename != '' and ename != null">

ename = #{ename}

</if>

<if test="age != '' and age != null">

and age = #{age}

</if>

<if test="sex != '' and sex != null">

and sex = #{sex}

</if>

</where>

</select>

7.3 trim

trim用于去掉或添加标签中的内容

常用属性:

(1)prefix:在trim标签中的内容的前面添加某些内容

(2)prefixOverrides:在trim标签中的内容的前面去掉某些内容

(3)suffix:在trim标签中的内容的后面添加某些内容

(4)suffixOverrides:在trim标签中的内容的后面去掉某些内容

<select id="getEmpListByMoreTJ" resultType="Emp">

select * from t_emp

<trim prefix="where" suffixOverrides="and">

<if test="ename != '' and ename != null">

ename = #{ename} and

</if>

<if test="age != '' and age != null">

age = #{age} and

</if>

<if test="sex != '' and sex != null">

sex = #{sex}

</if>

</trim>

</select>

7.4 choose、when、otherwise

choose、when、 otherwise相当于if...else if...else

when至少设置一个,otherwise最多设置一个

<select id="getEmpListByChoose" resultType="Emp">

select * from t_emp

<where>

<choose>

<when test="empName != null and empName != ''">

emp_name = #{empName}

</when>

<when test="age != null and age != ''">

age = #{age}

</when>

<when test="gender != null and gender != ''">

gender = #{gender}

</when>

</choose>

</where>

</select>

7.5 foreach

(1)collection:设置要循环的数组或集合;该属性是必须指定的,在不同的情况下,该属性的值是不一样的,

主要有以下3种情况:

①如果传入的是单参数且参数类型是一个List集合的时候,collection的属性值为list

②如果传入的是单参数且参数类型是一个Array数组的时候,collection的属性值为array

③如果传入的参数是多个的时候,我们就需要把它封装成一个Map了,当然单参数也可以

(2)item:用一个字符串表示数组或集合中的每一个数据

(3)separator:设置每次循环的数据之间的分隔符

(4)open:循环的所有内容以什么开始

(5)close:循环的所有内容以什么结束

<!-- 批量添加 void insertMoreEmp(@Param("emps") List<Emp> emps); -->

<insert id="insertMoreEmp">

insert into t_emp values

<foreach collection="emps" item="emp" separator=",">

(null,#{emp.empName},#{emp.age},#{emp.gender})

</foreach>

</insert>

<!-- 批量删除 void deleteMoreEmp(@Param("empIds") Integer[] empIds); -->

<delete id="deleteMoreEmp">

delete from t_emp where emp_id in

<foreach collection="empIds" item="empId" separator=",",open="(",close=")">

#{empId}

</foreach>

</delete>

补充:直接在mapper上写:

@Select({

"<script>",

"select * from sys_job where job_group in",

"<foreach item='item' index='index' collection='planIds' open='(' separator=',' close=')'>",

"#{item}",

"</foreach>",

"</script>"

})

List<SysJob> selectByJobGroup(@Param("planIds") String[] planIds);

7.6 set标签

主要使用在update语句当中,用来生成set关键字,同时去掉最后多余的"," 比如我们只更新提交的不为空的字段,如果提交的数据是空或者"",那么这个字段的原来数据我们将不更新

(1)mapper接口

/**

* 更新信息,使⽤set标签

* @param car

* @return

*/

int updateWithSet(Car car);

(2)xml文件

<update id="updateWithSet">

update t_car

<set>

<if test="carNum != null and carNum != ''">car_num = #{carNum},</if>

<if test="brand != null and brand != ''">brand = #{brand},</if>

<if test="guidePrice != null and guidePrice != ''">guide_price = #{guidePrice},</if>

<if test="produceTime != null and produceTime != ''">produce_time = #{produceTime},</if>

<if test="carType != null and carType != ''">car_type = #{carType},</if>

</set>

where id = #{id}

</update>

(3)测试

@Test

public void testUpdateWithSet(){

CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);

Car car = new Car(38L,"1001","丰⽥霸道2",10.0,"",null);

int count = mapper.updateWithSet(car);

System.out.println(count);

SqlSessionUtil.openSession().commit();

}

7.6 SQL片段

sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入

<sql id="empColumns">

eid,ename,age,sex,did

</sql>

select <include refid="empColumns"></include> from t_emp

7.7 在注解中使用动态 SQL(script标签)

@Select({

"<script>",

"select count(1) from employee_basic_information_table ",

"where phone_number = #{phoneNumber} ",

"<if test='userId != null'>",

"and user_id != #{userId}",

"</if>",

"</script>"

})

Integer getByPhoneNumber(@Param("phoneNumber") String phoneNumber,@Param("userId") Long userId);

在实际编程中,动态SQL可以通过以下方式实现:

  • 字符串拼接:在代码中直接拼接SQL语句的各个部分。
  • 预编译语句:使用参数化查询来避免SQL注入,同时提供动态SQL的功能。
  • 构建器模式:使用构建器类或函数来构建SQL语句,这种方式可以减少错误并提高代码的可读性。

动态SQL的具体实现会根据使用的编程语言和数据库访问技术(如JDBC、ADO.NET、Hibernate等)而有所不同。在使用动态SQL时,开发者需要权衡灵活性和安全性,确保代码既能够满足需求,又能够防止潜在的安全风险。

相关推荐
小参宿2 分钟前
【Stream流】
java·开发语言
ruleslol7 分钟前
java基础概念49-数据结构2
java·数据结构
qq_10613834579 分钟前
快速搭建SpringBoot3+Vue3+ElementPlus管理系统
java·vue.js·spring boot·idea
小草儿79913 分钟前
gbase8s之查看锁表的sql
服务器·数据库·mysql
Koikoi12321 分钟前
java引用相关(四大引用类型,软引用避免oom,弱引用表,虚引用和引用队列,可达性分析算法)
java·开发语言
GoodStudyAndDayDayUp28 分钟前
一个老是用的SQL
java·数据库·sql
whoami-430 分钟前
第二章.数据库与数据库管理系统
数据库·mysql
小屁孩大帅-杨一凡1 小时前
python实现文件夹打包成jar
java·开发语言·python·pycharm·jar
清风 0011 小时前
一、使用 mdadm 工具在 Ubuntu 上创建 RAID 1(镜像)
运维·服务器·数据库