动态sql

2023-05-16

1.什么是动态sql

sql的内容是变化的, 可以根据条件获取到不同的sql语句.
主要是where部分发生变化。
动态sql的实现, 使用的是mybatis提供的标签

2.为什么使用动态sql

使用动态sql可以解决某些功能的使用 例如使用条件查询某个商品 你输入价格,地区等等进行筛选,如果使用静态sql可能会查询出来的是一个空内容 但使用动态sql可以很好的解决这种问题 例如
在这里插入图片描述

3.动态sql的标签

在这里插入图片描述

3.1 if标签-单条件判断

作用:筛选条件语句
dao层方法为:

public User findConditon(@Param("name")String name, @Param("email")String email);

mapper层

 <!--如果姓名不为空则安姓名查找 如果姓名为空则按邮箱查找 否则查询全部-->
    <select id="findConditon" resultType="com.wx.entity.User">
        select * from tbl_user02
        <where>
            <if test="name!=null and name!=''">
                and name = #{name}
            </if>
            <if test="email!=null and email!=''">
                and email = #{email}
            </if>
        </where>
    </select>

3.2 choose标签 多条件分支判断

//当三者不为空的时候 按姓名 密码 邮件查询 三个条件都会执行一遍
public User findByCondition(@Param("name")String name, @Param("email")String email,
                                @Param("pwd")String pwd);
                                
<select id="findByCondition" resultType="com.wx.entity.User">
        select * from tbl_user02
        <where>
            <choose>
                <when test="name!=null and name!=''">
                    and name = #{name}
                </when>
                <when test="email!=null and email!=''">
                    and email = #{email}
                </when>
                <otherwise>
                    and pwd = #{pwd}
                </otherwise>
            </choose>
        </where>
    </select>

3.3 where语句

如果不使用where语句 就要在where其他判断语句前加入1=1 如 select * from tbl_user02 where 1=1加其他的if判断语句 如果我们不加入这个1=1就可以直接使用where语句 上面的choose和if都搭配使用 使用where 语句 可以自动消除第一个条件中的and 且加上where 例子如上面两个标签中即可

3.4set标签

这个标签配合if标签一起用 一般用于修改语句 如果传递的参数为null 那么就不会修改该列的值

 public int updateUser(User user);

//这里注意 test="参数" 这里的参数 是前端传过来的值就是你前端页面上是什么 这里就要写什么 
//而下面的name=#{name} 第一个name是你数据库中的字段 #{name}中是你的前端传过来的值
<update id="updateUser" parameterType="User">
        update tbl_user02
        <set>
            <if test="name!=null and name!=''">
                name=#{name},
            </if>
            <if test="pwd!=null">
                pwd=#{pwd},
            </if>
            <if test="email!=null">
                email=#{email},
            </if>
        </set>
        where id = #{id}
    </update>

3.4foreach标签

循环标签 适用于批量添加、删除 和查询记录

3.4.1用于批量查询

查询id为1 3 5 的用户信息
正常sql语句为 select * from tbl_user02 where id in(1,3,5);
下面的为使用foreach遍历 循环查询
    解释:
    <foreach collection="集合类型" open="开始的字符" close="结束的字符"
	    item="集合中的成员" separator="集合成员之间的分割符">
        #{item的值}
    </foreach>
   标签属性:
   collection:表示循环的对象是数组还是list集合。如果dao方法的形参是数组,collection="array";
		如果dao方法形参是list,collection="list";
   open:循环开始的字符。sql.append("(");
   close:循环结束的字符。sql.append(")");
   item:集合成员,自定义的变量。Integer item = idList.get(i);
   separator:集合成员之间的分隔符。sql.append(",");
   #{item的值}:获取集合成员的值;

具体代码实现
dao层

//传递的参数为id数组所以mapper层的collection="list"
public List<User> findByIds(Integer[] ids);

mapper层为

    <select id="findByIds" resultType="com.wx.entity.User">
        select * from tbl_user02 where id in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

测试类为:

@Test
    public void testFindByIds() throws Exception{
        Reader rd = Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        Integer[] ids = {1,3,5};
        List<User> user = userDao.findByIds(ids);
        System.out.println(user);
        session.close();
    }

查询出三条记录
在这里插入图片描述

3.4.2用于批量删除

dao层

public int BatchDelete(Integer[] ids);

mapper层

  <delete id="BatchDelete">
        delete from tbl_user02 where id in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

测试类:

@Test
    public void testBatchDelete() throws Exception{
        Reader rd = Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        Integer[] ids = {1,3,5};
        int row = userDao.BatchDelete(ids);
        System.out.println(row);
        session.commit();
        session.close();
    }

在这里插入图片描述

3.4.3用于批量添加

dao层

public int batchAdd(List<User> users);

mapper层

   <!--注意 因为循环添加的为一个对象 所以下面添加的值就必须是users.name ...-->
    <insert id="batchAdd">
        insert into tbl_user02(name,pwd,email) values
        <foreach collection="list" item="users" separator=",">
            (#{users.name},#{users.pwd},#{users.email})
        </foreach>

    </insert>

测试类:

@Test
    public void testBatchAdd() throws Exception{
        Reader rd = Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        List<User> list = new ArrayList<User>();
        list.add(new User("张三","123","zs@qq.com"));
        list.add(new User("李四","123","ls@qq.com"));
        list.add(new User("王五","123","ww@qq.com"));
        int row = userDao.batchAdd(list);
        System.out.println(row);
        session.commit();
        session.close();
    }

在这里插入图片描述

3.4.4sql片段

一般用于查询语句的时候 select * … 这种不推荐 所以用sql片段可以很好的解决这个问题
在这里插入图片描述

4.mybatis映射文件处理特殊字符.

当我们使用条件语句查询的时候 就比如在某个范围中使用条件如 money>100 and money<200
这个条件在mapper中无法直接写所以需要特殊处理,有两种解决办法:

   第一种:转义标签 &nbsp; &lt;  
   第二种: <![CDATA[sql]]>

<select id="findByMaxAndMin" resultType="com.ykq.entity.Account">
       <![CDATA[select * from account where id >#{min} and id <#{max}]]>
</select>

第一种:转义字符处理
dao层

 public User findByMaxAndMin(@Param("min") int min,@Param("max") int max);

mapper层

 <select id="findByMaxAndMin" resultType="com.wx.entity.User">
        select * from tbl_user02 where id &gt;#{min} and id &lt; #{max}
    </select>

测试类

    @Test
    public void testFindByMaxMin() throws Exception{
        Reader rd = Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        User user = userDao.findByMaxAndMin(1, 3);
        System.out.println(user);
        session.commit();
        session.close();
    }

在这里插入图片描述
第二种: <![CDATA[sql]]>

dao层

public User findByMaxAndMin01(@Param("min") int min,@Param("max") int max);

实体层

<select id="findByMaxAndMin01" resultType="com.wx.entity.User">
         <![CDATA[select * from tbl_user02 where id>#{min} and id<#{max}]]>
    </select>

测试类

 @Test
    public void testFindByMaxMin01() throws Exception{
        Reader rd = Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        User user = userDao.findByMaxAndMin01(1, 3);
        System.out.println(user);
        session.commit();
        session.close();
    }

在这里插入图片描述

5.mybatis完成模糊查询

语法:select * from 表名 where 列名 like ‘%a%’ 但是% a %这样在mapper层无法使用 解决办法有两种
第一种:使用字符串函数(concat)完成拼接
dao层

    /*模糊查询*/
    public User findByName(@Param("name")String name);

mapper层

<select id="findByName" resultType="com.wx.entity.User">
        select * from tbl_user02 where name like concat('%',#{name},'%');
    </select>

测试类

    @Test
    public void testFindByName() throws Exception{
        Reader rd = Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
        SqlSession session = factory.openSession();
        UserDao userDao = session.getMapper(UserDao.class);
        User user = userDao.findByName("李");
        System.out.println(user);
        session.close();
    }

在这里插入图片描述
第二种:使用${}

 <select id="findByName" resultType="com.wx.entity.User">
        select * from tbl_user02 where name like '%${name}%';
    </select>

两者区别:concat不能解决sql注入的问题 第二种是预编译 可以解决sql注入问题

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态sql 的相关文章

  • SQL - != 'NULL' 的解释

    我的SSMS代码如下 Select top 50 From FilteredContact Where statuscode 1 and emailaddress1 NULL and telephone1 NULL and address1
  • 在 Oracle 行的多个列上使用透视

    我在 Oracle 表中有以下示例数据 tab1 我正在尝试将行转换为列 我知道如何在某一列上使用 Oracle 数据透视表 但是否可以将其应用于多个列 样本数据 Type weight height A 50 10 A 60 12 B 4
  • 如何找到多个列中的最小值

    我在我的 DB 3 col 中有一个值 我想在所有这些值中找到一个值 如下所述 表名 MyTable id col1 col2 col3 1 200 300 400 2 100 150 300 3 800 102 20 4 80 80 0
  • MySQL - 从临时表插入

    这看起来非常简单 但我坚持使用简单的插入语句 见下文 begin work CREATE TEMPORARY TABLE IF NOT EXISTS insert table AS select r resource id fr file
  • date_sub 对于 mysql 可以,对于 postgresql 可以

    此查询适用于 mySQL 不适用于 Postgresql select from where id and h gt date sub now INTERVAL 30 MINUTE 错误是 Query failed ERREUR erreu
  • 在单个 select 语句中多次有条件地求和同一列?

    我有一个表 显示每个月在给定位置的各种类型的部署的员工部署情况 ID Location ID Date NumEmployees DeploymentType ID 例如 一些记录可能是 1 L1 12 2010 7 1 Permanent
  • 在 MySQL 中对整数字段运行带引号的数字(字符串)查询时会发生哪些复杂情况

    在 SQL 中 不应引用整数 因为如果引用 它将是一个字符串 但我很好奇如果我这样做会出现什么问题 并发症 例如 SELECT FROM table WHERE id 1 正确的 vs SELECT FROM table WHERE id
  • 有没有办法阻止 SQL Express 2008 空闲?

    我使用 SQL Express 2008 作为 Web 应用程序的后端 问题是 Web 应用程序是在工作时间使用的 因此有时在午餐或休息时间 如果 20 分钟内没有用户登录 SQL Express 将进入空闲状态模式并释放其缓存 我知道这一
  • SQL 中基于下一条记录和上一条记录的复杂排序

    这是一个后续问题根据 SQL 中的下一条记录和上一条记录进行排序 https stackoverflow com questions 30477803 sorting based on next and previous records i
  • SQL 查询用于计算每个客户的订单数量和总金额

    我有两张桌子Order与列 OrderID OrderDate CID EmployeeID And OrderItem与列 OrderID ItemID Quantity SalePrice 我需要返回客户 ID CID 每个客户的订单数
  • 数据库字段中的逗号分隔值

    我有一个产品表 该表中的每一行对应一个产品 并由唯一的 ID 标识 现在 每个产品都可以有多个与该产品关联的 代码 例如 Id Code 0001 IN ON ME OH 0002 ON VI AC ZO 0003 QA PS OO ME
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 内置函数将每个单词的第一个字母大写

    如果 SQL Server 中已存在此类函数 我不想为此创建自定义函数 输入字符串 This is my string to convert预期输出 This Is My String To Convert SET ANSI NULLS O
  • 提高第一个查询的性能

    如果执行以下数据库 postgres 查询 则第二次调用要快得多 我猜第一个查询很慢 因为操作系统 linux 需要从磁盘获取数据 第二个查询受益于文件系统级别和 postgres 中的缓存 有没有一种方法可以优化数据库以快速获得结果fir
  • 如何在 DB2 中创建返回序列值的函数?

    如何在 DB2 中创建一个从序列中获取值并返回该值的函数 应该可以在 select 或 insert 语句中使用该函数 例如 select my func from xxx insert into xxx values my func 基本
  • 从 Getdate() 获取时间

    我想采取Getdate 结果 例如 2011 10 05 11 26 55 000 into 11 26 55 AM 我看过其他地方并发现 Select RIGHT CONVERT VARCHAR GETDATE 100 7 这给了我 11
  • 我不断收到错误“关系 [TABLE] 不存在”

    我一直在尝试查询数据库中的两个表 在服务器资源管理器中 我可以看到两个表 甚至可以看到其中的列 我们将它们称为 Schema table1 和 Schema table2 其中 Schema 的第一个字母大写 我尝试运行以下查询 selec
  • 快速将列的副本添加到 MySQL 表

    我需要一种快速的方法来复制表中的 DATETIME 列并为其指定一个新名称 我的表中有一个名为 myDate 的列 名为 myResults 我需要一个查询来在名为 newDate 的表中创建一个新列 该列的数据与 myDate 列完全相同
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 使用加权行概率从 PostgreSQL 表中选择随机行

    输入示例 SELECT FROM test id percent 1 50 2 35 3 15 3 rows 你会如何编写这样的查询 平均 50 的时间我可以获得 id 1 的行 35 的时间 id 2 的行 15 的时间 id 3 的行

随机推荐

  • HDFS API操作

    HDFS API操作 实验环境 Linux Ubuntu 16 04 前提条件 xff1a 1 xff09 Java 运行环境部署完成 2 xff09 Hadoop 的单点部署完成 上述前提条件 xff0c 我们已经为你准备就绪了 实验内容
  • HBase的安装部署和使用

    HBase的安装部署和使用 文章目录 HBase的安装部署和使用实验环境实验内容实验步骤1 点击 34 命令行终端 34 xff0c 打开新的命令行窗口2 解压安装包3 更改文件夹名和所属用户4 设置HBASE HOME环境变量5 修改hb
  • 熟悉常用的HBase操作

    熟悉常用的HBase操作 文章目录 实验环境实验内容1 编程实现以下指定功能 xff0c 并用Hadoop提供的HBase Shell命令完成相同的任务 xff08 1 xff09 列出HBase所有的表的相关信息 xff0c 如表名 创建
  • Hive的安装部署和管理

    Hive的安装部署和管理 文章目录 实验环境实验内容实验步骤1 点击 34 命令行终端 34 xff0c 打开新窗口2 解压安装包3 更改文件夹名和所属用户4 设置HIVE HOME环境变量5 导入MySql jdbc jar包到hive
  • Hive数仓:使用桶表

    Hive数仓 xff1a 使用桶表 文章目录 Hive数仓 xff1a 使用桶表实验环境实验步骤1 点击 34 命令行终端 34 xff0c 打开新窗口2 启动MySQL3 指定元数据数据库类型并初始化Schema4 启动Hadoop5 启
  • python 获取当前文件路径

    一 Python 获取当前文件路径方法 sys path 0 获取文件当前工作目录路径 绝对路径 sys argv 0 获得模块所在的路径 由系统决定是否是全名 若显示调用python指令 xff0c 如python demo py xff
  • PySpark中的RDD基本操作

    PySpark中的RDD基本操作 课程性质 xff1a PySpark数据处理 文章目录 1 实验目标2 本次实验主要使用的 P y t h
  • PySpark中的RDD创建

    PySpark中的RDD创建 课程性质 xff1a PySpark数据处理 文章目录 1 实验目标2 本次实验主要使用的 P y t h
  • el-table-column的formatter的使用

    当后端返回来的数据格式需要再去处理 xff1b 可以使用formatter属性 lt el table column label 61 34 性别 34 align 61 34 center 34 formatter 61 34 genda
  • 提示“无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系“的解决方案

    使用sudo apt get install lt packgename gt 时出现提示无法修正错误 xff0c 因为您要求某些软件包保持现状 xff0c 就是它们破坏了软件包间的依赖关系 可以换个命令 sudo aptitude ins
  • aosp下载、编译、刷机和单编framework(android 12)

    我的设备 xff1a 咸鱼上买的pixel 3a 一 aosp下载 1 安装repo mkdir bin PATH 61 bin PATH curl sSL 39 https gerrit googlesource proxy ustclu
  • LAMP架构之mysql的安装部署

    mysql的安装部署 一 mysql编译安装1 编译过程 二 LAMP架构的部署 一 mysql编译安装 官网地址如下 xff0c 进入选择版本 xff1a https downloads mysql com archives commun
  • hexo博客绑定自己的域名

    hexo博客绑定自己的域名 学习网址1 学习网址2 学习网址3 一 购买域名 登录阿里云账号 控制台 搜索框输入域名 域名注册 输入需要注册的域名 xff08 查看是否被占用 xff09 加入购物车 xff08 显示不能备案的不可买 xff
  • SimpleDateFormat类 格式化日期

    功能 xff1a 格式化和解析日期 将Date类型的日期格式化成我们需要的日期类型一般是 字符串类型将字符串类的日期再转回来 用到两个方法 format Date date xff1a 将date型转换成特定格式的字符串 parse Str
  • 队列(Java实现)

    1 1应用场景 银行排队 xff1a 1 2基本介绍 特点 队列是一个有序列表 xff0c 可以用数组或是链表来实现 遵循先入先出的原则 即 xff1a 先存入队列的数据 xff0c 要先取出 后存入的要后取出 示意图 解释 MaxSize
  • IO字节流读取文本中文乱码

    1 1问题说明 我们都知道字符流适用于读取文本 xff0c 而字节流能读取文本 照片 视频等 xff0c 但是用字节流读取文本到我们程序的控制台中会出现中文乱码的情况 xff0c 如下图 我的文本中的数据是 生活很简单 xff0c 过了今天
  • glibc所安装的工具程序

    catchsegv 当程序发生segmentation fault的时候 用来建立一个 堆栈跟踪 gencat 建立消息列表 getconf 针对文件系统的指定变量显示其系统设置值 getent 从 系统管理数据库获取一个条目 glibcb
  • 单链表(java实现)

    1 1 链表 Linked List 介绍 链表是有序的列表 xff0c 但是它在内存中是存储如下 链表是以节点的方式来存储 是链式存储每个节点包含 data 域 xff0c next 域 xff1a 指向下一个节点 如图 xff1a 发现
  • prepareStatement的使用

    1 1prepareStatement解决sql注入的问题 span class token comment 演示sql注入的安全问题 span span class token keyword public span static voi
  • 动态sql

    1 什么是动态sql sql的内容是变化的 可以根据条件获取到不同的sql语句 主要是where部分发生变化 动态sql的实现 使用的是mybatis提供的标签 2 为什么使用动态sql 使用动态sql可以解决某些功能的使用 例如使用条件查