18
18
import java .sql .PreparedStatement ;
19
19
import java .sql .ResultSet ;
20
20
import java .sql .SQLException ;
21
+ import java .util .ArrayList ;
21
22
import java .util .List ;
22
23
import java .util .Map ;
23
24
@@ -29,89 +30,71 @@ public BatchJdbcOperations(JdbcOperations jdbcOperations) {
29
30
}
30
31
31
32
@ Nullable
32
- int [] batchUpdate (String insertSql , SqlParameterSource [] sqlParameterSources ,
33
- KeyHolder generatedKeyHolder ) {
34
- // TODO: This is largely duplicated from spring-jdbc and should be replaced with a call into
35
- // NamedParameterJdbcTemplate#batchUpdate once a method taking KeyHolder is added there.
36
- ParsedSql parsedSql = NamedParameterUtils .parseSqlStatement (insertSql );
37
- SqlParameterSource paramSource = sqlParameterSources [0 ];
33
+ int [] batchUpdate (String sql , SqlParameterSource [] batchArgs , KeyHolder generatedKeyHolder ) {
34
+ return batchUpdate (sql , batchArgs , generatedKeyHolder , null );
35
+ }
36
+
37
+ @ Nullable
38
+ public int [] batchUpdate (String sql , SqlParameterSource [] batchArgs , KeyHolder generatedKeyHolder ,
39
+ String [] keyColumnNames ) {
40
+ if (batchArgs .length == 0 ) {
41
+ return new int [0 ];
42
+ }
43
+
44
+ ParsedSql parsedSql = NamedParameterUtils .parseSqlStatement (sql );
45
+ SqlParameterSource paramSource = batchArgs [0 ];
38
46
String sqlToUse = NamedParameterUtils .substituteNamedParameters (parsedSql , paramSource );
39
47
List <SqlParameter > declaredParameters = NamedParameterUtils .buildSqlParameterList (parsedSql , paramSource );
40
48
PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory (sqlToUse , declaredParameters );
41
- pscf .setReturnGeneratedKeys (true );
49
+ if (keyColumnNames != null ) {
50
+ pscf .setGeneratedKeysColumnNames (keyColumnNames );
51
+ } else {
52
+ pscf .setReturnGeneratedKeys (true );
53
+ }
42
54
Object [] params = NamedParameterUtils .buildValueArray (parsedSql , paramSource , null );
43
55
PreparedStatementCreator psc = pscf .newPreparedStatementCreator (params );
44
56
BatchPreparedStatementSetter bpss = new BatchPreparedStatementSetter () {
45
57
@ Override
46
58
public void setValues (PreparedStatement ps , int i ) throws SQLException {
47
- Object [] values = NamedParameterUtils .buildValueArray (parsedSql , sqlParameterSources [i ], null );
59
+ Object [] values = NamedParameterUtils .buildValueArray (parsedSql , batchArgs [i ], null );
48
60
pscf .newPreparedStatementSetter (values ).setValues (ps );
49
61
}
50
62
51
63
@ Override
52
64
public int getBatchSize () {
53
- return sqlParameterSources .length ;
65
+ return batchArgs .length ;
54
66
}
55
67
};
56
68
PreparedStatementCallback <int []> preparedStatementCallback = ps -> {
57
69
int batchSize = bpss .getBatchSize ();
58
- for (int i = 0 ; i < batchSize ; i ++) {
59
- bpss .setValues (ps , i );
60
- ps .addBatch ();
61
- }
62
- int [] results = ps .executeBatch ();
63
- List <Map <String , Object >> generatedKeys = ((KeyHolder ) generatedKeyHolder ).getKeyList ();
64
- generatedKeys .clear ();
65
- ResultSet keys = ps .getGeneratedKeys ();
66
- if (keys != null ) {
67
- try {
68
- RowMapperResultSetExtractor <Map <String , Object >> rse =
69
- new RowMapperResultSetExtractor <>(new ColumnMapRowMapper (), 1 );
70
- //noinspection ConstantConditions
71
- generatedKeys .addAll (rse .extractData (keys ));
72
- } finally {
73
- JdbcUtils .closeResultSet (keys );
70
+ if (JdbcUtils .supportsBatchUpdates (ps .getConnection ())) {
71
+ for (int i = 0 ; i < batchSize ; i ++) {
72
+ bpss .setValues (ps , i );
73
+ ps .addBatch ();
74
+ }
75
+ int [] results = ps .executeBatch ();
76
+ storeGeneratedKeys (generatedKeyHolder ).doInPreparedStatement (ps );
77
+ return results ;
78
+ } else {
79
+ List <Integer > rowsAffected = new ArrayList <>();
80
+ for (int i = 0 ; i < batchSize ; i ++) {
81
+ bpss .setValues (ps , i );
82
+ rowsAffected .add (ps .executeUpdate ());
74
83
}
84
+ int [] rowsAffectedArray = new int [rowsAffected .size ()];
85
+ storeGeneratedKeys (generatedKeyHolder ).doInPreparedStatement (ps );
86
+ for (int i = 0 ; i < rowsAffectedArray .length ; i ++) {
87
+ rowsAffectedArray [i ] = rowsAffected .get (i );
88
+ }
89
+ return rowsAffectedArray ;
75
90
}
76
- return results ;
77
91
};
78
92
return jdbcOperations .execute (psc , preparedStatementCallback );
79
93
}
80
94
81
- @ Nullable
82
- public int [] batchUpdate (String insertSql , SqlParameterSource [] sqlParameterSources ,
83
- KeyHolder generatedKeyHolder , String [] keyColumnNames ) {
84
- // TODO: This is largely duplicated from spring-jdbc and should be replaced with a call into
85
- // NamedParameterJdbcTemplate#batchUpdate once a method taking KeyHolder is added there.
86
- ParsedSql parsedSql = NamedParameterUtils .parseSqlStatement (insertSql );
87
- SqlParameterSource paramSource = sqlParameterSources [0 ];
88
- String sqlToUse = NamedParameterUtils .substituteNamedParameters (parsedSql , paramSource );
89
- List <SqlParameter > declaredParameters = NamedParameterUtils .buildSqlParameterList (parsedSql , paramSource );
90
- PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory (sqlToUse , declaredParameters );
91
- pscf .setReturnGeneratedKeys (true );
92
- pscf .setGeneratedKeysColumnNames (keyColumnNames );
93
- Object [] params = NamedParameterUtils .buildValueArray (parsedSql , paramSource , null );
94
- PreparedStatementCreator psc = pscf .newPreparedStatementCreator (params );
95
- BatchPreparedStatementSetter bpss = new BatchPreparedStatementSetter () {
96
- @ Override
97
- public void setValues (PreparedStatement ps , int i ) throws SQLException {
98
- Object [] values = NamedParameterUtils .buildValueArray (parsedSql , sqlParameterSources [i ], null );
99
- pscf .newPreparedStatementSetter (values ).setValues (ps );
100
- }
101
-
102
- @ Override
103
- public int getBatchSize () {
104
- return sqlParameterSources .length ;
105
- }
106
- };
107
- PreparedStatementCallback <int []> preparedStatementCallback = ps -> {
108
- int batchSize = bpss .getBatchSize ();
109
- for (int i = 0 ; i < batchSize ; i ++) {
110
- bpss .setValues (ps , i );
111
- ps .addBatch ();
112
- }
113
- int [] results = ps .executeBatch ();
114
- List <Map <String , Object >> generatedKeys = ((KeyHolder ) generatedKeyHolder ).getKeyList ();
95
+ private PreparedStatementCallback <Void > storeGeneratedKeys (KeyHolder generatedKeyHolder ) {
96
+ return ps -> {
97
+ List <Map <String , Object >> generatedKeys = generatedKeyHolder .getKeyList ();
115
98
generatedKeys .clear ();
116
99
ResultSet keys = ps .getGeneratedKeys ();
117
100
if (keys != null ) {
@@ -120,12 +103,12 @@ public int getBatchSize() {
120
103
new RowMapperResultSetExtractor <>(new ColumnMapRowMapper (), 1 );
121
104
//noinspection ConstantConditions
122
105
generatedKeys .addAll (rse .extractData (keys ));
123
- } finally {
106
+ }
107
+ finally {
124
108
JdbcUtils .closeResultSet (keys );
125
109
}
126
110
}
127
- return results ;
111
+ return null ;
128
112
};
129
- return jdbcOperations .execute (psc , preparedStatementCallback );
130
113
}
131
114
}
0 commit comments