下面列出了java.sql.PreparedStatement#getClass ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void setLongVarChar(PreparedStatement Statmt, int ColIndex, String s, int jdbcType) throws SQLException {
Method m;
Class<? extends PreparedStatement> c = Statmt.getClass();
String className = c.getName();
if (className.equals("oracle.jdbc.driver.T4CPreparedStatement") || className.equals("oracle.jdbc.driver.T4CCallableStatement")) {
// When updating an Oracle CLOB column using the Oracle JDBC driver we need to use the
// Oracle proprietary method setStringForClob() so it will work for strings longer than 32765.
// NORMAL CODE: ((oracle.jdbc.OraclePreparedStatement)Statmt).setStringForClob( ColIndex, s );
try {
m = c.getMethod("setStringForClob", new Class[] { int.class, String.class });
m.invoke(Statmt, new Object[] { new Integer(ColIndex), s });
} catch (Exception e) {
// If the reflection code fails for some reason then just call setObject()
Statmt.setObject(ColIndex, s, jdbcType);
}
} else {
// for MS SQL Server via JDBC-ODBC Bridge, if you try to use setString()
// instead of setObject(), it will pad VARCHAR columns when it shouldn't
Statmt.setObject(ColIndex, s, jdbcType);
}
}
private CallableStatement toCallableStatement(PreparedStatement statement) {
if ( !CallableStatement.class.isInstance( statement ) ) {
throw new HibernateException(
"BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass()
);
}
return (CallableStatement) statement;
}
private static void setOracleNClob(PreparedStatement Statmt, int ColIndex, String s, int jdbcType) throws SQLException {
Method m;
Class<? extends PreparedStatement> c = Statmt.getClass();
String className = c.getName();
if (className.equals("oracle.jdbc.driver.T4CPreparedStatement")) {
// When updating an Oracle NCLOB column using the Oracle JDBC driver we need to use the
// Oracle proprietary method setFormOfUse() so it will know it's an NCLOB instead of CLOB.
// NOTE: a string longer than 2000 characters will result in the following error:
// "ORA-01461: can bind a LONG value only for insert into a LONG column."
// Using setString, setCharacterStream or setObject instead of setStringForClob
// results in the same limitation.
// NORMAL CODE: ((oracle.jdbc.OraclePreparedStatement)Statmt).setFormOfUse( ColIndex, oracle.jdbc.OraclePreparedStatement.FORM_NCHAR );
// NORMAL CODE: ((oracle.jdbc.OraclePreparedStatement)Statmt).setStringForClob( ColIndex, s );
try {
m = c.getMethod("setFormOfUse", new Class[] { int.class, short.class });
m.invoke(Statmt, new Object[] { new Integer(ColIndex), new Short(FORM_NCHAR) });
m = c.getMethod("setStringForClob", new Class[] { int.class, String.class });
m.invoke(Statmt, new Object[] { new Integer(ColIndex), s });
} catch (Exception e) {
// If the reflection code fails for some reason then just call setObject()
Statmt.setObject(ColIndex, s, Types.CLOB);
}
} else {
// Need to pass a jdbc type of Types.CLOB instead of ORACLE_NCLOB since the JDBC drivers
// won't recognize ORACLE_NCLOB.
Statmt.setObject(ColIndex, s, Types.CLOB);
}
}
private static void setFormOfUseToNCHAR(PreparedStatement Statmt, int ColIndex) {
Class<? extends PreparedStatement> c = Statmt.getClass();
String className = c.getName();
if (className.equals("oracle.jdbc.driver.T4CPreparedStatement")) {
try {
Method m = c.getMethod("setFormOfUse", new Class[] { int.class, short.class });
m.invoke(Statmt, new Object[] { new Integer(ColIndex), new Short(FORM_NCHAR) });
} catch (Exception e) {
}
}
}
private int getJdbcType(PreparedStatement Statmt, int cfSqlType) {
if (cfSqlType == CF_SQL_CLOB) {
// For Oracle callable statements we need to map the CF_SQL_CLOB
// type to the JDBC type java.sql.Types.CLOB.
Class<? extends PreparedStatement> c = Statmt.getClass();
String className = c.getName();
if (className.equals("oracle.jdbc.driver.T4CCallableStatement"))
return Types.CLOB;
}
return jdbcType[cfSqlType];
}
/**
* Insert a clob and test length.
*
* @param lengthless if true use the lengthless setCharacterStream api
*
* @throws SQLException
* @throws IOException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void testClobLength(boolean lengthless) throws SQLException, IOException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
getConnection().setAutoCommit(false);
Statement s = createStatement();
s.executeUpdate("CREATE TABLE CLOBTABLE (K INT CONSTRAINT PK PRIMARY KEY, C CLOB(" + LONG_CLOB_LENGTH + "))");
PreparedStatement ps = prepareStatement("INSERT INTO CLOBTABLE VALUES(?,?)");
// We allocate 16MB for the test so use something bigger than that.
ps.setInt(1,1);
LoopingAlphabetReader reader = new LoopingAlphabetReader(LONG_CLOB_LENGTH);
if (lengthless) {
Method m = null;
try {
Class c = ps.getClass();
m = c.getMethod("setCharacterStream",new Class[] {Integer.TYPE,
InputStream.class});
} catch (NoSuchMethodException e) {
// ignore method not found as method may not be present for
// jdk's lower than 1.6.
println("Skipping lengthless insert because method is not available");
return;
}
m.invoke(ps, new Object[] {new Integer(2), reader});
}
else
ps.setCharacterStream(2, reader, LONG_CLOB_LENGTH);
ps.executeUpdate();
// insert a zero length clob.
ps.setInt(1, 2);
ps.setString(2, "");
ps.executeUpdate();
// insert a null clob.
ps.setInt(1, 3);
ps.setString(2,null);
ps.executeUpdate();
// insert a short clob
ps.setInt(1, 4);
ps.setString(2, new String(SHORT_CLOB_CHARS));
ps.executeUpdate();
// Currently need to use optimizer override to force use of the index.
// Derby should use sort avoidance and do it automatically, but there
// appears to be a bug.
ResultSet rs = s.executeQuery("SELECT K, LENGTH(C), C FROM CLOBTABLE" +
"-- GEMFIREXD-PROPERTIES constraint=pk\n ORDER BY K");
rs.next();
assertEquals(LONG_CLOB_LENGTH_STRING,rs.getString(2));
// make sure we can still access the clob after getting length.
// It should be ok because we reset the stream
Reader rsReader = rs.getCharacterStream(3);
int len= 0;
char[] buf = new char[32672];
for (;;) {
int size = rsReader.read(buf);
if (size == -1)
break;
len += size;
int expectedValue = ((len -1) % 26) + 'a';
if (size != 0)
assertEquals(expectedValue,buf[size -1]);
}
assertEquals(LONG_CLOB_LENGTH,len);
// empty clob
rs.next();
assertEquals("0",rs.getString(2));
String chars = rs.getString(3);
assertEquals(0, chars.length());
// null clob
rs.next();
assertEquals(null, rs.getString(2));
chars = rs.getString(3);
assertEquals(null, chars);
// short clob
rs.next();
assertEquals("" + SHORT_CLOB_CHARS.length , rs.getString(2));
chars = rs.getString(3);
assertTrue(Arrays.equals(chars.toCharArray(), SHORT_CLOB_CHARS));
rs.close();
// Select just length without selecting the clob.
rs = s.executeQuery("SELECT K, LENGTH(C) FROM CLOBTABLE " +
"ORDER BY K");
JDBC.assertFullResultSet(rs, new String [][] {{"1",LONG_CLOB_LENGTH_STRING},{"2","0"},
{"3",null},{"4","6"}});
}
private CallableStatement toCallableStatement(PreparedStatement statement) {
if ( ! CallableStatement.class.isInstance( statement ) ) {
throw new HibernateException( "BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass() );
}
return ( CallableStatement ) statement;
}
/**
* Insert a clob and test length.
*
* @param lengthless if true use the lengthless setCharacterStream api
*
* @throws SQLException
* @throws IOException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void testClobLength(boolean lengthless) throws SQLException, IOException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
getConnection().setAutoCommit(false);
Statement s = createStatement();
s.executeUpdate("CREATE TABLE CLOBTABLE (K INT CONSTRAINT PK PRIMARY KEY, C CLOB(" + LONG_CLOB_LENGTH + "))");
PreparedStatement ps = prepareStatement("INSERT INTO CLOBTABLE VALUES(?,?)");
// We allocate 16MB for the test so use something bigger than that.
ps.setInt(1,1);
LoopingAlphabetReader reader = new LoopingAlphabetReader(LONG_CLOB_LENGTH);
if (lengthless) {
Method m = null;
try {
Class c = ps.getClass();
m = c.getMethod("setCharacterStream",new Class[] {Integer.TYPE,
InputStream.class});
} catch (NoSuchMethodException e) {
// ignore method not found as method may not be present for
// jdk's lower than 1.6.
println("Skipping lengthless insert because method is not available");
return;
}
m.invoke(ps, new Object[] {new Integer(2), reader});
}
else
ps.setCharacterStream(2, reader, LONG_CLOB_LENGTH);
ps.executeUpdate();
// insert a zero length clob.
ps.setInt(1, 2);
ps.setString(2, "");
ps.executeUpdate();
// insert a null clob.
ps.setInt(1, 3);
ps.setString(2,null);
ps.executeUpdate();
// insert a short clob
ps.setInt(1, 4);
ps.setString(2, new String(SHORT_CLOB_CHARS));
ps.executeUpdate();
// Currently need to use optimizer override to force use of the index.
// Derby should use sort avoidance and do it automatically, but there
// appears to be a bug.
ResultSet rs = s.executeQuery("SELECT K, LENGTH(C), C FROM CLOBTABLE" +
"-- GEMFIREXD-PROPERTIES constraint=pk\n ORDER BY K");
rs.next();
assertEquals(LONG_CLOB_LENGTH_STRING,rs.getString(2));
// make sure we can still access the clob after getting length.
// It should be ok because we reset the stream
Reader rsReader = rs.getCharacterStream(3);
int len= 0;
char[] buf = new char[32672];
for (;;) {
int size = rsReader.read(buf);
if (size == -1)
break;
len += size;
int expectedValue = ((len -1) % 26) + 'a';
if (size != 0)
assertEquals(expectedValue,buf[size -1]);
}
assertEquals(LONG_CLOB_LENGTH,len);
// empty clob
rs.next();
assertEquals("0",rs.getString(2));
String chars = rs.getString(3);
assertEquals(0, chars.length());
// null clob
rs.next();
assertEquals(null, rs.getString(2));
chars = rs.getString(3);
assertEquals(null, chars);
// short clob
rs.next();
assertEquals("" + SHORT_CLOB_CHARS.length , rs.getString(2));
chars = rs.getString(3);
assertTrue(Arrays.equals(chars.toCharArray(), SHORT_CLOB_CHARS));
rs.close();
// Select just length without selecting the clob.
rs = s.executeQuery("SELECT K, LENGTH(C) FROM CLOBTABLE " +
"ORDER BY K");
JDBC.assertFullResultSet(rs, new String [][] {{"1",LONG_CLOB_LENGTH_STRING},{"2","0"},
{"3",null},{"4","6"}});
}