15
15
*/
16
16
package org .springframework .data .jdbc .core .convert ;
17
17
18
+ import java .sql .PreparedStatement ;
19
+ import java .sql .ResultSet ;
20
+ import java .sql .SQLException ;
21
+ import java .util .ArrayList ;
22
+ import java .util .List ;
23
+ import java .util .Map ;
24
+
18
25
import org .springframework .jdbc .core .BatchPreparedStatementSetter ;
19
26
import org .springframework .jdbc .core .ColumnMapRowMapper ;
20
27
import org .springframework .jdbc .core .JdbcOperations ;
31
38
import org .springframework .lang .Nullable ;
32
39
import org .springframework .util .Assert ;
33
40
34
- import java .sql .PreparedStatement ;
35
- import java .sql .ResultSet ;
36
- import java .sql .SQLException ;
37
- import java .util .ArrayList ;
38
- import java .util .List ;
39
- import java .util .Map ;
40
-
41
41
/**
42
- * Counterpart to {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations} containing
43
- * methods for performing batch updates with generated keys.
42
+ * Counterpart to {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations} containing methods for
43
+ * performing batch updates with generated keys.
44
44
*
45
45
* @author Chirag Tailor
46
46
* @since 2.4
47
47
*/
48
48
public class BatchJdbcOperations {
49
+
49
50
private final JdbcOperations jdbcOperations ;
50
51
51
52
public BatchJdbcOperations (JdbcOperations jdbcOperations ) {
52
53
this .jdbcOperations = jdbcOperations ;
53
54
}
54
55
55
56
/**
56
- * Execute a batch using the supplied SQL statement with the batch of supplied arguments,
57
- * returning generated keys.
57
+ * Execute a batch using the supplied SQL statement with the batch of supplied arguments, returning generated keys.
58
+ *
58
59
* @param sql the SQL statement to execute
59
- * @param batchArgs the array of {@link SqlParameterSource} containing the batch of
60
- * arguments for the query
60
+ * @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query
61
61
* @param generatedKeyHolder a {@link KeyHolder} that will hold the generated keys
62
- * @return an array containing the numbers of rows affected by each update in the batch
63
- * (may also contain special JDBC-defined negative values for affected rows such as
64
- * {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
62
+ * @return an array containing the numbers of rows affected by each update in the batch (may also contain special
63
+ * JDBC-defined negative values for affected rows such as
64
+ * {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
65
65
* @throws org.springframework.dao.DataAccessException if there is any problem issuing the update
66
66
* @see org.springframework.jdbc.support.GeneratedKeyHolder
67
67
* @since 2.4
@@ -71,16 +71,15 @@ int[] batchUpdate(String sql, SqlParameterSource[] batchArgs, KeyHolder generate
71
71
}
72
72
73
73
/**
74
- * Execute a batch using the supplied SQL statement with the batch of supplied arguments,
75
- * returning generated keys.
74
+ * Execute a batch using the supplied SQL statement with the batch of supplied arguments, returning generated keys.
75
+ *
76
76
* @param sql the SQL statement to execute
77
- * @param batchArgs the array of {@link SqlParameterSource} containing the batch of
78
- * arguments for the query
77
+ * @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query
79
78
* @param generatedKeyHolder a {@link KeyHolder} that will hold the generated keys
80
79
* @param keyColumnNames names of the columns that will have keys generated for them
81
- * @return an array containing the numbers of rows affected by each update in the batch
82
- * (may also contain special JDBC-defined negative values for affected rows such as
83
- * {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
80
+ * @return an array containing the numbers of rows affected by each update in the batch (may also contain special
81
+ * JDBC-defined negative values for affected rows such as
82
+ * {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
84
83
* @throws org.springframework.dao.DataAccessException if there is any problem issuing the update
85
84
* @see org.springframework.jdbc.support.GeneratedKeyHolder
86
85
* @since 2.4
@@ -91,7 +90,7 @@ int[] batchUpdate(String sql, SqlParameterSource[] batchArgs, KeyHolder generate
91
90
if (batchArgs .length == 0 ) {
92
91
return new int [0 ];
93
92
}
94
-
93
+
95
94
ParsedSql parsedSql = NamedParameterUtils .parseSqlStatement (sql );
96
95
SqlParameterSource paramSource = batchArgs [0 ];
97
96
String sqlToUse = NamedParameterUtils .substituteNamedParameters (parsedSql , paramSource );
@@ -105,6 +104,7 @@ int[] batchUpdate(String sql, SqlParameterSource[] batchArgs, KeyHolder generate
105
104
Object [] params = NamedParameterUtils .buildValueArray (parsedSql , paramSource , null );
106
105
PreparedStatementCreator psc = pscf .newPreparedStatementCreator (params );
107
106
BatchPreparedStatementSetter bpss = new BatchPreparedStatementSetter () {
107
+
108
108
@ Override
109
109
public void setValues (PreparedStatement ps , int i ) throws SQLException {
110
110
Object [] values = NamedParameterUtils .buildValueArray (parsedSql , batchArgs [i ], null );
@@ -117,19 +117,24 @@ public int getBatchSize() {
117
117
}
118
118
};
119
119
PreparedStatementCallback <int []> preparedStatementCallback = ps -> {
120
+
120
121
int batchSize = bpss .getBatchSize ();
121
122
generatedKeyHolder .getKeyList ().clear ();
122
123
if (JdbcUtils .supportsBatchUpdates (ps .getConnection ())) {
124
+
123
125
for (int i = 0 ; i < batchSize ; i ++) {
126
+
124
127
bpss .setValues (ps , i );
125
128
ps .addBatch ();
126
129
}
127
130
int [] results = ps .executeBatch ();
128
131
storeGeneratedKeys (generatedKeyHolder , ps , batchSize );
129
132
return results ;
130
133
} else {
134
+
131
135
List <Integer > rowsAffected = new ArrayList <>();
132
136
for (int i = 0 ; i < batchSize ; i ++) {
137
+
133
138
bpss .setValues (ps , i );
134
139
rowsAffected .add (ps .executeUpdate ());
135
140
storeGeneratedKeys (generatedKeyHolder , ps , 1 );
@@ -146,18 +151,20 @@ public int getBatchSize() {
146
151
return result ;
147
152
}
148
153
149
- private void storeGeneratedKeys (KeyHolder generatedKeyHolder , PreparedStatement ps , int rowsExpected ) throws SQLException {
154
+ private void storeGeneratedKeys (KeyHolder generatedKeyHolder , PreparedStatement ps , int rowsExpected )
155
+ throws SQLException {
150
156
151
157
List <Map <String , Object >> generatedKeys = generatedKeyHolder .getKeyList ();
152
158
ResultSet keys = ps .getGeneratedKeys ();
153
159
if (keys != null ) {
160
+
154
161
try {
155
- RowMapperResultSetExtractor <Map <String , Object >> rse =
156
- new RowMapperResultSetExtractor <>(new ColumnMapRowMapper (), rowsExpected );
157
- //noinspection ConstantConditions
162
+
163
+ RowMapperResultSetExtractor <Map <String , Object >> rse = new RowMapperResultSetExtractor <>(
164
+ new ColumnMapRowMapper (), rowsExpected );
165
+ // noinspection ConstantConditions
158
166
generatedKeys .addAll (rse .extractData (keys ));
159
- }
160
- finally {
167
+ } finally {
161
168
JdbcUtils .closeResultSet (keys );
162
169
}
163
170
}
0 commit comments