动态sql语句

1.1 动态sql语句概述

Mybatis 的映射文件中,业务逻辑复杂时, SQL是动态变化的,此时在前面的学习中 SQL 就不能满足要求了。

参考的官方文档:
在这里插入图片描述

1.2 动态 SQL 之<if>

根据实体类的不同取值,使用不同的 SQL语句来进行查询
比如在 id 如果不为空时可以根据id查询,如果username 不为空时还要加入用户名作为条件。
这种情况在多条件组合查询中经常会碰到

  <select id="findColl" parameterType="user" resultType="user">
        select * from T_user
        <where> <!--表示where-->
            <if test="id!=0">
                 id=#{id}
            </if>
            <if test="username!=null and username!=''">
                and username=#{username}
            </if>
        </where>

编写dao接口:

//多条件查询
public List<User> findColl(User user);

当查询条件id和username都存在时,控制台打印的sql语句如下:

     @Test
    public void findCollT(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user=new User();
        user.setId(1);
        user.setUsername("张三");
        List<User> coll = mapper.findColl(user);
        System.out.println(coll.toString());
        
        MybatisUtils.closeSqlSession(sqlSession);
    }

在这里插入图片描述

当查询条件只有id存在时,控制台打印的sql语句如下:

 //获得MyBatis框架生成的UserDao接口的实现类
@Test
    public void findCollT(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User user=new User();
        user.setId(1);
        List<User> coll = mapper.findColl(user);
        System.out.println(coll.toString());MybatisUtils.closeSqlSession(sqlSession);
    }

在这里插入图片描述

总结语法:

<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
<if>:条件判断标签。
<if test=“条件判断”>
    查询条件拼接
</if>

1.3 动态sql之set (update insert)

  <!-- 动态语句 set 更新语句 update 表名 set name=#{name} -->
 <update id="updateMap" parameterType="map">
        update T_user 
        <set>
            <if test="username!=null">username=#{username},</if>
            <if test="sex!=null">sex=#{sex}</if>
        </set>
        <where>
            <if test="id!=null">id=#{id}</if>
        </where>
    </update>
    <!-- 动态语句 set 插入语句 insert into 表名 set name=#{name},age=#{age} -->
 
    <insert id="saveMap" parameterType="map">
        insert into T_user
        <set>
            <if test="id!=null">id=#{id},</if>
            <if test="username!=null">username=#{username},</if>
            <if test="sex!=null">sex=#{sex},</if>
            <if test="address!=null">address=#{address},</if>
            <if test="birthday!=null">birthday=#{birthday}</if>
        </set>
    </insert>

编写dao接口添加方法:

public int updateMap(Map<String ,Object> map);public int saveMap(Map<String ,Object> map);

测试类编写:

修改的测试方法
@Test
    public void updatemap(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);Map<String,Object> map=new HashMap<>();
        map.put("id",1);
        map.put("username","老六");
        map.put("sex","女");
        int i = mapper.updateMap(map);
        System.out.println(i);
    }
添加的测试方法
    @Test
    public void savemapT(){
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);Map<String,Object> map=new HashMap<>();
        map.put("username","老六");
        map.put("sex","女");
        map.put("address","郑州");
        map.put("birthday",Date.valueOf("2010-03-09"));
        int i = mapper.saveMap(map);
        System.out.println(i);
    }

总结语法:

<set>:条件标签。set 元素可以用于动态包含需要更新的列
<if>:条件判断标签。
<if test="条件判断">
    查询条件拼接
</if>

1.4 动态sql之choose (when, otherwise)

相当于Java中的switch语句

当when有条件满足的时候,就跳出choose

 <choose>
        <when test="条件1">...</when>
        <when test="条件2">...</when>
        <when test="条件3">...</when>
        <otherwise>其他条件</otherwise>
</choose>

代码演示步骤:

1、编写Dao接口代码

2、编写mapper文件

3、测试运行

代码实现:

编写Dao接口代码

public List<User> showUserfindAll(
       @Param("username") String username,
        @Param("sex") String sex,
        @Param("address") String address,
        @Param("birthday") Date birthday;

编写mapper文件

<!-- 动态语句choose when when otherwise -->
<!-- if elseif elseif else
    <choose>
        <when test=""></when>
        <when test=""></when>
        <when test=""></when>
        <otherwise>...</otherwise>
    </choose>-->
<select id="showUserfindAll" resultType="cn.zxy.pojo.User">
    select * from user where 
    <choose>
        <when test="username!=null and username!=''">
             username like concat("%",#{username},"%")
        </when>
        <when test="sex!=null and sex!=''">
             sex =#{sex}
        </when>
        <when test="address!=null and address!=''">
            address like concat("%",#{address},"%")
        </when>
        <otherwise>
             year(birthday)=year(#{birthday})
        </otherwise></choose>

另一种写法


 <select id="showUserfindAll" resultType="cn.zxy.pojo.User">
        select * from user 
	<where>
        <choose>
            <when test="username!=null">
              <choose>
                 <when test="username.indexOf('%')!=-1"> username like #{username}</when>
                 <when test="username.indexOf('_')!=-1">username like #{username}</when>
                 <otherwise>username = #{username}</otherwise>
              </choose>
            </when>
            <when test="sex!=null and sex!=''">
               sex =#{sex}
            </when>
            <when test="address!=null and address!=''">
                address like concat("%",#{address},"%")
            </when>
            <otherwise>
                birthday=#{birthday}
            </otherwise>
        </choose>
	</where>

    </select>

实体和数据库名字不匹配

<!-- 查询中如果表字段名和实体类名不一致,不想定义ResultMap,可以使用查询的列名 -->
<sql id="s1p">id,user_name username,birthday birth,address addr,sex sex</sql><select id="showUserfindAll" resultType="cn.zxy.pojo.User">
    select <include refid="s1p"/> from user where 1=1
    <choose>
        <when test="username!=null">
            <choose>
                <when test="username.indexOf('%')!=-1">user_name like #{username}</when>
                <when test="username.indexOf('_')!=-1">user_name like #{username}</when>
                <otherwise>user_name = #{username}</otherwise>
            </choose>
        </when>
        <when test="sex!=null and sex!=''">
            and sex =#{sex}
        </when>
        <when test="address!=null and address!=''">
            and address like concat("%",#{addr},"%")
        </when>
        <otherwise>
            and year(birthday)=year(#{birth})
        </otherwise>
    </choose>
</select>

测试运行

 @Test
    public void test() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        List<User> users = userDao.showUserfindAll("小_", "男", "河", null);
        System.out.println(users.toString());}

1.5 动态 SQL 之<foreach>

循环执行sql的拼接操作,例如:SELECT * FROM user WHERE id IN (1,2,5)。

foreach 迭代一个集合,通常用于in条件

属性:

  • item 查询条件

  • collection:必须指定

    • list

    • array

    • map—key

  • open : 括号 (

  • separator :分割符 ,

  • close :括号 )

例子如下

  <!--循环迭代-->
<select id="findByIds" parameterType="list" resultType="user">
    <!--
        collection: 表示集合存储类型 分别为 list array数组
           open : id in (  是指代  where id in(
           close: 闭合括号
           item : 查询条件
           separator: 分割符
    -->
    select * from T_user
    <where>
    <foreach collection="list" open="id in (" close=")" item="id" separator=",">
        #{id}
    </foreach>
    </where>
</select>

编写dao接口:

//根据多个id查询
public List<User> findByIds(List<Integer> ids);

测试代码片段如下:

 @Test
    public void findByidst() {
        //获取sqlssession给定的对象
        SqlSession sqlSession = MybatisUtils.getSqlSession(true);
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //创建list集合 并赋值
        List<Integer> list=new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(5);
        //把集合里面的值赋给mapper
        List<User> byIds = mapper.findByIds(list);
        for (User byId : byIds) {
            System.out.println(byId);
        }
        MybatisUtils.closeSqlSession(sqlSession);
    }

批量插入:

Mapper接口编写

public  void insert(List<User> list);

映射文件编写:

 <insert id="insert" parameterType="user">
        insert into user values
        <foreach collection="list" separator="," item="user">
            (#{user.id},#{user.username},#{user.sex},#{user.address},#{user.birthday})
        </foreach>
    </insert>

测试类编写:

 @Test
    public void inTest(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession(true);
        DUserMapper mapper = sqlSession.getMapper(DUserMapper.class);
        long start=System.currentTimeMillis();
        log.info("开始的时间{}",start);
        List<User> userList=new ArrayList<>();
        User user;
        for (int i = 0; i < 5; i++) {
            user=new User();
            user.setUsername("唐"+i);
            user.setSex("男");
            user.setAddress("河南北京");
            user.setBirthday(new Date());
            userList.add(user);
        }
        mapper.insert(userList);
        long end = System.currentTimeMillis();
        log.info("结束的时间{}",(end-start));
    }

总结语法:

<foreach>:循环遍历标签。适用于多个参数或者的关系。
    <foreach collection="" open="" close="" item="" separator="">
        获取参数
    </foreach>

属性
collection:参数容器类型, (list-集合, array-数组)
open:开始的 SQL 语句 id in (
close:结束的 SQL 语句
item:参数变量名
separator:分隔符

1.6 SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

<!--抽取sql片段简化编写-->
<sql id="selectUser" select * from student</sql>
<!--根据id查询-->
<select id="findById" parameterType="int" resultType="user">
    <include refid="selectUser"></include> where id=#{id}
</select>
<!--根据ids遍历-->
<select id="findByIds" parameterType="list" resultType="student">
    <include refid="selectUser"></include>
    <where>
        <foreach collection="array" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

总结语法:

我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果。

-  <sql>:抽取 SQL 语句标签。 
-  <include>:引入 SQL 片段标签。 
   <sql id=“片段唯一标识”>抽取的 SQL 语句</sql> 
<include refid=“片段唯一标识”/>
 

1.7 知识小结

MyBatis映射文件配置:

<select>:查询
​
<insert>:插入
​
<update>:修改
​
<delete>:删除
​
<where>:where条件
​
<if>:if判断
​
<foreach>:循环
​
<sql>:sql片段抽取
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/39011.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

园区能源控制管理系统

园区能源控制管理系统是一种能够实现对园区内能源消耗、供应和分配进行实时监控、管理和控制的系统。该系统通过对园区内各种能源设备的数据采集、处理和分析&#xff0c;为管理者提供实时的能源使用情况和数据分析&#xff0c;从而帮助管理者制定科学的能源管理策略和节能措施…

3Ds max图文教程:高精度篮球3D建模

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 第 1 步。使用以下设置在顶部视口上创建球体&#xff1a; 第 2 步。将球体转换为可编辑的多边形&#xff1a; 第 3 步。转到 Edge 子对象级别并剪切以下边缘&#xff1a; 第 4 步。选择以下边&#xff0c;然…

github 最简单的使用步骤(个人学习记录~)

github 使用步骤&#xff1a; (11条消息) github新手用法详解&#xff08;建议收藏&#xff01;&#xff01;&#xff01;&#xff09;_github详解_怪 咖的博客-CSDN博客 1.获取ssh密钥 打开输入&#xff1a;ssh-keygen -t rsa -C “git账号” 输入之后一路Enter&#xff08…

Kubernetes Service的过程

文章目录 Kubernetes Service的实现基础内容1. 命令 ip route show table all2. DNAT3. IPVS和iptables4. Service Service的实现简述 Kubernetes Service的实现 基础内容 在了解Service之前,需要先了解一些额外的知识: 命令: ip route show table allDNATIPVS和iptables基础…

【云原生】K8S单节点搭建

Kubernetes Kubernetes基础概念架构1、基础环境2、安装kubelet、kubeadm、kubectl 2、使用kubeadm引导集群1、下载各个机器需要的镜像2、初始化主节点 Kubernetes核心实战Pod Kubernetes基础概念 kubernetes具有以下特性&#xff1a; ● 服务发现和负载均衡 Kubernetes 可以使…

EasyCVR录像阈值配置未生效,是什么原因?

有用户反馈&#xff0c;在平台中设置了录像阈值不生效&#xff0c;导致磁盘爆满。针对该反馈&#xff0c;我们立即进行了排查。 EasyCVR基于云边端一体化架构&#xff0c;可支持多协议、多类型设备接入&#xff0c;在视频能力上&#xff0c;平台可实现视频直播、录像、回放、检…

小白带你学习Linux的rsync的基本操作(二十四)

目录 前言 一、概述 二、特性 1、快速 2、安全 三、应用场景 四、数据的同步方式 五、rsync传输模式 六、rsync应用 七、rsync命令 1、格式 2、选项 3、举例 4、配置文件 5、练习 八、rsyncinotfy实时同步 1、服务器端 2、开发客户端 前言 Rsync是一个开源的…

分布式应用之zookeeper集群+消息队列Kafka

一、zookeeper集群的相关知识 1.zookeeper的概念 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的功能…

【深入探究人工智能】:历史、应用、技术与未来

深入探究人工智能 前言人工智能的历史人工智能的应用人工智能的技术人工智能的未来当代的人工智能产物结语&#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &am…

软件渗透测试真的很重要吗?渗透测试有哪些测试流程?

软件渗透测试是指通过模拟恶意攻击者的行为&#xff0c;评估软件系统中的潜在安全漏洞和弱点的活动。这种安全测试方法能够帮助开发人员和系统管理员发现并修复潜在的安全漏洞&#xff0c;以确保软件系统的安全性和完整性。软件渗透测试是一项高度技术性的任务&#xff0c;需要…

Docker 基本管理

Docker 基本管理 一&#xff1a;Docker 概述1.容器化越来越受欢迎&#xff0c;因为容器是&#xff1a;2.Docker与虚拟机的区别&#xff1a;3.Docker核心概念&#xff1a; 二&#xff1a;安装 Docker1.安装依赖包2.设置阿里云镜像源3.安装 Docker-CE并设置为开机自动启动4.查看 …

Storage、正则表达式

1 LocalStorage 2 SessionStorage 3 正则表达式的使用 4 正则表达式常见规则 5 正则练习-歌词解析 6 正则练习-日期格式化 Storage-Storage的基本操作 // storage基本使用// 1.token的操作let token localStorage.getItem("token")if (!token) {console.log(&q…

SpringBoot读取配置的6种方式

1. 概述 通过了解springboot加载配置&#xff0c;可以更方便地封装自定义Starter。 在SpringBoot中&#xff0c;可以使用以下6种方式读取 yml、properties配置&#xff1a; 使用Value注解&#xff1a;读取springboot全局配置文件单个配置。使用Environment接口&#xff1a;通过…

J-Flash烧录工具如何添加新的芯片类型

0 Preface/Foreword 1 添加方法 1.1 修改JLinkDevices.xm <!-- --> <!-- CMS --> <!-- --> <Device> <ChipInfo Vendor"CMS32" Name"CMS32L051" Core"JLINK_CORE_CORTEX_…

每天一点Python——day58

#第五十八天 集合间的关系&#xff1a; 类似于数学中学到的集合一样&#xff0c;关系差不多&#xff0c;譬如相等&#xff0c;子集&#xff0c;交集 如图所示&#xff1a;#①两个集合是否相等&#xff1a;运用运算符【等号】或者运算符&#xff01;【不等号】进行判断 #例&…

企业电子招标采购系统源码Spring Cloud + Spring Boot + MybatisPlus + 前后端分离 + 二次开发

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

3Ds max入门教程:快捷键命令和鼠标热键大全

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 起初&#xff0c;您可能需要花一些时间查找热键&#xff0c;但是一旦您使用它们记住了它们&#xff0c;它们将使您以至少两倍的速度产生结果。例如&#xff0c;当您进行建模&#xff08;移动、缩放、旋转等…

allure环境搭建

allure环境搭建 在搭建之前你应该有python、pycharm allure介绍 官网&#xff1a;https://docs.qameta.io/allure/ 英文介绍 Allure Framework is a flexible lightweight multi-language test report tool that not only shows a very concise representation of what have…

青岛大学_王卓老师【数据结构与算法】Week05_13_队列的顺序表示和实现1_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c; 另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础…

Mysql教程(一):Mysql数据模型和SQL语法分析

Mysql教程&#xff08;一&#xff09;&#xff1a;Mysql数据模型和SQL语法分析 1、Mysql数据模型 1.1 关系型数据库&#xff08;RDBMS&#xff09; 概念&#xff1a;建立在关系模型基础上&#xff0c;由多张相互连接的二维表组成的数据库。 特点&#xff1a; 使用表存储数…