在现实场景中,我们在进行物品选择的时候,通过不同的筛选条件 实现我们的目标选择。
同样在数据库进行有针对性对象的选择的时候,我们也可以根据sql语句的不同条件进行精准操作。即,根据不同标签组合sql语句。
实现方式: ①映射配置文件xml;②注解;
常用的动态sql元素:
二、映射配置文件xml-- 动态sql中的元素标签
1、
if是 判断语句,用于单条件分支判断;在查询、删除、修改的时候会使用到.
if 标签的 test 属性值是一个符合 OGNL 的表达式, 表达式可以是 true 或 false。如果为true就会被选择,如果是false,自动被省略不会被选择。
另外,if标签在条件不成立时,不会自动去掉where和add,所以在where后写1=1这个条件,让条件恒成立。
2、
多条件分支判断;
choose when otherwise 这三个标签可以帮我们实现 if else 的判断逻辑 。
一个 choose 标签至少有一个 when,when的标签也可以有多个,但是最多只有一个otherwise。
当when中的OGNL条件表达式成立时,则不走下一个when标签;
相反,如果图中的when条件都不成立时,就走otherwise中,当不写otherwise并且以上条件都不满足时,就是全查。
3、
update student
sname=#{sname},
birthday=#{birthday},
ssex=#{ssex},
classid=#{classid},
sid=#{sid}
①、添加一个set字段
②、将要修改的字段=值中的最后一个,(逗号)去掉。
set 标签元素主要是用在更新操作的时候,可以不用全部字段都修改,只需要在修改的字段部分添加
4、
where 是:条件标签
当没有条件能够满足sql语句条件时,where标签整体不会出现,也不会添加where关键字
当条件前没有其他表达式时,第一个标签where会自动去掉第一个 and | 或者 or
当OGNL表达式满足为true时,表示有条件,就会加上where。
5、
update student
sname=#{sname},
birthday=#{birthday},
ssex=#{ssex},
classid=#{classid}
sid=#{sid}
上面的是【修改】
下面的是【新增】
insert into student
sname,
birthday,
ssex,
classid,
values
#{sname},
#{birthday},
#{ssex},
#{classid}
俗称“万能标签”;可以替代where标签,可以替代set标签;
trim标签中的属性:
①、prefix: 当 trim 元素包含有内容时, 增加所指定的前缀
②、prefixOverrides: 当 trim 元素包含有内容时, 去除所指定的前缀
③、suffix: 当 trim 元素包含有内容时, 增加所指定的后缀
④、suffixOverrides:当 trim 元素包含有内容时, 去除指定的后缀
6、
数组用 array 集合用 list
<二 使用array数组>
foreach 中的属性
collection: 必填, 集合/数组/Map的名称.
item: 变量名。即从迭代的对象中取出的每一个值
index: 索引的属性名。当迭代的对象为 Map 时, 该值为 Map 中的 Key.
open: 循环开头的字符串
close: 循环结束的字符串
separator: 每次循环的分隔符
7、
作用:自定义一个上下文变量
8、
反复使用的sql标签 将重复的片段固定下来; 双标签 定义sql片段
select * from student
sid,sname,birthday,ssex,classid
9、
用include将定义的片段通过sql中的id名去引入,去补充除了定义好的片段以外的部分,和片段中拼接成一条完整的sql语句
三、注解动态sql
第一种方式:脚本sql
在sql语句中加入标签,按照之前sqlmap中的动态sql的样式书写
// 动态sql注解
@Select("")
public List findStuScript(Student stu);
第二种方式: 使用方法构建sql语句
@SelectProvider | @InsertProvider | @UpdateProvider | @DeleteProvider
@UpdateProvider(type = StuUpd.class, method = "funUpdStu")
public int updStuFunction(Student stu);
第三种方式:方法中构建动态sql
在接口中定义内部类,来构建需要的动态sql语句,比使用标签的方式结构更加清晰
class StuUpd {
public String funUpdStu(Student stu) {
String sql = "update student set ";
if (stu.getSname() != null) {
sql += " sname=#{sname}, ";
}
if (stu.getBirthday() != null) {
sql += " birthday=#{birthday}, ";
}
if (stu.getSsex() != null) {
sql += " ssex=#{ssex}, ";
}
if (stu.getClassid() != 0) {
sql += " classid=#{classid},";
}
sql = sql.substring(0, sql.length() - 1);
sql += " where sid = #{sid}";
return sql;
}
}
第四种方式: 使用sql语句构造器
@DeleteProvider(type = delGZQ.class, method = "delgzq")
public int delStuGZQ(Student stu);
// 构造内部类
class delGZQ {
public String delgzq(Student stu) {
return new SQL() {
{
DELETE_FROM("student");
if (stu.getSid() != 0) {
WHERE("sid = #{sid}");
}
}
}.toString();
}
}
作用:解决 Java 代码中嵌入 SQL 语句(硬编码问题),通过简单地创建一个实例来调用方法生成SQL语句
特点:没有过多的使用类如 and的连接词,也不用过多使用字符串的拼接。
SQL 语句构造器的常用方法
属性名 | 说明 |
SELECT | 开始或插入到 SELECT 子句,可以被多次调用,参数也会添加到 SELECT子句 |
FROM | 开始或插入到 FROM 子句,可以被多次调用,参数也会添加到 FROM 子句 |
WHERE | 插入新的 WHERE 子句条件,可以多次被调用 |
OR / AND | 使用 OR / AND 来分隔当前的 WHERE 子句的条件 |
DELETE_FROM | 开始一个 delete 语句并指定需要从哪个表删除的表名。 |
INSERT_INTO | 开始一个 insert 语句并指定需要插入数据的表名 |
VALUES | 插入到 insert 语句中。第一个参数是要插入的列名,第二个参数则是该列的值。 |
UPDATE | 开始一个 update 语句并指定需要更新的表名 |
SET | 针对 update 语句,插入到 "set" 列表中 |