SQLバインド変数の上限

Oracle は、SQLバインド変数の上限を超えると、
 ORA-01745: ホスト/バインド変数名が無効です。
が発生する
Oracle のバインド変数の上限は、32768

PostgreSQL は、32767

MySQL はクエリの上限サイズで制限を見た方が良いみたい

show variables like 'max_allowed_packet'

mybatis で、バルクインサートをする場合に、もしもこの上限を超えるのであれば、
分割して実行するしかない。
そんな時、List要素を任意の数で分割したリストで処理したい。
以下のようなメソッドが汎用的であろう。

public static <T> List<List<T>> chunklist(List<T> list, int size) {
    return IntStream.range(0, (int)Math.ceil((double)list.size() / (double)size))
        .boxed()
        .map(i -> list.stream().skip((long)i * size).limit(size).collect(Collectors.toList()))
        .collect(Collectors.toList());
}

1回のSQLのバインド数×リストサイズ > 上限値の場合、
バルクインサートにおける利用では、
 CEIL( 1回のSQLのバインド数×リストサイズ / 上限値 )
の数を size に指定すれば良い。

もちろん。バルクインサートでない1回のSQLが、
バインド変数の数 > 上限値 だったらどうしようもない。

Java9 以降なら、

public static <T> List<List<T>> chunklist(List<T> list, int size) {
    return Stream.iterate(0, n -> n + size)
        .limit((list.size() + size - 1) / size)
        .map(n -> list.subList(n, Math.min(n + size, list.size())))
        .collect(Collectors.toList());
}

メソッドにしないまでも、、
Throwable Consumer<T> を使って、以下でも良い。

int size = 1200;
IntStream.range(0, (int)Math.ceil((double)list.size() / (double)size))
.boxed()
.map(i -> list.stream().skip((long)i * size)
.limit(size)
.collect(Collectors.toList()))
.forEach(ThrowableConsumer.of(e->{
    // TODO sqlSesssion.insert(sqlid, e);
}));

Java9 以降~

int size = 1200;
Stream.iterate(0, n->n + size)
.limit((list.size() + size - 1) / size)
.map(n -> list.subList(n, Math.min(n + size, list.size())))
.forEach(ThrowableConsumer.of(e->{
    // TODO sqlSesssion.insert(sqlid, e);
}));