05 动态sql
动态sql
动态 SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作。
• 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处
理器相似。
• MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作。
– if
– choose (when, otherwise)
– trim (where, set)
– foreach
if判断
<!-- 查询员工:携带了那个字段查询条件就带上这个字段的值-->
<!-- public List<Employee> getEmpsByConditionIf(Employee employee);-->
<select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
where 1=1
<!-- test:判断表达式(OGNL)
从参数中取值进行判断
遇见特殊符号应该去写转义字符
查询的时候如果某些条件没带可能sql拼装会有问题
EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(null,"%e%",null,null);
// List<Employee> emps = mapper.getEmpsByConditionIf(employee);
List<Employee> emps = mapper.getEmpsByConditionTrim(employee);
//1、给where 后面加上 1=1,以后的条件都 and xxx
//2、 mybatis 使用where标签将所有的查询条件包括在内
-->
<if test="id!=null">
and id=#{id}
</if>
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=''">
and email = #{email}
</if>
<!--ognl会进行字符串域数字的转换判断 -->
<if test="gender==0 or gender==1">
and gender = #{gender}
</if>
</select>
where标签
2、 mybatis 使用where标签将所有的查询条件包括在内
<!-- 查询员工:携带了那个字段查询条件就带上这个字段的值-->
<!-- public List<Employee> getEmpsByConditionIf(Employee employee);-->
<select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<!--where-->
<where>
<!-- test:判断表达式(OGNL)
从参数中取值进行判断
遇见特殊符号应该去写转义字符
查询的时候如果某些条件没带可能sql拼装会有问题
//1、给where 后面加上 1=1,以后的条件都 and xxx
//2、 mybatis 使用where标签将所有的查询条件包括在内,mybatis就会将where标签中拼装的sql,多出来的and或者or去掉
** where只会去掉第一个多出来的 and 或者 or
-->
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=''">
and email = #{email}
</if>
<!--ognl会进行字符串域数字的转换判断 -->
<if test="gender==0 or gender==1">
and gender = #{gender}
</if>
</where>
</select>
trim 标签
trim 字符串截取(where(封装查询条件), set(封装修改条件))
<!-- public List<Employee> getEmpsByConditionTrim(Employee employee);-->
<select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<!-- 后面多出的and或者or where标签不能解决
prefix="":前缀, trim标签中是整个字符串拼串后的结果
prefix 给拼串后的整个字符串加一个前缀
prefixOverrides="" :前缀覆盖,去掉整个字符串前面多余的字符
suffix="":后缀
suffix 给拼串后的整个字符串加一个后缀
suffixOverrides=""
后缀覆盖:去掉整个字符串后面多余的字符
-->
<trim prefix="where" suffixOverrides="and">
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null and lastName!=''">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=''">
email = #{email} and
</if>
<!--ognl会进行字符串域数字的转换判断 -->
<if test="gender==0 or gender==1">
gender = #{gender}
</if>
</trim>
</select>
set 标签
<!-- public void updateEmp(Employee employee);-->
<update id="updateEmp">
update tbl_employee
<set>
<if test="id!=null">
id = #{id},
</if>
<if test="lastName!=null">
last_name=#{lastName},
</if>
<if test="email!=null">
email=#{email},
</if>
</set>
where id = #{id}
</update>
使用trim标签来完成
<!-- public void updateEmp(Employee employee);-->
<update id="updateEmp">
update tbl_employee
<trim prefix="set" suffixOverrides=",">
<if test="id!=null">
id = #{id},
</if>
<if test="lastName!=null">
last_name=#{lastName},
</if>
<if test="email!=null">
email=#{email},
</if>
</trim>
where id = #{id}
</update>
chose 标签
choose (when, otherwise)
<!-- public List<Employee> getEmpsByConditionChoose(Employee employee);-->
<select id="getEmpsByConditionChoose" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee
<where>
<!-- 如果带了id就用id查,如果带了lastName就用lastName查-->
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="lastName!=null">
last_name like #{lastName}
</when>
<when test="email!=null">
email = #{email}
</when>
<otherwise>
gender = 0
</otherwise>
</choose>
</where>
</select>
foreach循环
<!-- public List<Employee> getEmpsByConditionForeach(List<Integer> ids);
加了@param collection="ids"
public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);
-->
<select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee">
select * from tbl_employee where id in
<!--
collection:指定要遍历的集合
list类型的参数会特殊处理封装在map中,map中的key就叫list
item:将当前遍历出的元素赋值给指定的变量
separator:每个元素之间的分隔符
open:遍历出所有结果拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
index:索引,遍历list的时候index是索引 item是值
遍历map的时候index表示的是mao的key,item就是map的值
#{变量名}就能取出变量的值也就是当前遍历出的元素
-->
<foreach collection="list" item="item_id" separator=","
open="(" close=")">
#{item_id}
</foreach>
</select>
MySQL下批量保存
第一种
<!-- public void addEmps(@Param("emps") List<Employee> emps);-->
<insert id="addEmps">
insert into tbl_employee(last_name,email,gender,d_id)
values
<foreach collection="emps" item="emp" separator=",">
(#{emplastName},#{emp.email},#{emp.gender},#{emp.dept.id})
</foreach>
</insert>
</mapper>
第二种:
需要在dbconfig.properties上加上
jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true
<insert id="addEmps">
<foreach collection="emps" item="emp" separator=";">
insert into tbl_employee(last_name,email,gender,d_id)
values (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
</foreach>
</insert>
Oracle下批量保存
<!-- <insert id="addEmps"><foreach collection="emps" item="emp" separator=";">insert into tbl_employee(last_name,email,gender,d_id)values(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})</foreach></insert> -->
<!-- Oracle数据库批量保存: Oracle不支持 values(),(),()Oracle支持的批量方式
1、多个insert放在begin - end里面 begin insert into employees(employee_id,last_name,email)values(employees_seq.nextval,'test_001','test_001@atguigu.com');
insert into employees(employee_id,last_name,email)values(employees_seq.nextval,'test_002','test_002@atguigu.com');end;
2、利用中间表: insert into employees(employee_id,last_name,email)select employees_seq.nextval,lastName,email from(select 'test_a_01' lastName,'test_a_e01' email from dualunionselect 'test_a_02' lastName,'test_a_e02' email from dualunionselect 'test_a_03' lastName,'test_a_e03' email from dual) -->
-<insert id="addEmps" databaseId="oracle">
<!-- oracle第一种批量方式 -->
<!--
<foreach collection="emps" item="emp" open="begin" close="end;">
insert into employees(employee_id,last_name,email)values(employees_seq.nextval,# {emp.lastName},#{emp.email});
</foreach> -->
<!-- oracle第二种批量方式 -->
insert into employees(
<!-- 引用外部定义的sql -->
-<include refid="insertColumn">
<property value="abc" name="testColomn"/>
</include>
)
<foreach close=")" open="select employees_seq.nextval,lastName,email from(" separator="union" item="emp" collection="emps">
select #{emp.lastName} lastName,#{emp.email} email from dual
</foreach>
</insert>
内置参数
<!-- public List<Employee> getEmpsTestInnerParameter(Employee employee);-->
<select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
<if test="_databaseId=='mysql'">
select * from tbl_employee
</if>
<if test="_databaseId=='oracle'">
select * from employees
</if>
</select>
bind 标签
模糊查询的时候 不想 加上 % 可以用bind 在映射文件中加上
<select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
<!-- bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值-->
<bind name="_lastName" value="'%'+lastName+'%'"></bind>
<if test="_databaseId=='mysql'">
select * from tbl_employee
<if test="_parameter!=null">
where last_name like #{_lastName}
</if>
</if>
</select>
sql标签
<!--抽取可重用的sql片段,方便后面引用
1、sql经常将要查询的列名,或者插入用的列名抽取出来,方便引用
2、include 来引用已经抽取的sql
3、include还可以自定义一些property,sql标签内部就能使用自定义的属性
${prop},#{ prop}不可用
-->
<sql id="insertColumn">
employee_id,last_name,email,${testColumn}
</sql>
insert into tbl_employee(
<include refid="insertColumn">
<property name="testColumn" value="abc"/>
</include>
)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)