12.动态sql
动态sql:根据不同的条件生成不同的sql语句,其本质是在sql层面,加入一些逻辑代码
1.if标签的使用:(重点:会执行所有的fi标签,并进行条件判断,满足的部分进行sql拼接)
1.1接口中的定义:
public interface UserMapper {
List<User> getUserByListtIf(Map map);
}
1.2xml文件中的写法
<select id="getUserByListtIf" resultType="user">
select * from public."user" where 1=1
重点1:如果传入的id参数不为null,会在上述的sql上拼接上改条件:select * FROM public.user WHERE 1=1 and id=1;
<if test="id !=null">
and id=#{id}
</if>
<if test="name !=null">
and name=#{name}
</if>
</select>
1.3测试类的写法:
@org.junit.Test
public void testGetUserByListif(){
SqlSession sqlSession = MybatisTools.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
重点1:创建map放入sql所需参数
Map<String, Object> map = new HashMap<String, Object>();
map.put("id",1);
map.put("name","刘丹");
List<User> userByListtIf = mapper.getUserByListtIf(map);
for (User user : userByListtIf) {
System.out.println(user);
}
sqlSession.close();
}
2.where标签的使用:动态拼接where(并且会智能的去掉第一个语句的and或者or)
上述sql写成:
select * from public."user" where 1=1再拼接下面的if标签内容,显得很不专业
可以使用<where>标签
用法如下:
xml文件中的写法:
<select id="getUserByListtIf" resultType="user">
select * from public."user"
重点1:使用where标签,下面跟条件,如果条件不满足,则不会拼接where语句
并且第一个子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
<where>
<if test="id !=null">
id=#{id}
</if>
重点2:第一个if标签的不满足,第二个语句前有and,在拼接sql时会将and去除!
<if test="name !=null">
and name=#{name}
</if>
</where>
</select>
3.choose、when、otherwise标签 (重点:不会执行所有的when语句,遇到满足的条件,后面的when语句不会执行)
3.1xml中的写法如下:
<select id="getUserByListtIf" resultType="user" >
select * from public."user"
重点1:配合where标签使用
<where>
<choose>
重点2:如果1一条件满足,不会执行剩余的语句,直接跳出
<when test="id !=null">
and id=#{id}
</when>
<when test="name !=null">
and name=#{name}
</when>
重点3:otherwise可以不写,即不拼接该语句,会查询出所有的记录
<otherwise>
</otherwise>
</choose>
</where>
</select>
4.set标签,用于更新操作(并且会智能的去掉最后一个语句后面的逗号)
更新语句:update 表名 set ... where ...
xml文件中的写法:
<update id="updatePwd">
update public."user"
重点1:使用set标签,相当于update语句中的set字段
<set>
重点2:使用if标签进行字段判断,注意每个判断后面的逗号,因为多字段更新时,字段以逗号隔开
(update 表明 SET name='无法', pwd='五天' where 语句),逗号必须有
但是mybatis在进行拼接时,会自动将最后一个set字段的逗号去掉,所以每个set语句都要加逗号
<if test="name !=null">name=#{name},</if>
<if test="pwd !=null">pwd=#{pwd},</if>
</set>
重点3:条件语句的拼接
<where>
<choose>
<when test="id!=null">id=#{id}</when>
<when test="name!=null">name=#{name}</when>
</choose>
</where>
</update>
sql片段
在mapper.xml中有些sql片段,在多个sql语句中都有用,每个都写的话显得代码冗余,可以用到代码片段,将公共部分抽取出来
注意点:
1.最好基于单表定义sql片段
2.sql片段中不要存在where标签,因为where标签会自动优化sql中的and和or
3.尽量存放是简单的if标签
样例:
重点1:使用sql标签,定义自定义id,将工共sql片段抽取出来
<sql id="choose-when-id-name">
<choose>
<when test="id!=null">id=#{id}</when>
<when test="name!=null">name=#{name}</when>
</choose>
</sql>
<update id="updatePwd">
update public."user"
<set>
<if test="name !=null">name=#{name},</if>
<if test="pwd !=null">pwd=#{pwd},</if>
</set>
<where>
重点2:使用include标签和refid标签来进行sql片段的引入
<include refid="choose-when-id-name"></include>
</where>
</update>
foreach的使用
示例1:如果想执行这么一个语句呢:select * FROM public."user" WHERE ( id=1 or id=2 or id=3 or id=4 );
如何动态拼接呢:
1.1xml中的写法
<select id="seletUserForEarch" resultType="cn.com.wmd.pojo.User">
select * from public."user"
<where>
重点1:使用foreach标签,
collection=map中list集合的key名称,
item=每个的id值,
open=前面的拼接,因为在where标签中,会自动去除第一个子句的and
close=结尾的拼接
separator=每个元素间的分割符
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id=#{id}
</foreach>
</where>
</select>
1.2测试类代码:
@org.junit.Test
public void testSelectUserForEarch(){
SqlSession sqlSession = MybatisTools.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map=new HashMap<String, Object>();
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
ids.add(4);
map.put("ids",ids);
List<User> userList = mapper.seletUserForEarch(map);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
示例2:如果想要执行sql:select * FROM public."user" WHERE id in(1,2,3,4)
<select id="seletUserForEarch" resultType="cn.com.wmd.pojo.User">
select * from public."user"
<where>
重点1:open=此处是id in ( 分割符是,
<foreach collection="ids" item="id" open="id in (" close=")" separator=",">
#{id}
</foreach>
</where>
</select>