为什么要用动态sql:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。 若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的 SQL 语句。此时,可使用动态 SQL 来解决这样的问题
动态sql:根据不同条件拼接 SQL 语句,实现对数据库更准确的操作
实现:映射器配置文件或者注解
1、映射器的写法:
if标签:只执行满足条件的语句
<select id="findstudent" parameterType="Bean.Student" resultType="Bean.Student" >
select * from student where 1=1
<if test="ssex!=null">
and ssex=#{ssex}
</if>
<if test="classid!=0">
and classid=#{classid}
</if>
</select>
choose 标签:只要找到一个就不会往下执行,分先后顺序
<select id="findstudentchoose" parameterType="Bean.Student" resultType="Bean.Student" >
select * from student where 1=1
<choose>
<when test="sname!=null">
and sname=#{sname}
</when>
<when test="classid!=0">
and classid=#{classid}
</when>
<!-- 上面条件都不满足就执行下面的语句 -->
<otherwise>
and sid=24
</otherwise>
</choose>
</select>
where标签:1没有任何条件的时候 where标签整体不出现,也不会添加where关键词
2.将遇到的第一个and 去掉
3.有条件时,会添加一个where关键词
<select id="findstudentwhere" parameterType="Bean.Student" resultType="Bean.Student">
select * from student
<where>
<if test="ssex!=null">
and ssex=#{ssex}
</if>
<if test="classid!=0">
and classid=#{classid}
</if>
</where>
</select>
set 标签: 1.添加一个set关键词
2.将最后一个条件的,去掉
<update id="updatestudent" parameterType="Bean.Student">
update student
<set>
<if test="sname!=null">
sname=#{sname},
</if>
<if test="birthday!=null">
birthday=#{birthday},
</if>
<if test="ssex!=null">
ssex=#{ssex},
</if>
<if test="classid!=0">
classid=#{classid},
</if>
</set>
</update>
trim 标签(万能标签): prefix:开头加上
prefixOverrides:开头去掉
suffix:结尾加上
suffixOverrides:结尾去掉
trim查询:
<select id="findstudenttrim" parameterType="student" resultType="student" >
select * from student
<trim prefix="where" prefixOverrides="and" >
<if test="ssex!=null">
and ssex=#{ssex}
</if>
<if test="classid!=0">
and classid=#{classid}
</if>
</trim>
</select>
trim 新增 :
<insert id="addstudenttrim" parameterType="student">
insert into student
<trim prefix="(" suffix=")" suffixOverrides=",">
<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="(" suffix=")" suffixOverrides=",">
<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>
</insert>
froeach 数组:array:数组
item:就是数组中的每个元素
open:在开始的地方加in(
close:在结束后面加)
separator:每个数输完后面加个,
<select id="findforeach" resultType="student">
select * from student where sid
<foreach collection="array" item="x" open=" in (" close=")" separator=",">
#{x}
</foreach>
for each
int array[]= {2,4,6,8,10,20,500,3000};
List<Student> list = map.findforeach(array);
for (Student s1 : list) {
System.out.println(s1);
}
模糊查询
#{} 可以防止SQL注入
${} 字符串替换不能防止SQL注入
bind 元素:name:自定义变量的变量名
value: 自定义变量的变量值
_parameter: 传递进来的参数 valu
<select id="findlike" parameterType="string" resultType="student">
<!--1 select * from student where sname like #{s} -->
<!--2 select * from student where sname like "%"#{s}"%" -->
<!--3 select * from student where sname like '${s}%' -->
<!-- 4 select * from student where sname like concat(#{s},'%') -->
<!-- 5 <bind name="bb" value="_parameter+'%'"/>
select * from student where sname like #{bb} -->
</select>
enaame
2、注解的写法:
1:脚本sql:将映射器的写法用<script></script>的方式拿过来
@Select("<script>"
+ "select * from student "
+ "<where>"
+ "<if test= \"ssex!=null\"> and ssex=#{ssex} </if>"
+"<if test= \"classid!=0\"> and classid=#{classid} </if>"
+"</where>"
+"</script>")
public List<Student> chaozhao(Student s);
2.方法中构建sql
在接口中定义内部类,来构建需要的动态sql语句,比使用标签的方式结构更加清晰
//修改方法
@UpdateProvider(type = Stuxiugai.class,method = "xiuhai")
public int xiugai(Student s);
class Stuxiugai{
public String xiuhai(Student s) {
String sql="update student set ";
if(s.getSsex()!=null) {
sql+="ssex=#{ssex},";
}
if(s.getClassid()!=0) {
sql+="classid=#{classid},";
}
sql = sql.substring(0, sql.length()-1);
sql+="where sid=#{sid}";
return sql;
}
3.SQL 语句构造器
//删除
@DeleteProvider(type = Stuxiugai.class,method = "shanchu")
public int shanchu(int sid);
class Stuxiugai{
public String shanchu(int sid) {
return new SQL() {
{
DELETE_FROM("student");
WHERE("sid=#{sid}");
}
}.toString();
}
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" 列表中