14 动态SQL
张创琦 2022.03.13
减少拼接SQL语句的麻烦之处。
1 where 标签在 select 中的作用
原来的动态SQL写法,十分麻烦,容易出错。
/*原有的多条件分析:都是通过java中的字符串拼接实现String sql="select * from team where 1 = 1 ";// 如果用户输入了名称,就模糊查询and teamName like '%?%'// 如果用户输入了日期,按照日期区间查询and createTime> ? and createTime< ?//如果输入了地区,按照地区查询and location =?";*/if(vo.getName()!=null && !"".equals(vo.getName().trim())){sql+=" and teamName like '%"+vo.getName().trim()+"%'";}if(vo.getBeginTime()!=null ){sql+=" and getEndTime>"+vo.getBeginTime();}if(vo.getBeginTime()!=null ){sql+=" and createTime<="+vo.getEndTime();}if(vo.getLocation()!=null && !"".equals(vo.getLocation().trim())){sql+=" and location ="+vo.getLocation().trim();}
QueryTeamVO.java
package com.kkb.pojo;import java.util.Date;/*** ClassName: QueryVO* 自己封装的球队查询条件* @author wanglina* @version 1.0*/public class QueryTeamVO {private String name;private Date beginTime;private Date endTime;private String location;public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBeginTime() {return beginTime;}public void setBeginTime(Date beginTime) {this.beginTime = beginTime;}public Date getEndTime() {return endTime;}public void setEndTime(Date endTime) {this.endTime = endTime;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}}
TeamMapper.java接口添加:
List<Team> queryByVO(QueryTeamVO vo);
TeamMapper.xml映射文件添加:
<!--多条件查询:模糊查询的写法可以使用3种方式:方式1: and teamName like #{name} ,传递参数的时候带上%,例如vo.setName("%人%")方式2: and teamName like ‘%${name}%’ 传递参数的时候没有%,例如vo.setName("人")方式3: and teamName like concat(concat('%',#{name}),'%') 例如vo.setName("人") concat(str1,str2)函数是字符串拼接使用--><select id="queryByVO" parameterType="QueryVO" resultMap="baseResultMap">select * from team<where><!-- 如果用户输入了名称,就模糊查询 and teamName like '%?%'--><if test="name!=null ">and teamName like concat(concat('%',#{name}),'%')</if><if test="beginTime!=null ">and createTime>=#{beginTime}</if><if test="endTime!=null ">and createTime<=#{endTime}</if><if test="location!=null ">and location=#{location}</if></where></select>
TestSQL.java
package com.kkb.test;import com.kkb.mapper.TeamMapper;import com.kkb.pojo.QueryTeamVO;import com.kkb.pojo.Team;import com.kkb.utils.MybatisUtil;import org.junit.Test;import java.util.Date; import java.util.List;/*** ClassName: TestSQL* 测试类* @author wanglina* @version 1.0*/public class TestSQL {private TeamMapper teamMapper = MybatisUtil.getSqlSession().getMapper(TeamMapper.class);@Testpublic void test1(){QueryTeamVO vo=new QueryTeamVO();vo.setName("人");// 依次添加查询条件添加控制台的SQL语句//vo.setEndTime(new Date());//依次添加查询条件观察控制台的SQL语句//vo.setLocation("加利福尼亚州洛杉矶");//依次添加查询条件观察控制台的SQL语句List<Team> teams = teamMapper.queryByVO(vo);for (Team team : teams) { System.out.println(team);}}}
运行结果:
Preparing: select * from team WHERE teamName like concat(concat('%',?),'%')
2 set 标签在 update 中的作用
1 更新的原有写法
- TeamMapper.java接口中的方法:
int update(Team team);
- TeamMapper.xml映射文件对应的内容:
<update id="update" parameterType="com.kkb.pojo.Team">update team set teamName=#{teamName},location=#{location},createTime=#{createTime} where teamId=#{teamId}</update>
- 测试类中添加测试方法:
TeamMapper teamMapper=MybatisUtil.getSqlSession().getMapper(TeamMapper.class);@Testpublic void test2(){Team team=new Team();team.setTeamId(1055); team.setTeamName("lina");int update = teamMapper.update2(team);MybatisUtil.getSqlSession().commit();System.out.println(update);}
测试结果:
DEBUG [main] - ==> Preparing: update team set teamName=?,location=?,createTime=? where teamId=?DEBUG [main] - ==> Parameters: lina(String), null, null, 1063(Integer)DEBUG [main] - <== Updates: 1DEBUG [main] - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@64cd705f]1
弊端:没有赋值的属性会被赋值为空。
2 使用set标签构建动态的SQL语句
- TeamMapper.java接口中添加方法:
int update1(Team team);
- TeamMapper.xml映射文件对应的内容:
<update id="update1" parameterType="com.kkb.pojo.Team"> update team<set><if test="teamName!=null"> teamName=#{teamName},</if><if test="location!=null"> location=#{location},</if><if test="createTime!=null"> createTime=#{createTime},</if></set>where teamId=#{teamId}</update>
- 测试代码
@Testpublic void test2(){Team team=new Team();team.setTeamId(1055);team.setTeamName("lina");int update = teamMapper.update1(team);MybatisUtil.getSqlSession().commit();System.out.println(update);}
- 测试结果
DEBUG [main] - ==> Preparing: update team SET teamName=? where teamId=?DEBUG [main] - ==> Parameters: lina(String), 1055(Integer)DEBUG [main] - <== Updates: 0DEBUG [main] - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@20deea7f]0
优点:动态SQL只更新非空属性列。
3 forEach 标签
1 批量添加
- TeamMapper.java接口中添加方法:
void addList(List<Team> list);
- TeamMapper.xml映射文件对应的内容:
<!--批量添加--><insert id="addList" parameterType="arraylist"> INSERT INTO team (teamName,location) VALUES<!--collection:要遍历的集合;参数是集合类型,直接写listitem:遍历的集合中的每一个数据separator:将遍历的结果用,分割--><foreach collection="list" item="t" separator=","> (#{t.teamName},#{t.location})</foreach></insert>
- 编写测试类
@Testpublic void test3(){List<Team> list=new ArrayList<>();for(int i=1;i<=3;i++){Team team=new Team();team.setTeamName("lina"+i);team.setLocation("bj"+i);list.add(team);}teamMapper.addList(list);MybatisUtil.getSqlSession().commit();}
- 运行结果
DEBUG [main] - ==> Preparing: INSERT INTO team (teamName,location) VALUES (?,?) , (?,?) , (?,?)DEBUG [main] - ==> Parameters: lina1(String), bj1(String), lina2(String), bj2(String), lina3(String), bj3(String)DEBUG [main] - <== Updates: 3DEBUG [main] - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3835c46]
2 批量删除
- TeamMapper.java接口中添加方法:
void delList(List<Integer> list);
- TeamMapper.xml映射文件对应的内容:
<!-- 批量删除 --><delete id="delList" >delete from team where teamId in<!--collection:要遍历的集合;参数是集合类型,直接写list item:遍历的集合中的每一个数据separator:将遍历的结果用,分割open="(" close=")":表示将遍历结果用open close包裹起来--><foreach collection="list" item="teamId" separator="," open="(" close=")">#{teamId}</foreach></delete>
- 编写测试类
@Testpublic void test4() {List<Integer> list = new ArrayList<>();list.add(1109);list.add(1110);list.add(1111);teamMapper.delList(list);MybatisUtil.getSqlSession().commit();}
- 代码结果
DEBUG [main] - ==> Preparing: delete from team where teamId in ( ? , ? , ? )DEBUG [main] - ==> Parameters: 1109(Integer), 1110(Integer), 1111(Integer)DEBUG [main] - <== Updates: 0DEBUG [main] - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3835c46]
