JavaEE简单示例——动态SQL的复杂查询操作<foreach>

news2024/10/5 15:26:44

简单介绍:

在我们之前学习MySQL的时候,我们曾经有一个操作叫做查询区间,比如我们使用in关键字查询id为3到6之间的值,或者查询id小于100的值,这时候如果将SQL语句一条一条的查询出来进行筛选效率就太慢了,所以我们要使用<foreach>语句用于数组和集合的循环遍历元素:

<foreach>的属性:

属性说明
item表示集合中每一个元素进行迭代时候的别名。该属性为必选属性
index在List是元素的序号,在Map中,index是元素的key。可选属性
open表示foreach语句代码开始的符号,一般和close=")"一起用
separator表示元素的分隔符,一般值为逗号,防止我们手动输入的时候出现错误
close表示foreach语句代码结束的符号,一般和opne="("一起用,常用在in关键字后面
collection

用于指定遍历参数的类型,注意,该属性必须指定,且不同情况下指定的值是不一样的:

1、当遍历一个数组的时候,值为array

2、当遍历一个List的时候,值为list

3、当遍历一个Map的时候,值为map

使用方法:

<select id="" resultType="" paramterType="">

        select * from student where id in

        <foreach item="" index="" collection="" open="(" separator="," close=")">

                #{id}

        </foreach>

</select>

代码实现:

因为<foreach>的遍历对象有三种,所以我们分三种情况进行代码演示:

1.当遍历的对象是数组的时候:

SQL映射文件:

<?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="Mappers.dynamicSql">
<!--    使用<foreach>遍历数组-->
    <select id="selectByArray" resultType="student" parameterType="java.util.Arrays">
        select * from student where id in
        <foreach collection="array" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
</mapper>

接口文件:

package Mappers;

import com.mybatis.POJO.student;

import java.util.Arrays;
import java.util.List;

public interface dynamicSql {
    List<student> selectByArray(Integer[] ints);
}

测试类:

package Mappers;

import com.mybatis.POJO.Tools.createSqlSession;
import com.mybatis.POJO.student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class dynamicSqlTest {
    @Test
//    使用<foreach>标签循环查询区间
    public void selectByArray(){
        SqlSession sqlSession = new createSqlSession().create();
        dynamicSql dynamicSql = new createSqlSession().createdynamicSql();
//        首先查询id的值为3和4的数据信息
        Integer[] ints = {3,4};
        for (student student : dynamicSql.selectByArray(ints)) {
            System.out.println(student.toString());
        }

    }
}

运行结果:

当我们传入数组的时候,因为数组中的数字是3和4,使用in关键字,也就是查询出id的值为3和4的两条数据:

查询结果正确。

2.当遍历的对象是List的时候:

这个可以在之前的案例的基础上进行修改,需要将SQL映射文件中的parameterType的值修改成List集合的全限定类名,以及将接口中的形参的类型修改成List集合,最后传递一个List集合的参数即可:

SQL映射文件:

<?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="Mappers.dynamicSql">
<!--    使用<foreach>遍历List集合-->
    <select id="selectByList" parameterType="java.util.List" resultType="student">
        select * from student where id in
        <foreach collection="list" close=")" separator="," open="(" item="id" index="index">
            #{id}
        </foreach>
    </select>
</mapper>

测试类:

package Mappers;

import com.mybatis.POJO.Tools.createSqlSession;
import com.mybatis.POJO.student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class dynamicSqlTest {
//    使用<foreach>标签循环查询List
    @Test
    public void selectByList(){
        SqlSession sqlSession = new createSqlSession().create();
        dynamicSql dynamicSql = new createSqlSession().createdynamicSql();
        List<Integer> li = new ArrayList<>();
        li.add(1);
        li.add(2);
        for (student student : dynamicSql.selectByList(li)) {
            System.out.println(student.toString());
        }

    }
}

接口类:

package Mappers;

import com.mybatis.POJO.student;

import java.util.Arrays;
import java.util.List;

public interface dynamicSql {
    List<student> selectByList(List<Integer> list);
}

运行结果: 

我们在list集合中添加了两个数,那么查询结果应该就是id的值等于3和4的两条信息:

查询结果正确。

1.当遍历的对象是Map的时候:

SQL映射文件:

<?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="Mappers.dynamicSql">
<!--    使用<foreach>遍历Map集合-->
    <select id="selectByMap" resultType="student" parameterType="java.util.HashMap">
        select * from student where name like concat('%',#{name},'%') and id in
        <foreach collection="id" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
</mapper>

接口类:

package Mappers;

import com.mybatis.POJO.student;
import org.apache.ibatis.annotations.Mapper;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public interface dynamicSql {
    List<student> selectByMap(HashMap<String,Object> mapper);
}

实现类:

package Mappers;

import com.mybatis.POJO.Tools.createSqlSession;
import com.mybatis.POJO.student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class dynamicSqlTest {
//    使用<foreach>标签循环查询Map
    @Test
    public void selectByMap(){
        SqlSession sqlSession = new createSqlSession().create();
        dynamicSql dynamicSql = new createSqlSession().createdynamicSql();
        List<Integer> li = new ArrayList<>();
        li.add(1);
        li.add(2);
        HashMap<String,Object> mis = new HashMap<>();
        mis.put("id",li);
        mis.put("name","张三");
        for (student student : dynamicSql.selectByMap(mis)) {
            System.out.println(student);
        }

    }
}

运行结果:

使用Map进行查询的主要作用是传入多个参数,进行多个参数的查询,Map中的每一个元素都表示一个参数,并且其中一个是一个范围参数,比如上图中的键为id的属性,她的值就是一个List集合,并且这个值可以是任何的范围,我们使用Map集合的时候,遍历的是它多个元素中值是一个范围的元素,也就是上图中的键为id的值:

 值得注意的是,在之前我们在遍历的时候,<foreach>的collection属性的值都是list或者是arrays,但是在使用map的时候,需要将这个值改成map中需要被遍历的属性的键,从而找到需要被遍历的值 :

根据上图中的SQL语句和参数,应该是查询出id在1和2中的name为张三的值,查询结果确实如下所示,完整的SQL语句如下:

select * from student where name like '张三' and id in (1,2)

其中的'张三'属性和in关键字后面的(1,2)就是来自于Map集合中的元素 

注意点:

注意我们在编写SQL映射文件的时候,需要将parameterType的值修改为遍历对象的类型,并且一定是要类型的全路径名,比如java.util.Arrays用来遍历数组,并且如果使用的是接口化开发,注意方法的形参的类型要和自己传入的参数类型一致,或者形参的位置直接使用Object。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【05-JVM面试专题-运行时数据区的结构都有哪些?哪些是共享的呢?哪些是非共享的呢?详细的介绍一下运行时数据区结构各部分的作用?】

运行时数据区的结构都有哪些&#xff1f;哪些是共享的呢&#xff1f;哪些是非共享的呢&#xff1f;详细的介绍一下运行时数据区结构各部分的作用&#xff1f; 运行时数据区的结构都有哪些&#xff1f;哪些是共享的呢&#xff1f;哪些是非共享的呢&#xff1f;详细的介绍一下运行…

带您了解TiDB MySQL数据库中关于日期、时间的坑

带您了解TiDB & MySQL数据库中关于日期、时间的坑时间的基础知识什么是时间计算时间的几种方法世界时&#xff08;UT&#xff09;协调世界时&#xff08;UTC&#xff09;国际原子时&#xff08;TAI&#xff09;时区的概念中国所在的时区操作系统的时区datetimedatectl数据库…

Spring代理模式——静态代理和动态代理

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

python打包exe实用工具auto-py-to-exe的操作方法

auto-py-to-exe操作方法auto-py-to-exe 是一个用于打包 python 程序的程序。本文就是主要介绍如何使用 auto-py-to-exe 完成 python 程序打包。本文主要分为两节&#xff0c;第一节主要对 auto-py-to-exe 做一些介绍&#xff0c;第二节则是演示 auto-py-to-exe 的打包过程。一、…

pygraphviz安装教程

0x01. 背景 最近在做casual inference&#xff0c;做实验时候想因果图可视化&#xff0c;遂需要安装pygraphviz&#xff0c;整了一下午&#xff0c;终于捣鼓好了&#xff0c;真头大。 环境&#xff1a; win10操作系统python3.9环境 0x02. 安装Graphviz 传送门&#xff1a;…

linux:本地套接字通信客户和服务器代码

客户端代码 #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <arpa/inet.h> #include <sys/un.h> int main(int argc, const cha…

中间件安全—Tomcat常见漏洞

中间件安全—Tomcat常见漏洞1.Tomcat常见漏洞1.1.前言1.2.文件上传 (CVE-2017-12615)1.2.1.漏洞原理1.2.2.影响版本1.2.3.漏洞复现1.2.3.1.测试是否允许PUT1.2.3.2.验证漏洞是否存在1.2.3.3.访问test.jsp1.2.3.4.上传执行命令脚本1.2.3.5.执行命令1.3.文件包含漏洞&#xff08;…

【第一章 - 绪论】- 数据结构(近八千字详解)

目录 一、 数据结构的研究内容 二、基本概念和术语 2.1 - 数据、数据元素、数据项和数据对象 2.2 - 数据结构 2.2.1 - 逻辑结构 2.2.2 - 存储结构 2.3 - 数据类型和抽象数据类型 三、抽象数据类型的表现与实现 四、算法和算法分析 4.1 - 算法的定义及特性 4.2 - 评价…

手把手教大家在 gRPC 中使用 JWT 完成身份校验

文章目录1. JWT 介绍1.1 无状态登录1.1.1 什么是有状态1.1.2 什么是无状态1.2 如何实现无状态1.3 JWT1.3.1 简介1.3.2 JWT数据格式1.3.3 JWT 交互流程1.3.4 JWT 存在的问题2. 实践2.1 项目创建2.2 grpc_api2.3 grpc_server2.4 grpc_client3. 小结上篇文章松哥和小伙伴们聊了在 …

Docker 如何配置镜像加速

Docker 镜像加速 国内从 DockerHub 拉取镜像有时会遇到困难&#xff0c;此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务&#xff0c;例如&#xff1a; 科大镜像&#xff1a;https://docker.mirrors.ustc.edu.cn/网易&#xff1a;https://hub-…

生态流量数据采集传输协议定制开发(嵌入式水资源SZY206协议以及VC++ POST数据发送)

水电站生态流量在线监测&#xff0c;流量数据采集传输,水资源遥测终端机程序。 背景&#xff1a;现场使用SCJ-LL01多普勒超声波流量计采集生态下泄流量&#xff0c;使用太阳能供电系统&#xff0c;使用SCJ-RTU01遥测终端机进行数据采集&#xff0c;设备采用4G通讯&#xff0c;…

基于MATLAB开发AUTOSAR软件应用层模块-part23.SR interface通信介绍(接收的数据错误时应该如何处理)

在软件SWC之间的AUTOSAR SR通信中,当COM报告接收SWC的数据接收错误时,运行时环境(RTE)触发DataReceiveErrorEvent。该事件可以指示发送方SWC未能在AliveTimeout限制内回复,或者发送方SWC发送了无效数据。 接下来我们就讲解下怎么实现无效数据的接收和判断 还是三步走,建模…

Ubuntu 上 Let‘s Encrypt 生成泛域名证书

安装生成工具certbot&#xff1a; apt install certbot 查看安装在哪&#xff1a; which certbot 使用certbot&#xff08;位置在 /usr/bin/certbot&#xff09;生成证书&#xff1a; /usr/bin/certbot certonly -d *.xxx.com --manual --preferred-challenges dns --ser…

一种全新的图像滤波理论的实验(二)

一、前言 2021年12月31日&#xff0c;我发布了基于加权概率模型的图像滤波算法的第一个实验&#xff0c;当时有两个关键问题没有解决&#xff1a; 1、出现了大面积的黑色区域&#xff0c;最近考虑把这个算法实际应用在图像和视频的压缩领域&#xff0c;于是通过对程序的分析&a…

【论文简述】GMFlow: Learning Optical Flow via Global Matching(CVPR 2022)

一、论文简述 1. 第一作者&#xff1a;Haofei Xu 2. 发表年份&#xff1a;2022 3. 发表期刊&#xff1a;CVPR oral 4. 关键词&#xff1a;光流、代价体、Transformers、全局匹配、注意力机制 5. 探索动机&#xff1a;过去几年中具有代表性的光流学习框架的核心估计方式没有…

Java文件IO及其案例分析

目录 1. 文件概述 1.1 狭义和广义上的文件 1.2 文件的路径 1.3 文件的类型 2. 针对文件系统的操作 3. 针对文件内容的操作&#xff08;文件的读和写&#xff09; 3.1 IO流对象 3.2 文件的读操作&#xff08;字节流&#xff09; 3.3 文件的写操作&#xff08;字节流&#…

内存取证常见例题思路方法-volatility (没有最全 只有更全)

目录 1.从内存文件中获取到用户hacker 的密码并且破解密码&#xff0c;将破解后的密码作为 Flag值提交; 2.获取当前系统的主机名&#xff0c;将主机名作为Flag值提交; 3.获取当前系统浏览器搜索过的关键词&#xff0c;作为Flag提交; 4.获取当前内存文件的 ip地址 5.当前系…

pycharm和navigator打开时出现报错,无法正常打开

1、navigator打开时出现提示&#xff1a; 原因是&#xff1a;python.exe有多个任务在占用。 解决办法&#xff1a; &#xff08;1&#xff09;打开cmd &#xff08;2&#xff09;输入&#xff1a;tasklist | findstr “pythonw” &#xff08;3&#xff09;有几个线程就kill几个…

qt qchart学习

Qt Charts主要由QChartView、QChart、QLegend图例、坐标轴(由QAbstractAxis子类实现)、**数据源(由QAbstractSeries子类实现)**等组成使用QChart的前期准备1. Qt5.9及以上版本&#xff1b;2. .pro文件中添加QT charts3. 在使用QChart的各个控件之前&#xff0c;引用头文件并必…

【前缀和】和为k的子数组 路径总和 III

文章目录和为k的子数组路径总和 III和为k的子数组 动态规划算法&#xff08;超时&#xff09; class Solution { public:int subarraySum(vector<int>& nums, int k) {int n nums.size();vector<vector<int>> dp(n, vector<int>(n, 0));int ans …