解决Oracle使用IN不能超过1000问题

报错

 ORA-01795: 列表中的最大表达式数为 1000

解决方案

Example.Criteria 中使用in

Example example = new Example(Entry.class);
example.and(DatabaseUtil.sqlSpecialForIn(example, property, values));
List<Entry> result = entryMapper.selectByExample(example);

DatabaseUtil.java

import com.google.common.collect.Lists;
import org.apache.commons.collections4.IterableUtils;
import org.mybatis.spring.SqlSessionTemplate;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * 数据库工具类
 */
public class DatabaseUtil {

    /**
     * 获取数据库使用类型
     * @return
     */
    public static String getDatabaseId() {
        SqlSessionTemplate sqlSessionTemplate = SpringContextUtil.getBean("sqlSessionTemplate");
        return sqlSessionTemplate.getConfiguration().getDatabaseId();
    }

    /**
     * sql中对应In特殊处理:oracle中如果in超过1000则报ORA-01795: 列表中的最大表达式数为 1000错误,mysql则不会
     * @param example
     * @param property 表属性
     * @param values in里的数据
     * @return
     */
    public static Example.Criteria sqlSpecialForIn(Example example, String property, Iterable values) {
        String databaseId = DatabaseUtil.getDatabaseId();
        Example.Criteria criteria = example.createCriteria();
        if("oracle".equals(databaseId)){
            if(values != null){
                List myList = IterableUtils.toList(values);
                List<List<String>> rsList = Lists.partition(myList, 950);
                rsList.forEach(l ->  criteria.orIn(property, l));
            }
        }else{
            criteria.andIn(property, values);
        }
        return criteria;
    }
}

foreach 中使用in

<if test="items != null and items .size > 0">
	AND (
       <foreach collection="items" item="item" index="index" open="id IN (" close=")" separator=",">
           <if test="((index+1) % 950) == 0"> NULL ) OR id IN (</if>#{item}
       </foreach>
       )
</if>

你可能感兴趣的:(Mybatis)