DefaultLobCreator supports JDBC 4.0 set-stream variants without length parameter

Issue: SPR-12265
This commit is contained in:
Juergen Hoeller 2014-09-26 23:56:43 +02:00
parent 7f9baa3a09
commit d65db65fad
2 changed files with 47 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,13 @@ import org.apache.commons.logging.LogFactory;
* Invokes the direct accessor methods that {@code java.sql.ResultSet} * Invokes the direct accessor methods that {@code java.sql.ResultSet}
* and {@code java.sql.PreparedStatement} offer. * and {@code java.sql.PreparedStatement} offer.
* *
* <p>By default, incoming streams are going to be passed to the appropriate
* {@code setBinary/Ascii/CharacterStream} method on the JDBC driver's
* {@link PreparedStatement}. If the specified content length is negative,
* this handler will use the JDBC 4.0 variants of the set-stream methods
* without a length parameter; otherwise, it will pass the specified length
* on to the driver.
*
* <p>This LobHandler should work for any JDBC driver that is JDBC compliant * <p>This LobHandler should work for any JDBC driver that is JDBC compliant
* in terms of the spec's suggestions regarding simple BLOB and CLOB handling. * in terms of the spec's suggestions regarding simple BLOB and CLOB handling.
* This does not apply to Oracle 9i's drivers at all; as of Oracle 10g, * This does not apply to Oracle 9i's drivers at all; as of Oracle 10g,
@ -262,9 +269,12 @@ public class DefaultLobHandler extends AbstractLobHandler {
ps.setBlob(paramIndex, (Blob) null); ps.setBlob(paramIndex, (Blob) null);
} }
} }
else { else if (contentLength >= 0) {
ps.setBinaryStream(paramIndex, binaryStream, contentLength); ps.setBinaryStream(paramIndex, binaryStream, contentLength);
} }
else {
ps.setBinaryStream(paramIndex, binaryStream);
}
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(binaryStream != null ? "Set binary stream for BLOB with length " + contentLength : logger.debug(binaryStream != null ? "Set binary stream for BLOB with length " + contentLength :
"Set BLOB to null"); "Set BLOB to null");
@ -326,9 +336,12 @@ public class DefaultLobHandler extends AbstractLobHandler {
ps.setClob(paramIndex, (Clob) null); ps.setClob(paramIndex, (Clob) null);
} }
} }
else { else if (contentLength >= 0) {
ps.setAsciiStream(paramIndex, asciiStream, contentLength); ps.setAsciiStream(paramIndex, asciiStream, contentLength);
} }
else {
ps.setAsciiStream(paramIndex, asciiStream);
}
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(asciiStream != null ? "Set ASCII stream for CLOB with length " + contentLength : logger.debug(asciiStream != null ? "Set ASCII stream for CLOB with length " + contentLength :
"Set CLOB to null"); "Set CLOB to null");
@ -356,9 +369,12 @@ public class DefaultLobHandler extends AbstractLobHandler {
ps.setClob(paramIndex, (Clob) null); ps.setClob(paramIndex, (Clob) null);
} }
} }
else { else if (contentLength >= 0) {
ps.setCharacterStream(paramIndex, characterStream, contentLength); ps.setCharacterStream(paramIndex, characterStream, contentLength);
} }
else {
ps.setCharacterStream(paramIndex, characterStream);
}
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(characterStream != null ? "Set character stream for CLOB with length " + contentLength : logger.debug(characterStream != null ? "Set character stream for CLOB with length " + contentLength :
"Set CLOB to null"); "Set CLOB to null");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.junit.Test; import org.junit.Test;
import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.jdbc.support.lob.LobHandler;
@ -39,10 +40,14 @@ import static org.mockito.BDDMockito.*;
public class DefaultLobHandlerTests { public class DefaultLobHandlerTests {
private ResultSet rs = mock(ResultSet.class); private ResultSet rs = mock(ResultSet.class);
private PreparedStatement ps = mock(PreparedStatement.class); private PreparedStatement ps = mock(PreparedStatement.class);
private LobHandler lobHandler = new DefaultLobHandler(); private LobHandler lobHandler = new DefaultLobHandler();
private LobCreator lobCreator = lobHandler.getLobCreator(); private LobCreator lobCreator = lobHandler.getLobCreator();
@Test @Test
public void testGetBlobAsBytes() throws SQLException { public void testGetBlobAsBytes() throws SQLException {
lobHandler.getBlobAsBytes(rs, 1); lobHandler.getBlobAsBytes(rs, 1);
@ -82,12 +87,18 @@ public class DefaultLobHandlerTests {
@Test @Test
public void testSetBlobAsBinaryStream() throws SQLException, IOException { public void testSetBlobAsBinaryStream() throws SQLException, IOException {
InputStream bis = new ByteArrayInputStream("testContent".getBytes()); InputStream bis = new ByteArrayInputStream("testContent".getBytes());
lobCreator.setBlobAsBinaryStream(ps, 1, bis, 11); lobCreator.setBlobAsBinaryStream(ps, 1, bis, 11);
verify(ps).setBinaryStream(1, bis, 11); verify(ps).setBinaryStream(1, bis, 11);
} }
@Test
public void testSetBlobAsBinaryStreamWithoutLength() throws SQLException, IOException {
InputStream bis = new ByteArrayInputStream("testContent".getBytes());
lobCreator.setBlobAsBinaryStream(ps, 1, bis, -1);
verify(ps).setBinaryStream(1, bis);
}
@Test @Test
public void testSetClobAsString() throws SQLException, IOException { public void testSetClobAsString() throws SQLException, IOException {
String content = "testContent"; String content = "testContent";
@ -102,6 +113,13 @@ public class DefaultLobHandlerTests {
verify(ps).setAsciiStream(1, bis, 11); verify(ps).setAsciiStream(1, bis, 11);
} }
@Test
public void testSetClobAsAsciiStreamWithoutLength() throws SQLException, IOException {
InputStream bis = new ByteArrayInputStream("testContent".getBytes());
lobCreator.setClobAsAsciiStream(ps, 1, bis, -1);
verify(ps).setAsciiStream(1, bis);
}
@Test @Test
public void testSetClobAsCharacterStream() throws SQLException, IOException { public void testSetClobAsCharacterStream() throws SQLException, IOException {
Reader str = new StringReader("testContent"); Reader str = new StringReader("testContent");
@ -109,4 +127,11 @@ public class DefaultLobHandlerTests {
verify(ps).setCharacterStream(1, str, 11); verify(ps).setCharacterStream(1, str, 11);
} }
@Test
public void testSetClobAsCharacterStreamWithoutLength() throws SQLException, IOException {
Reader str = new StringReader("testContent");
lobCreator.setClobAsCharacterStream(ps, 1, str, -1);
verify(ps).setCharacterStream(1, str);
}
} }