美文网首页
04动态sql

04动态sql

作者: RobertLiu123 | 来源:发表于2019-07-18 16:27 被阅读0次

学习以下动态sql语句

if(多条件动态拼接)
2)where(解决where and/or情况)
3)set(解决update语句多逗号情况 与update一起用)
4)trim(**可以前后追加,同时还能用指定字符分隔语句,还可以去除语句前后的指定字符)
5)foreach(拼装in语句)
6)sql片段(提取出公用的sql)
7)choose(选择很多情况下的一种,和 Java 中的 switch语句相似

if(多条件动态拼接)
1)页面让用户输入查询条件
用户名 身份证号 邮箱
后台动态判断他输入了什么
如果输入了用户名我就把用户名做为选择条件
如果输入了身份证号我就把身份证号做为选择条件
如果输入了邮箱我就把邮箱做为选择条件
select * from t_user
where (如果输入用户名 username=#{username})
(如果输入身份证号 and/or idcard=#{useridcard})
(如果输入邮箱 and/or email=#{useremail})
样例代码
接口

public interface UserSqlMapper {
  public User getUser(User user);
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.neuedu.day02.mapper.UserSqlMapper">
<select id="getUser" parameterType="User" resultType="user">
select * from t_user where 
<if test="user_name!=null and user_name!=''">
 user_name=#{user_name}
</if>
<if test="user_email!=null and user_email!=''">
 and user_email=#{user_email}
</if>
<if test="user_idCard!=null and user_idCard!=''">
 and user_idCard=#{user_idCard}
</if>
</select>
</mapper>

测试类以下方法调用usersqlmapper下的

   @Test
   public void testFind() throws IOException{
       IUserDao userDao=new UserDaoImpl(factory);
       User user=new User();
       user.setUser_name("chenhao");
       user.setUser_email("chenhao.newedu.com");
       user.setUser_idCard("210101200006061234");
       User dbuser=userDao.getUser(user);
       System.out.println(dbuser.getUser_name());
   }

如果上述查询不输入用户名,会出现where直接加and/or的情况,导致查询不到结果
where(解决if多条件拼装时,如果第一个条件不存在,where+and/or的问题。)
把上面的statement稍微改写一个。改写成用where子句把if包起来。即下面这样:

<select id="getUser" parameterType="User" resultType="user">
select * from t_user 
<where> 
<if test="user_name!=null and user_name!=''">
 user_name=#{user_name}
</if>
<if test="user_email!=null and user_email!=''">
 and user_email=#{user_email}
</if>
<if test="user_idCard!=null and user_idCard!=''">
 and user_idCard=#{user_idCard}
</if>
</where>
</select>

set(解决update语句多逗号情况 与update一起用)
关键代码
UserSqlMapper.xml

<update id="updateUser" parameterType="user">
update t_user set
<if test="user_name!=null and user_name!=''">
user_name=#{user_name},
</if>
<if test="user_email!=null and user_email!=''">
user_email=#{user_email},
</if>
<if test="user_idCard!=null and user_idCard!=''">
user_idcard=#{user_idCard},
</if>
<if test="user_pwd!=null and user_pwd!=''">
user_pwd=#{user_pwd}
</if>
where  user_id=#{user_id}
</update>

测试类:

@Test
   public void testUpdate() throws IOException{
       IUserDao userDao=new UserDaoImpl(factory);
       User user=new User();
       //主键必须带
       user.setUser_id(8);
       //user.setUser_name("chenhao");
       user.setUser_pwd("654321");
       user.setUser_email("chenhao@newedu.com");
       user.setUser_idCard("210101200006061233");
       int count=userDao.updateUserSql(user);
       System.out.println(count);
   }

上面的语句如果最后一个条件没有输入,会有多余的逗号,导致语句出错,把set写成动态的,也就是用<set> </set>把IF语句把起来,能够解决上述问题。
上面的语句改造成下面的形式

<update id="updateUser" parameterType="user">
update t_user 
<set>
<if test="user_name!=null and user_name!=''">
user_name=#{user_name},
</if>
<if test="user_email!=null and user_email!=''">
user_email=#{user_email},
</if>
<if test="user_idCard!=null and user_idCard!=''">
user_idcard=#{user_idCard},
</if>
<if test="user_pwd!=null and user_pwd!=''">
user_pwd=#{user_pwd}
</if>
</set>
where  user_id=#{user_id}
</update>

第二节
trim(可以前后追加,同时还能用指定字符分隔语句,还可以去除语句前后的指定字符)
格式:

<trim prefix="" suffix="" prefixOverrides="" suffixOverrides=""></trim>

其中:prefix:前面加上什么
suffix:后面加上什么
prefixOverrides:前面去掉什么
suffixOverrides:后面去掉什么
他可以替代前面的set where
举例如果想动态拼装inset语句:

insert into t_user (key1,key2)
values (value1,value2)

我们可以通过更改上下两个括号的部分来实现
来试一下
*注意如果字段是int类型,user_power=0时,user_power!=''为true
所以,
关键代码:
动态的insert的xml为

<insert id="insertUserSql" parameterType="User">
insert into t_user 
<trim prefix="(" suffix=")" suffixOverrides=",">
user_id,
<if test="user_name!=null and user_name!=''">
user_name,
</if>
<if test="user_pwd!=null and user_pwd!=''">
user_pwd,
</if>
<if test="user_email!=null and user_email!=''">
user_email,
</if>
<if test="user_idcard!=null and user_idcard!=''">
user_idcard,
</if>
<if test="user_power!=null">
user_power,
</if>
</trim>
 values 
<trim prefix="(" suffix=")" suffixOverrides=",">
null,
<if test="user_name!=null and user_name!=''">
#{user_name},
</if>
<if test="user_pwd!=null and user_pwd!=''">
#{user_pwd},
</if>
<if test="user_email!=null and user_email!=''">
#{user_email},
</if>
<if test="user_idcard!=null and user_idcard!=''">
#{user_idcard},
</if>
<if test="user_power!=null">
#{user_power},
</if>
</trim>

对应的测试类为:

 @Test
   public void testInsert() {
       IUserDao userDao=new UserDaoImpl(factory);
       User user=new User();
       user.setUser_name("gujunn");
       user.setUser_pwd("123456");
       user.setUser_power(0);
       //user.setUser_email("chenhao.newedu.com");
       //user.setUser_idCard("210101200006061234");
       int count=userDao.insertUserSql(user);
       System.out.println(count);
   }

第三节
foreach(拼装in语句)
注意:你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时
候,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list”
作为键,而数组实例将会以“array”作为键。
语法:

<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>

代码示例:用户批量删除功能
UserSqlMapper.xml

<delete id="delUserList">
<!-- 分析批量删除语句delete from t_user where user_id in (1,2,3,4,5) 
上述语句需要动态拼(1,2,3,4,5)
foreach可以实现循环拼接
如果传递参数为list,collection="list"(固定写法)
前面加(  open="("
后面加)  close=")"
中间加,  separator=","
-->
delete from t_user where user_id in 
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>

接口里对应方法UserSqlMapper.java

public int delUserList(List ids);

测试用例:UserSqlServiceTest.java

@Test
   public void testDeleteBatch() throws IOException{
       SqlSession session=factory.openSession();
       //执行查询
       UserSqlMapper mapper=session.getMapper(UserSqlMapper.class);
       List<Integer> ids=new ArrayList();
       ids.add(10);
       ids.add(8);
       int count=mapper.delUserList(ids);
       System.out.println(count);
       //关闭连接
       session.close();
   }

学生练习:
批量删除传入参数为Array
关键代码UserSqlMapper.xml

<delete id="delUserArray">
<!-- 分析批量删除语句delete from t_user where user_id in (1,2,3,4,5) 
上述语句需要动态拼(1,2,3,4,5)
foreach可以实现循环拼接
如果传递参数为数组,collection="array"(固定写法)
前面加(  open="("
后面加)  close=")"
中间加,  separator=","
-->
delete from t_user where user_id in 
<foreach collection="array" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>

问题:前面两个方法的sql语句中有重复的部分 delete from t_user where user_id in 为了减少代码冗余,我们引入sql片段
sql片段(提取出公用的sql)

<sql id="delusersql">
delete from t_user where user_id in 
</sql>

再将上面的statement改造成如下形式

<delete id="delUserArray">
<!--refid与sql的id对应-->
<include refid="delusersql"/>
<foreach collection="array" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>

choose(选择很多情况下的一种,和 Java 中的 switch语句相似) (手册41页)##
作业:
练习上面的代码,完成用户动态添加、修改、批量删除、动态拼接查询语句

相关文章

  • 04动态sql

    学习以下动态sql语句 if(多条件动态拼接)2)where(解决where and/or情况)3)set(解决u...

  • MyBatis学习:动态sql

    1.动态sql 动态sql是mybatis中的一个核心,什么是动态sql?动态sql即对sql语句进行灵活操作,通...

  • 第十三章 使用动态SQL(一)

    第十三章 使用动态SQL(一) 动态SQL简介 动态SQL是指在运行时准备并执行的SQL语句。在动态SQL中,准备...

  • 第八章 动态SQL

    动态SQL中的元素介绍 动态SQL有什么作用 MyBatis提供了对SQL语句动态组装的功能 动态SQL中的元素 ...

  • 关于Mybatis的一些问题讨论

    Mybatis动态sql是做什么的?都有哪些动态sql?简述一下动态sql的执行原理 动态sql的用途 Mybat...

  • MyBatis5-动态 SQL

    动态 SQL 什么是动态 SQL 就是动态的对 SQL 进行组装 拼接. : 可以自动去...

  • mybatis 04 动态sql

    myBatis-conf.xml userMapper.xml 类 补充:输出mybatis中的sql语句 1. ...

  • geoserver动态颜色参数样式、动态sql配置实现

    geoserver动态颜色参数样式、动态sql配置实现 动态颜色参数样式、动态sql 访问方式: http://l...

  • 强大的动态SQL

    1 动态SQL# 那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家...

  • MyBatis:动态 SQL

    1. 动态 SQL 简而言之,动态 SQL 就是在 Mapper 中使用分支、循环等逻辑。常见的动态 SQL 元素...

网友评论

      本文标题:04动态sql

      本文链接:https://www.haomeiwen.com/subject/mknllctx.html