1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2014 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
26
26
import java .sql .ResultSet ;
27
27
import java .sql .ResultSetMetaData ;
28
28
import java .sql .SQLException ;
29
+ import java .sql .SQLFeatureNotSupportedException ;
29
30
import java .sql .Statement ;
30
31
import java .sql .Types ;
31
-
32
32
import javax .sql .DataSource ;
33
33
34
34
import org .apache .commons .logging .Log ;
35
35
import org .apache .commons .logging .LogFactory ;
36
36
37
37
import org .springframework .jdbc .CannotGetJdbcConnectionException ;
38
38
import org .springframework .jdbc .datasource .DataSourceUtils ;
39
+ import org .springframework .util .ClassUtils ;
39
40
40
41
/**
41
42
* Generic utility methods for working with JDBC. Mainly for internal use
@@ -53,6 +54,10 @@ public abstract class JdbcUtils {
53
54
public static final int TYPE_UNKNOWN = Integer .MIN_VALUE ;
54
55
55
56
57
+ // Check for JDBC 4.1 getObject(int, Class) method - available on JDK 7 and higher
58
+ private static final boolean getObjectWithTypeAvailable =
59
+ ClassUtils .hasMethod (ResultSet .class , "getObject" , int .class , Class .class );
60
+
56
61
private static final Log logger = LogFactory .getLog (JdbcUtils .class );
57
62
58
63
@@ -134,74 +139,74 @@ public static Object getResultSetValue(ResultSet rs, int index, Class<?> require
134
139
return getResultSetValue (rs , index );
135
140
}
136
141
137
- Object value = null ;
138
- boolean wasNullCheck = false ;
142
+ Object value ;
139
143
140
144
// Explicitly extract typed value, as far as possible.
141
145
if (String .class .equals (requiredType )) {
142
- value = rs .getString (index );
146
+ return rs .getString (index );
143
147
}
144
148
else if (boolean .class .equals (requiredType ) || Boolean .class .equals (requiredType )) {
145
149
value = rs .getBoolean (index );
146
- wasNullCheck = true ;
147
150
}
148
151
else if (byte .class .equals (requiredType ) || Byte .class .equals (requiredType )) {
149
152
value = rs .getByte (index );
150
- wasNullCheck = true ;
151
153
}
152
154
else if (short .class .equals (requiredType ) || Short .class .equals (requiredType )) {
153
155
value = rs .getShort (index );
154
- wasNullCheck = true ;
155
156
}
156
157
else if (int .class .equals (requiredType ) || Integer .class .equals (requiredType )) {
157
158
value = rs .getInt (index );
158
- wasNullCheck = true ;
159
159
}
160
160
else if (long .class .equals (requiredType ) || Long .class .equals (requiredType )) {
161
161
value = rs .getLong (index );
162
- wasNullCheck = true ;
163
162
}
164
163
else if (float .class .equals (requiredType ) || Float .class .equals (requiredType )) {
165
164
value = rs .getFloat (index );
166
- wasNullCheck = true ;
167
165
}
168
166
else if (double .class .equals (requiredType ) || Double .class .equals (requiredType ) ||
169
167
Number .class .equals (requiredType )) {
170
168
value = rs .getDouble (index );
171
- wasNullCheck = true ;
172
169
}
173
- else if (byte [] .class .equals (requiredType )) {
174
- value = rs .getBytes (index );
170
+ else if (BigDecimal .class .equals (requiredType )) {
171
+ return rs .getBigDecimal (index );
175
172
}
176
173
else if (java .sql .Date .class .equals (requiredType )) {
177
- value = rs .getDate (index );
174
+ return rs .getDate (index );
178
175
}
179
176
else if (java .sql .Time .class .equals (requiredType )) {
180
- value = rs .getTime (index );
177
+ return rs .getTime (index );
181
178
}
182
179
else if (java .sql .Timestamp .class .equals (requiredType ) || java .util .Date .class .equals (requiredType )) {
183
- value = rs .getTimestamp (index );
180
+ return rs .getTimestamp (index );
184
181
}
185
- else if (BigDecimal .class .equals (requiredType )) {
186
- value = rs .getBigDecimal (index );
182
+ else if (byte [] .class .equals (requiredType )) {
183
+ return rs .getBytes (index );
187
184
}
188
185
else if (Blob .class .equals (requiredType )) {
189
- value = rs .getBlob (index );
186
+ return rs .getBlob (index );
190
187
}
191
188
else if (Clob .class .equals (requiredType )) {
192
- value = rs .getClob (index );
189
+ return rs .getClob (index );
193
190
}
194
191
else {
195
192
// Some unknown type desired -> rely on getObject.
196
- value = getResultSetValue (rs , index );
193
+ if (getObjectWithTypeAvailable ) {
194
+ try {
195
+ return rs .getObject (index , requiredType );
196
+ }
197
+ catch (SQLFeatureNotSupportedException ex ) {
198
+ logger .debug ("JDBC driver does not support JDBC 4.1 'getObject(int, Class)' method" , ex );
199
+ }
200
+ catch (AbstractMethodError err ) {
201
+ logger .debug ("JDBC driver does not implement JDBC 4.1 'getObject(int, Class)' method" , err );
202
+ }
203
+ }
204
+ // Fall back to getObject without type specification...
205
+ return getResultSetValue (rs , index );
197
206
}
198
207
199
- // Perform was-null check if demanded (for results that the
200
- // JDBC driver returns as primitives).
201
- if (wasNullCheck && value != null && rs .wasNull ()) {
202
- value = null ;
203
- }
204
- return value ;
208
+ // Perform was-null check if necessary (for results that the JDBC driver returns as primitives).
209
+ return (rs .wasNull () ? null : value );
205
210
}
206
211
207
212
/**
@@ -234,15 +239,12 @@ public static Object getResultSetValue(ResultSet rs, int index) throws SQLExcept
234
239
else if (obj instanceof Clob ) {
235
240
obj = rs .getString (index );
236
241
}
237
- else if (className != null &&
238
- ("oracle.sql.TIMESTAMP" .equals (className ) ||
239
- "oracle.sql.TIMESTAMPTZ" .equals (className ))) {
242
+ else if ("oracle.sql.TIMESTAMP" .equals (className ) || "oracle.sql.TIMESTAMPTZ" .equals (className )) {
240
243
obj = rs .getTimestamp (index );
241
244
}
242
245
else if (className != null && className .startsWith ("oracle.sql.DATE" )) {
243
246
String metaDataClassName = rs .getMetaData ().getColumnClassName (index );
244
- if ("java.sql.Timestamp" .equals (metaDataClassName ) ||
245
- "oracle.sql.TIMESTAMP" .equals (metaDataClassName )) {
247
+ if ("java.sql.Timestamp" .equals (metaDataClassName ) || "oracle.sql.TIMESTAMP" .equals (metaDataClassName )) {
246
248
obj = rs .getTimestamp (index );
247
249
}
248
250
else {
@@ -371,9 +373,6 @@ public static boolean supportsBatchUpdates(Connection con) {
371
373
catch (SQLException ex ) {
372
374
logger .debug ("JDBC driver 'supportsBatchUpdates' method threw exception" , ex );
373
375
}
374
- catch (AbstractMethodError err ) {
375
- logger .debug ("JDBC driver does not support JDBC 2.0 'supportsBatchUpdates' method" , err );
376
- }
377
376
return false ;
378
377
}
379
378
0 commit comments