结合 Mybatis,探讨 Oracle 中 in 与 not in 的陷阱

简介: 一、Oracle 中的 in 与 not in1. 正常情况下的使用查询语句使用 in 和 not in 的例子--表:T_USER,USER_ID 有 1,2,3,4,5,6--查询 userId 中包含1,2,3的数据--查询结果:1,2,3SELECT * FROM T_USER T WHERE T.

一、Oracle 中的 in 与 not in

1. 正常情况下的使用

查询语句使用 in 和 not in 的例子

--表:T_USER,USER_ID 有 1,2,3,4,5,6
--查询 userId 中包含1,2,3的数据
--查询结果:1,2,3
SELECT * FROM T_USER T WHERE T.USER_ID IN (1, 2, 3);

--查询 userId 中不包含1,2,3的数据
--查询结果:4,5,6
SELECT * FROM T_USER T WHERE T.USER_ID NOT IN (1, 2, 3);

2. 数据为空时的使用

数据为空时,是最容易产生理解错误和查询报错。

数据为“空”表现为,没有数据或者数据为 null 。如以下两种情景:

  • 数据为空,例如
SELECT * FROM T_USER T WHERE T.USER_ID IN ();

这时候查询语句会报错,“缺失表达式”。

  • 数据为 null,例如
SELECT * FROM T_USER T WHERE T.USER_ID IN (NULL);

这时候查询结果为空,即没有任何数据。

而此种情况下容易产生理解错误的是以下两个查询语句:

SELECT * FROM T_USER T WHERE T.USER_ID IN (NULL);

SELECT * FROM T_USER T WHERE T.USER_ID NOT IN (NULL);

很多人以为这两个查询语句的查询结果应该是相反的,即 IN (NULL) 查不出数据,而 NOT IN (NULL) 查出所有数据,或者反过来。

但实际的查询结果是,两个语句查询结果都为空,即都没有数据。

二、结合 Mybatis,探讨 Oracle 中 in 与 not in 的陷阱

1. 常用场景:

在 Mybatis 中使用 in 或者 not in 的方式如下:

<if test="null != list and list.size > 0 ">
    AND T.USER_ID IN
    <foreach collection="list" item="userID" open="(" separator="," close=")">
        #{userID}
    </foreach>
</if>

这种方式可以有效避免因为出现 IN ( ) 而导致的缺失表达式异常。

但是这个表达式所使用的场景是,有 userID 集合时,查询出集合中 userID 数据;没有 userID 集合时,查询出所有 userID 的数据。

2. 特殊场景:当没有 userID 集合时,不查任何数据

偶尔会出现这样的使用场景,当没有 userID 集合时,不查任何数据。

这时候就有人会把 if 条件去掉,即采用如下的查询方式

AND T.USER_ID IN
<foreach collection="list" item="userID" open="(" separator="," close=")">
    #{userID}
</foreach>

很容易理解为什么有人会这么写。list 有值时,in 就有数据,查询也就有数据;list 为空时,in 就没有数据,查询也就得不到数据。

理想很丰富,现实很骨感。

如果你这么写的时候,你们当list为空时,就会出现如下的查询语句

AND T.USER_ID IN

直接导致缺失表达式异常。

我的一个解决办法是,在 list 中增加一个数据库中没有的 userID,例如 userID = 0 的数据

那么当你需要的 list 为空时,list 中仍然保留有 0 这个值。于是,当你查询时会出现如下语句

AND T.USER_ID IN (0)
相关文章
|
Oracle Java 数据库连接
使用Mybatis generator自动生成代码,仅限Oracle数据库
使用Mybatis generator自动生成代码,仅限Oracle数据库
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
684 0
|
Oracle 关系型数据库 Java
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
216 9
|
Oracle Java 关系型数据库
SpringBoot整合Mybatis连接Oracle数据库
SpringBoot整合Mybatis连接Oracle数据库
SpringBoot整合Mybatis连接Oracle数据库
mybatis-plus使用oceanbase-oracle模式
mybatis-plus使用oceanbase-oracle模式
1051 2
|
Oracle 关系型数据库 Java
Mybatis JdbcType与Oracle、MySql数据类型对应列表
Mybatis JdbcType与Oracle、MySql数据类型对应列表
546 0
|
XML SQL Oracle
使用mybatis 连接Oracle 数据库 xml 文件中需要注意的问题
使用mybatis 连接Oracle 数据库 xml 文件中需要注意的问题
309 0
|
5月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
1017 1
Spring boot 使用mybatis generator 自动生成代码插件
|
8月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
700 0
|
10月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
461 2