mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-11-24 18:02:18 -05:00
Optimize InListUtil.java
This commit is contained in:
parent
3f45785865
commit
9c1efdc715
@ -1,86 +1,98 @@
|
|||||||
package com.moparisthebest.jdbc.util;
|
package com.moparisthebest.jdbc.util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class InListUtil {
|
public class InListUtil {
|
||||||
|
|
||||||
public static final int defaultMaxSize = Integer.parseInt(System.getProperty("QueryMapper.BindInList.defaultMaxSize", "999"));
|
public static final int defaultMaxSize = Integer.parseInt(System.getProperty("QueryMapper.BindInList.defaultMaxSize", "999"));
|
||||||
|
public static final String inEmpty = "(0=1)", notInEmpty = "(1=1)";
|
||||||
|
|
||||||
private static <T> List<List<T>> split(final List<T> list, final int maxLength) {
|
// fieldName + listPrefix + 3 parens + ((number expected which is less than maxSize * 2) - 1) assuming 20 items = 39 + 3 = 42
|
||||||
final int listSize = list.size();
|
public static final int defaultInListPreallocLength = Integer.parseInt(System.getProperty("QueryMapper.BindInList.defaultInListPreallocLength", "42"));
|
||||||
final List<List<T>> ret = new ArrayList<List<T>>();
|
|
||||||
if (listSize < maxLength)
|
|
||||||
ret.add(list);
|
|
||||||
else
|
|
||||||
for (int fromIndex = 0, toIndex = maxLength; fromIndex < listSize; fromIndex = toIndex, toIndex += maxLength)
|
|
||||||
ret.add(list.subList(fromIndex, toIndex > listSize ? listSize : toIndex));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> StringBuilder buildCommaSeparatedList(final Iterable<T> list, final StringBuilder sb) {
|
private static <T> String toNotInListNonEmpty(final String fieldName, final Iterator<T> items, final int maxSize, final String listPrefix, final String listCombine) {
|
||||||
boolean notFirst = false;
|
final StringBuilder sb = new StringBuilder(fieldName.length() + listPrefix.length() + defaultInListPreallocLength);
|
||||||
for (final T obj : list) {
|
sb.append('(');
|
||||||
if (notFirst) sb.append(',');
|
|
||||||
else notFirst = true;
|
|
||||||
sb.append('?');
|
|
||||||
}
|
|
||||||
return sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> StringBuilder buildInList(final Iterable<T> list, final StringBuilder sb, final String fieldName, final String listPrefix) {
|
|
||||||
return buildCommaSeparatedList(list, sb.append(fieldName).append(listPrefix)).append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> String toInList(final String fieldName, final Collection<T> items, final int maxSize, final String listPrefix, final String listCombine) {
|
|
||||||
final StringBuilder sb = new StringBuilder("(");
|
|
||||||
|
|
||||||
// do it quick if it will fit in one in-list
|
|
||||||
if (items.size() < maxSize) // 999 or less
|
|
||||||
return buildInList(items, sb, fieldName, listPrefix).append(")").toString();
|
|
||||||
|
|
||||||
// else we need to split lists
|
// else we need to split lists
|
||||||
boolean notFirst = false;
|
int count;
|
||||||
for (final List<T> item : split(items instanceof List ? (List<T>) items : new ArrayList<T>(items), maxSize)) {
|
while(true) {
|
||||||
if (notFirst) sb.append(listCombine);
|
|
||||||
else notFirst = true;
|
sb.append(fieldName).append(listPrefix);
|
||||||
buildInList(item, sb, fieldName, listPrefix);
|
count = 1;
|
||||||
|
while(true) {
|
||||||
|
items.next();
|
||||||
|
sb.append('?');
|
||||||
|
if (!items.hasNext() || ++count > maxSize)
|
||||||
|
break;
|
||||||
|
sb.append(',');
|
||||||
|
}
|
||||||
|
sb.append(')');
|
||||||
|
|
||||||
|
if(!items.hasNext())
|
||||||
|
break;
|
||||||
|
sb.append(listCombine);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.append(")").toString();
|
return sb.append(')').toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> String toInListNonEmpty(final String fieldName, final Collection<T> items, final int maxSize) {
|
private static <T> String toInListNonEmpty(final String fieldName, final Iterator<T> items, final int maxSize) {
|
||||||
return toInList(fieldName, items, maxSize, " IN (", " OR ");
|
return toNotInListNonEmpty(fieldName, items, maxSize, " IN (", " OR ");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> String toNotInListNonEmpty(final String fieldName, final Collection<T> items, final int maxSize) {
|
private static <T> String toNotInListNonEmpty(final String fieldName, final Iterator<T> items, final int maxSize) {
|
||||||
return toInList(fieldName, items, maxSize, " NOT IN (", " AND ");
|
return toNotInListNonEmpty(fieldName, items, maxSize, " NOT IN (", " AND ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String toInList(final String fieldName, final Collection<T> items, final int maxSize) {
|
public static <T> String toInList(final String fieldName, final Iterator<T> items, final int maxSize) {
|
||||||
return items == null || items.isEmpty() ? "(0=1)" : toInListNonEmpty(fieldName, items, maxSize);
|
return items == null || !items.hasNext() ? inEmpty : toInListNonEmpty(fieldName, items, maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String toNotInList(final String fieldName, final Collection<T> items, final int maxSize) {
|
public static <T> String toNotInList(final String fieldName, final Iterator<T> items, final int maxSize) {
|
||||||
return items == null || items.isEmpty() ? "(1=1)" : toNotInListNonEmpty(fieldName, items, maxSize);
|
return items == null || !items.hasNext() ? notInEmpty : toNotInListNonEmpty(fieldName, items, maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String toInList(final String fieldName, final Collection<T> items) {
|
public static <T> String toInList(final String fieldName, final Iterable<T> items, final int maxSize) {
|
||||||
|
final Iterator<T> itemIt;
|
||||||
|
return items == null || !(itemIt = items.iterator()).hasNext() ? inEmpty : toInListNonEmpty(fieldName, itemIt, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String toNotInList(final String fieldName, final Iterable<T> items, final int maxSize) {
|
||||||
|
final Iterator<T> itemIt;
|
||||||
|
return items == null || !(itemIt = items.iterator()).hasNext() ? notInEmpty : toNotInListNonEmpty(fieldName, itemIt, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String toInList(final String fieldName, final T[] items, final int maxSize) {
|
||||||
|
// is Arrays.asList(items).iterator() the best iterator for Array ? why aren't they Iterable again...
|
||||||
|
return items == null || items.length == 0 ? inEmpty : toInListNonEmpty(fieldName, Arrays.asList(items).iterator(), maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String toNotInList(final String fieldName, final T[] items, final int maxSize) {
|
||||||
|
return items == null || items.length == 0 ? notInEmpty : toNotInListNonEmpty(fieldName, Arrays.asList(items).iterator(), maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String toInList(final String fieldName, final Iterator<T> items) {
|
||||||
return toInList(fieldName, items, defaultMaxSize);
|
return toInList(fieldName, items, defaultMaxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String toNotInList(final String fieldName, final Collection<T> items) {
|
public static <T> String toNotInList(final String fieldName, final Iterator<T> items) {
|
||||||
|
return toNotInList(fieldName, items, defaultMaxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String toInList(final String fieldName, final Iterable<T> items) {
|
||||||
|
return toInList(fieldName, items, defaultMaxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> String toNotInList(final String fieldName, final Iterable<T> items) {
|
||||||
return toNotInList(fieldName, items, defaultMaxSize);
|
return toNotInList(fieldName, items, defaultMaxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String toInList(final String fieldName, final T[] items) {
|
public static <T> String toInList(final String fieldName, final T[] items) {
|
||||||
return toInList(fieldName, Arrays.asList(items), defaultMaxSize);
|
return toInList(fieldName, items, defaultMaxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String toNotInList(final String fieldName, final T[] items) {
|
public static <T> String toNotInList(final String fieldName, final T[] items) {
|
||||||
return toNotInList(fieldName, Arrays.asList(items), defaultMaxSize);
|
return toNotInList(fieldName, items, defaultMaxSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.moparisthebest.jdbc;
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
import com.moparisthebest.jdbc.util.InListUtil;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -27,8 +29,8 @@ public interface InList {
|
|||||||
public <T> InListObject notInList(final Connection conn, final String columnName, final Collection<T> values) throws SQLException;
|
public <T> InListObject notInList(final Connection conn, final String columnName, final Collection<T> values) throws SQLException;
|
||||||
|
|
||||||
class InListObject {
|
class InListObject {
|
||||||
static final InListObject inEmpty = new InListObject("(0=1)");
|
static final InListObject inEmpty = new InListObject(InListUtil.inEmpty);
|
||||||
static final InListObject notInEmpty = new InListObject("(1=1)");
|
static final InListObject notInEmpty = new InListObject(InListUtil.notInEmpty);
|
||||||
|
|
||||||
private final String sql;
|
private final String sql;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user