public BatchInsertGenKeysOp(String sql, F<A, TryEffect1<PreparedStatement, SQLException>> binder, Iterable<A> as, Try1<ResultSet, B, SQLException> getKey, CanBuildFrom<B, C1, C2> cbf) { this.sql = sql; this.binder = batchBinder(binder, as); this.getKey = getKey; this.cbf = cbf; this.as = as; }
public BatchDeleteOptimized(String tableName, List<String> whereColumns, Iterable<A> xs, Try3<Integer, PreparedStatement, A, Integer, SQLException> binder, int batchSize) { int whereColumnsLength = whereColumns.size(); op = DbOps.toChunks(xs, ys -> { String colsSegment = "(" + StringUtil.join(whereColumns, ", ") + ")"; String sql = MessageFormat.format(SQL_TEMPLATE, tableName, colsSegment, SqlStringUtils.placeholderRows(Collections.size(xs), whereColumnsLength)); TryEffect1<PreparedStatement, SQLException> populatedBinder = iterableBinder(binder, xs); return new DB<Integer>() { @Override public Integer run(Connection c) throws SQLException { try (PreparedStatement ps = c.prepareStatement(sql)) { populatedBinder.f(ps); return ps.executeUpdate(); } } }; }, batchSize); }
/** * A binder that takes a binder and an iterable, applies the binder to each element of the iterable and adds it as a batch, * executes the batch, and returns the total update count. Used in BatchInsertGenKeysOp and BatchUpdateOp * @param binder the binder for a single element in the iterable * @param as the iterable * @param <A> the type of elements in the iterable * @return the total update count, as an Option. The option will be none() iff any of the elements in the update count * is equal to Statement.SUCCESS_NO_INFO */ public static <A> Try1<PreparedStatement, Option<Integer>, SQLException> batchBinder( F<A, TryEffect1<PreparedStatement, SQLException>> binder, Iterable<A> as) { return ps -> { for (A a : as) { binder.f(a).f(ps); ps.addBatch(); } return sumBatchResult(ps.executeBatch()); }; }
public static DB<List<Employee>> selectByIds(Iterable<Integer> ids) { return new SelectOp.List<>( format("SELECT ID, NAME, DEPARTMENT_ID FROM EMPLOYEES WHERE ID IN ({0}) ORDER BY ID", SqlStringUtils.placeholders(size(ids)) ), iterableBinder((idx, ps, id) -> { ps.setInt(idx++, id); return idx; }, ids), rs -> new Employee(rs.getInt(1), rs.getString(2), rs.getInt(3)) ); }
@Test public void iterableBinder() { List<P2<String, String>> data = arrayList(p("x1", "y1"), p("x2", "y2"), p("x3", "y3")); String sql = format( "INSERT INTO MySqlTest_FOO(X,Y) VALUES ({0})", SqlStringUtils.placeholderRows(data.length(), 2) ); UpdateOp insert = new UpdateOp( sql, Binders.iterableBinder((pos, ps, x) -> { int currentPosition = pos; ps.setString(currentPosition++, x._1()); ps.setString(currentPosition++, x._2()); return currentPosition; }, data) ); int updateCount = DB.transact(insert); assertThat(updateCount, is(3)); List<P2<String, String>> readData = DB.submit(new SelectOp.FjList<>("SELECT X,Y FROM MySqlTest_FOO", NO_BINDER, rs -> p(rs.getString(1), rs.getString(2)))); assertThat(readData, is(data)); }
public BatchUpdateOp(String sql, F<A, TryEffect1<PreparedStatement, SQLException>> binder, Iterable<A> as) { this.binder = batchBinder(binder, as); this.as = as; this.sql = sql; }