Hibernate查询之Criteria查询in中的长度大于1000解决方案


众所周知。hibernate的查询有好几种,Criteria正是其查询方式的一种,跟其他查询方式比较下具体优缺多有争议,不过这个不是今天要讨论的重点,我开发用的就是Criteria查询,先来说说我在使用中遇到的问题,在查询中对于in的使用我想都很普遍,比如:

Criteria createCriteria = this.getHibernateSession().createCriteria(

				VideoQualitBadGpsPoint.class);	 

createCriteria .add(Restrictions.in("id", list));

然而这样问题就来了,对于in中的集合会有一个长度限制,当集合长度大于1000的时候会报错,那么问题来了,在查询中in后的集合大于1000是很常见的,总不能一次查询要手动拆分成多个查询再拼接结果巴,当然这样是可以的,不过效率太低,于是研究了一个解决方案如下:

public List<VideoQualitBadGpsPoint> getVideoQualityBadGpsPointsByIds(
			List<VideoQualityBad> videoQualityBads) {
		List<VideoQualitBadGpsPoint> points = new ArrayList<>();
		if (null == videoQualityBads || 0 == videoQualityBads.size()) {
			return points;
		}
		ArrayList<Long> idList = new ArrayList<Long>();
		for (VideoQualityBad videoQualityBad : videoQualityBads) {
			idList.add(videoQualityBad.getId());
		}
		Criteria createCriteria = this.getHibernateSession().createCriteria(
				VideoQualitBadGpsPoint.class);
		Criteria criteria = createCriteria.createCriteria("videoQualityBad");
		if (idList.size() > 1000) {
			Disjunction dis = Restrictions.disjunction();
			List<List<Long>> segmentationList = segmentationList(idList, 999);
			for (List<Long> list : segmentationList) {
				dis.add(Restrictions.in("id", list));
			}
			criteria.add(dis);
		} else {
			criteria.add(Restrictions.in("id", idList));
		}

		createCriteria.add(Restrictions.eq("gpsPointType", 0));
		// latitude 16.585919~53.743108
		// longitude 73.386567~135.300369
		// 筛选经纬度
		// 筛选经纬度
		createCriteria.add(Restrictions.between("latitude",
				Float.valueOf("16.585919"), Float.valueOf("53.743108")));
		createCriteria.add(Restrictions.between("longitude",
				Float.valueOf("73.386567"), Float.valueOf("135.300369")));
		createCriteria.add(Restrictions.neOrIsNotNull("gpsPointTime", 0l));
		createCriteria.addOrder(Order.asc("gpsPointTime"));
		points = criteria.list();
		return points;
	}
/**
	 * 分割List
	 * 
	 * @param targe
	 * @param size
	 * @return
	 */
	public static List<List<Long>> segmentationList(List<Long> targe, int size) {
		List<List<Long>> listArr = new ArrayList<List<Long>>();
		// 获取被拆分的数组个数
		int arrSize = targe.size() % size == 0 ? targe.size() / size : targe
				.size() / size + 1;
		for (int i = 0; i < arrSize; i++) {
			List<Long> sub = new ArrayList<Long>();
			// 把指定索引数据放入到list中
			for (int j = i * size; j <= size * (i + 1) - 1; j++) {
				if (j <= targe.size() - 1) {
					sub.add(targe.get(j));
				}
			}
			listArr.add(sub);
		}
		return listArr;
	}
这里主要的就是 Disjunction的引入,可以拼接多个in,相当于SQL中的in()or in() or in().....

当然网上可能有更多更好的解决方案,这种只是我个人研究得出,仅供参考 


猜你喜欢

转载自blog.csdn.net/shenyanwei/article/details/75599850
今日推荐