前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[已解决]oracle使用in占位符超过1000报错 java.sql.SQLSyntaxErrorException:ORA-01795:列表中的最大表达式数为1000

[已解决]oracle使用in占位符超过1000报错 java.sql.SQLSyntaxErrorException:ORA-01795:列表中的最大表达式数为1000

作者头像
小小鱼儿小小林
发布2022-04-14 08:01:45
2.1K0
发布2022-04-14 08:01:45
举报
文章被收录于专栏:灵儿的笔记灵儿的笔记

目录

前言

异常情况下(不超过1000也是正常的)

支持超过1000情况

前言

当我们使用在mapper.xml文件中写sql时,in占位符过多,会导致报下面的异常:

org.springframework.jdbc.BadSqglGrammarException: ###Error querying database.Cause: java.sq.SQLSyntaxErrorException:ORA-01795:列表中的最大表达式数为1000

异常情况下(不超过1000也是正常的)

mapper.xml文件和Dao层、service层是下面这样的

代码语言:javascript
复制
<?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.xxx.xxx.zygxsq.aaaaaaDao">
    <select id="getXxxxxxInfo" resultType="com.xxx.xxx.zygxsq.model.Aaaaaaaa">
        SELECT
        aa,
        bb,
        cc
        FROM AaaaTable T
		<where>
			<if test="namesList != null and namesList.size() > 0 ">
				T.NAME in
				<foreach collection="namesList" item="name" separator="," open="(" close=")">
					#{name}
				</foreach>
			</if>
		</where>
    </select>


</mapper>

Dao层:

代码语言:javascript
复制
@Mapper
public interface aaaaaaDao {


    List<StudentDTO> getXxxxxxInfo(@Param(value = "nameList") List<String> nameList);

    
}

service层

代码语言:javascript
复制
@Slf4j
public class BbbbbbbServiceImpl implements BbbbbbbService {
    
    @Autowired
    AaaaaaDao aaaaaaDao;



	@Override
    private void getXxxxxxInfo() {
        
        List<StudentDTO> list = aaaaaaDao.getXxxxxxInfo(nameList);
            
        return null;
    }

    
}

上述mapper.xml就会出现,如果nameList的长度过大,大于1000的话,就会报上述异常 :Error querying database.Cause: java.sq.SQLSyntaxErrorException:ORA-01795:列表中的最大表达式数为1000,

那应该怎么改呢,可以将超过1000的变成or的形式

支持超过1000情况

正确的mapper.xml、Dao层、Service层如下

代码语言:javascript
复制
<?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.xxx.xxx.zygxsq.aaaaaaDao">
    <select id="getXxxxxxInfo" resultType="com.xxx.xxx.zygxsq.model.Aaaaaaaa">
        SELECT
        aa,
        bb,
        cc
        FROM AaaaTable T
        <where>
            <if test="namesList != null and namesList.size() > 0 ">
                AND
                <foreach collection="namesList" item="names" separator="or">
                    T.NAME in
                    <foreach collection="names" item="name" separator="," open="(" close=")">
                        #{name}
                    </foreach>
                </foreach>
            </if>
            <if test="sex!=null">
                AND sex= #{sex}
            </if>
        </where>
    </select>


</mapper>

Dao层

代码语言:javascript
复制
@Mapper
public interface aaaaaaDao {


    List<StudentDTO> getXxxxxxInfo(@Param(value = "nameList") List<List<String>> nameList);

    
}

service层

代码语言:javascript
复制
@Slf4j
public class BbbbbbbServiceImpl implements BbbbbbbService {
    
    @Autowired
    AaaaaaDao aaaaaaDao;



	@Override
    private void getXxxxxxInfo() {
        // 切割超过1000的变成多个list
        List<List<String>> sumArrayCodeList = CommonUtil.getSumArrayList(nameList);
        
        List<StudentDTO> list = aaaaaaDao.getXxxxxxInfo(sumArrayCodeList);
            
        return null;
    }

    
}

getSumArrayList 工具类方法,可以有多种实现方式

方式一

代码语言:javascript
复制
/**
     * oracle超过1000拆分list
     * @param list
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> getSumArrayList(List<T> list) {
        int maxSize = 1000;
        int one = 1;
        int zero = 0;
        List<List<T>> objectlist = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return objectlist;
        }
        int iSize = list.size() / maxSize;
        int iCount = list.size() % maxSize;
        for (int i = 0; i <= iSize; i++) {
            List<T> newObjList = new ArrayList<>();
            if (i == iSize) {
                for (int j = i * maxSize; j < i * maxSize + iCount; j++) {
                    newObjList.add(list.get(j));
                }
            } else {
                for (int j = i * maxSize; j < (i + one) * maxSize; j++) {
                    newObjList.add(list.get(j));
                }
            }
            if (newObjList.size() > zero) {
                objectlist.add(newObjList);
            }
        }
        return objectlist;
    }

方式二

代码语言:javascript
复制
/**
     * 列表分页
     * Oracla中In参数超过1000会抛出异常
     *
     * @param list 源列表
     * @param max  每页最多数据量
     * @return 分页列表
     */
    public static <T> List<List<T>> getSumArrayList(List<T> list, int max) {
        List<T> templist;

        List<List<T>> pageList = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            log.warn("参数列表为空!");
            return Collections.emptyList();
        }

        // 去重
        log.debug("去重前长度" + list.size());
        templist = list.stream().distinct().collect(Collectors.toList());
        log.debug("去重后长度" + list.size());

        // 总页数
        int pageTotalNum = (int) Math.ceil(templist.size() / (max * 1.0));

        for (int i = 0; i < pageTotalNum; i++) {
            pageList.add(templist.stream().skip(i * max).limit(max).collect(Collectors.toList()));
        }
        return pageList;
    }

方式三

代码语言:javascript
复制
 /**
     * 数据库in ()切割
     * @param data
     * @return
     */
    public static List<List<String>> getSumArrayList(List<String> data) {
        private static final Integer MAX_SEND = 999;
        int size = data.size();
        int limit = (size + MAX_SEND - 1) / MAX_SEND;
        return Stream
                .iterate(0, n -> n + 1).limit(limit).parallel()
                .map(a -> data.stream().skip(a * MAX_SEND).limit(MAX_SEND).parallel().collect(Collectors.toList()))
                .collect(Collectors.toList());
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 异常情况下(不超过1000也是正常的)
  • 支持超过1000情况
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档