1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2013 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.
32
32
import org .apache .commons .logging .LogFactory ;
33
33
34
34
/**
35
- * Default implementation of the {@link LobHandler} interface. Invokes
36
- * the direct accessor methods that {@code java.sql.ResultSet}
35
+ * Default implementation of the {@link LobHandler} interface.
36
+ * Invokes the direct accessor methods that {@code java.sql.ResultSet}
37
37
* and {@code java.sql.PreparedStatement} offer.
38
38
*
39
39
* <p>This LobHandler should work for any JDBC driver that is JDBC compliant
40
40
* in terms of the spec's suggestions regarding simple BLOB and CLOB handling.
41
- * This does not apply to Oracle 9i, and only to a limited degree to Oracle 10g!
42
- * As a consequence, use {@link OracleLobHandler} for accessing Oracle BLOBs/CLOBs.
41
+ * This does not apply to Oracle 9i's drivers at all; as of Oracle 10g,
42
+ * it does work but may still come with LOB size limitations. Consider using
43
+ * recent Oracle drivers even when working against an older database server.
44
+ * See the {@link LobHandler} javadoc for the full set of recommendations.
43
45
*
44
46
* <p>Some JDBC drivers require values with a BLOB/CLOB target column to be
45
- * explicitly set through the JDBC {@code setBlob} / {@code setClob}
46
- * API: for example, PostgreSQL's driver. Switch the {@link #setWrapAsLob "wrapAsLob"}
47
+ * explicitly set through the JDBC {@code setBlob} / {@code setClob} API:
48
+ * for example, PostgreSQL's driver. Switch the {@link #setWrapAsLob "wrapAsLob"}
47
49
* property to "true" when operating against such a driver.
48
50
*
49
51
* <p>On JDBC 4.0, this LobHandler also supports streaming the BLOB/CLOB content
50
52
* via the {@code setBlob} / {@code setClob} variants that take a stream
51
53
* argument directly. Consider switching the {@link #setStreamAsLob "streamAsLob"}
52
54
* property to "true" when operating against a fully compliant JDBC 4.0 driver.
53
55
*
54
- * <p>See the {@link LobHandler} javadoc for a summary of recommendations.
56
+ * <p>Finally, primarily as a direct equivalent to {@link OracleLobHandler},
57
+ * this LobHandler also supports the creation of temporary BLOB/CLOB objects.
58
+ * Consider switching the {@link #setCreateTemporaryLob "createTemporaryLob"}
59
+ * property to "true" when "streamAsLob" happens to run into LOB size limitations.
60
+ *
61
+ * <p>See the {@link LobHandler} interface javadoc for a summary of recommendations.
55
62
*
56
63
* @author Juergen Hoeller
57
64
* @since 04.12.2003
58
- * @see #setStreamAsLob
59
65
* @see java.sql.ResultSet#getBytes
60
66
* @see java.sql.ResultSet#getBinaryStream
61
67
* @see java.sql.ResultSet#getString
@@ -75,15 +81,18 @@ public class DefaultLobHandler extends AbstractLobHandler {
75
81
76
82
private boolean streamAsLob = false ;
77
83
84
+ private boolean createTemporaryLob = false ;
85
+
78
86
79
87
/**
80
88
* Specify whether to submit a byte array / String to the JDBC driver
81
89
* wrapped in a JDBC Blob / Clob object, using the JDBC {@code setBlob} /
82
90
* {@code setClob} method with a Blob / Clob argument.
83
91
* <p>Default is "false", using the common JDBC 2.0 {@code setBinaryStream}
84
- * / {@code setCharacterStream} method for setting the content.
85
- * Switch this to "true" for explicit Blob / Clob wrapping against
86
- * JDBC drivers that are known to require such wrapping (e.g. PostgreSQL's).
92
+ * / {@code setCharacterStream} method for setting the content. Switch this
93
+ * to "true" for explicit Blob / Clob wrapping against JDBC drivers that
94
+ * are known to require such wrapping (e.g. PostgreSQL's for access to OID
95
+ * columns, whereas BYTEA columns need to be accessed the standard way).
87
96
* <p>This setting affects byte array / String arguments as well as stream
88
97
* arguments, unless {@link #setStreamAsLob "streamAsLob"} overrides this
89
98
* handling to use JDBC 4.0's new explicit streaming support (if available).
@@ -100,7 +109,7 @@ public void setWrapAsLob(boolean wrapAsLob) {
100
109
* {@code setClob} method with a stream argument.
101
110
* <p>Default is "false", using the common JDBC 2.0 {@code setBinaryStream}
102
111
* / {@code setCharacterStream} method for setting the content.
103
- * Switch this to "true" for explicit JDBC 4.0 usage , provided that your
112
+ * Switch this to "true" for explicit JDBC 4.0 streaming , provided that your
104
113
* JDBC driver actually supports those JDBC 4.0 operations (e.g. Derby's).
105
114
* <p>This setting affects stream arguments as well as byte array / String
106
115
* arguments, requiring JDBC 4.0 support. For supporting LOB content against
@@ -112,6 +121,23 @@ public void setStreamAsLob(boolean streamAsLob) {
112
121
this .streamAsLob = streamAsLob ;
113
122
}
114
123
124
+ /**
125
+ * Specify whether to copy a byte array / String into a temporary JDBC
126
+ * Blob / Clob object created through the JDBC 4.0 {@code createBlob} /
127
+ * {@code createClob} methods.
128
+ * <p>Default is "false", using the common JDBC 2.0 {@code setBinaryStream}
129
+ * / {@code setCharacterStream} method for setting the content. Switch this
130
+ * to "true" for explicit Blob / Clob creation using JDBC 4.0.
131
+ * <p>This setting affects stream arguments as well as byte array / String
132
+ * arguments, requiring JDBC 4.0 support. For supporting LOB content against
133
+ * JDBC 3.0, check out the {@link #setWrapAsLob "wrapAsLob"} setting.
134
+ * @see java.sql.Connection#createBlob()
135
+ * @see java.sql.Connection#createClob()
136
+ */
137
+ public void setCreateTemporaryLob (boolean createTemporaryLob ) {
138
+ this .createTemporaryLob = createTemporaryLob ;
139
+ }
140
+
115
141
116
142
public byte [] getBlobAsBytes (ResultSet rs , int columnIndex ) throws SQLException {
117
143
logger .debug ("Returning BLOB as bytes" );
@@ -169,12 +195,12 @@ public Reader getClobAsCharacterStream(ResultSet rs, int columnIndex) throws SQL
169
195
}
170
196
171
197
public LobCreator getLobCreator () {
172
- return new DefaultLobCreator ();
198
+ return ( this . createTemporaryLob ? new TemporaryLobCreator () : new DefaultLobCreator () );
173
199
}
174
200
175
201
176
202
/**
177
- * Default LobCreator implementation as inner class.
203
+ * Default LobCreator implementation as an inner class.
178
204
* Can be subclassed in DefaultLobHandler extensions.
179
205
*/
180
206
protected class DefaultLobCreator implements LobCreator {
@@ -268,15 +294,10 @@ public void setClobAsAsciiStream(
268
294
PreparedStatement ps , int paramIndex , InputStream asciiStream , int contentLength )
269
295
throws SQLException {
270
296
271
- if (streamAsLob || wrapAsLob ) {
297
+ if (streamAsLob ) {
272
298
if (asciiStream != null ) {
273
299
try {
274
- if (streamAsLob ) {
275
- ps .setClob (paramIndex , new InputStreamReader (asciiStream , "US-ASCII" ), contentLength );
276
- }
277
- else {
278
- ps .setClob (paramIndex , new PassThroughClob (asciiStream , contentLength ));
279
- }
300
+ ps .setClob (paramIndex , new InputStreamReader (asciiStream , "US-ASCII" ), contentLength );
280
301
}
281
302
catch (UnsupportedEncodingException ex ) {
282
303
throw new SQLException ("US-ASCII encoding not supported: " + ex );
@@ -286,6 +307,14 @@ public void setClobAsAsciiStream(
286
307
ps .setClob (paramIndex , (Clob ) null );
287
308
}
288
309
}
310
+ else if (wrapAsLob ) {
311
+ if (asciiStream != null ) {
312
+ ps .setClob (paramIndex , new PassThroughClob (asciiStream , contentLength ));
313
+ }
314
+ else {
315
+ ps .setClob (paramIndex , (Clob ) null );
316
+ }
317
+ }
289
318
else {
290
319
ps .setAsciiStream (paramIndex , asciiStream , contentLength );
291
320
}
@@ -325,7 +354,7 @@ else if (wrapAsLob) {
325
354
}
326
355
327
356
public void close () {
328
- // nothing to do here
357
+ // nothing to do when not creating temporary LOBs
329
358
}
330
359
}
331
360
0 commit comments