+ // Returns the number of rows inserted
+ public int insert(Connection con, Table table, Object[][] values) throws SQLException
+ {
+ int count = 0;
+ int pendingValues = 0;
+
+ assert( isValidInsert(table, values));
+
+ String sql = insertSql(table);
+
+ try (PreparedStatement ps = con.prepareStatement(sql))
+ {
+ for (int row = 0; row < values.length; ++row) {
+ Object[] data = values[row];
+
+ assert(null != data);
+ assert(data.length == table.getNumColumns());
+
+ for (int idx = 0; idx < data.length; ++idx) {
+ Object obj = data[idx];
+ Column column = table.getColumn(idx);
+ column.setObject(ps, idx + 1, obj);
+ pendingValues++;
+ }
+ ps.addBatch();
+
+ int rowsFlushed = checkFlushBatch(ps, pendingValues, false);
+ if (rowsFlushed > 0) {
+ count += rowsFlushed;
+ pendingValues = 0;
+ }
+ }
+
+ count += checkFlushBatch(ps, pendingValues, true);
+ }
+
+ return count;
+ }
+
+ int checkFlushBatch(PreparedStatement ps, int pendingValues, boolean forceFlush) throws SQLException
+ {
+ int count = 0;
+
+ if (forceFlush || (pendingValues >= PENDING_LIMIT))
+ {
+ int[] updateCounts = ps.executeBatch();
+ for (int i = 0; i < updateCounts.length; ++i) {
+ if (updateCounts[i] > 0) {
+ count += updateCounts[i];
+ }
+ }
+ }
+
+ return count;
+ }
+
+ String insertSql(Table table) {
+ StringBuilder sb = new StringBuilder("INSERT INTO ");
+ sb.append(table.getName())
+ .append(" VALUES (");
+
+ for (int i = 0; i < table.getNumColumns(); ++i) {
+ if (i > 0) {
+ sb.append(",");
+ }
+ sb.append("?");
+ }
+ sb.append(")");
+
+ return sb.toString();
+ }
+
+ protected String selectSql(Column[] columns, Table[] tables, Condition[] conditions, Sort[] sorts, int limit)