📄 sqlcache.java
字号:
}
/**
* Return a prepared SQL statement for the given statement string.
* The statement should either be closed after use.
*
* <p>Only works for single statements, not compound statements.
* @param stmt the sql statement to prepare.
* @return a prepared SQL statement appropriate for the JDBC connection
* used when this SQLCache was constructed or null if there is no such
* connection.
*/
public synchronized PreparedStatement prepareSQLStatement(String sql) throws SQLException {
if (m_connection == null) return null;
return doPrepareSQLStatement(sql);
}
public synchronized PreparedStatement getPreparedSQLStatement(String opname) throws SQLException {
return getPreparedSQLStatement(opname, (String[]) null);
}
/**
* Variant on {@link #getPreparedSQLStatement getPreparedSQLStatement} which
* accesses the attribute variant correspond to the given attribute suffix.
*/
public synchronized PreparedStatement getPreparedSQLStatement(String opname, String attr) throws SQLException {
String[] param = {attr};
return getPreparedSQLStatement(opname,param);
}
/**
* Variant on {@link #getPreparedSQLStatement getPreparedSQLStatement} which
* access the attribute variant correspond to the given attribute suffix.
*/
public synchronized PreparedStatement getPreparedSQLStatement(String opname, String attrA, String attrB) throws SQLException {
String[] param = {attrA,attrB};
return getPreparedSQLStatement(opname,param);
}
/**
* Return a prepared statement to the statement pool for reuse by
* another caller. Any close problems logged rather than raising exception
* so that iterator close() operations can be silent so that they can meet
* the ClosableIterator signature.
*/
public synchronized void returnPreparedSQLStatement(PreparedStatement ps) {
if (!CACHE_PREPARED_STATEMENTS) {
try {
ps.close();
} catch (SQLException e) {
logger.warn("Problem discarded prepared statement", e);
}
return;
}
List psl = (List) m_cachedStmtInUse.get(ps);
if (psl != null) {
if (psl.size() >= MAX_PS_CACHE) {
try {
ps.close();
} catch (SQLException e) {
logger.warn("Problem discarded prepared statement", e);
}
} else {
psl.add(ps);
}
m_cachedStmtInUse.remove(ps);
} else {
throw new JenaException("Attempt to return unused prepared statement");
}
}
/**
* Execute a named pre-prepared SQL query statement taking a set of arguments and return
* a set of results as an iterator (probably a subclass of ResultSetIterator. Returns null
* if they query is an update (as opposed to an empty iterator for a true query which happens
* to return no answers).
* <p>
* Not sure this is a good design. Reducing this to a general interface leads to lots of clunky
* wrapping and unwrapping of primitive types, coercions and lack of compile-time type checking.
* On the other hand letting the clients do this themselves with direct jdbc calls leaves us up
* to the mercy of the client to correctly use returnPreparedSQLStatement and on average seems
* to lead to more duplication of boiler plate code. Currently the client can chose either approach.
* <p>
* The calling arguments are passed in as an array.
*/
public ResultSetIterator runSQLQuery(String opname, Object[] args) throws SQLException {
PreparedStatement ps = getPreparedSQLStatement(opname);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
return executeSQL(ps, opname, new ResultSetIterator());
}
/**
* Variant on {@link #runSQLQuery} which
* access the attribute variant correspond to the given attribute suffix.
*/
public ResultSetIterator runSQLQuery(String opname,String attr, Object[] args) throws SQLException {
String aop = concatOpName(opname, attr);
PreparedStatement ps = getPreparedSQLStatement(aop);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
return executeSQL(ps, aop, new ResultSetIterator());
}
/**
* Variant on {@link #runSQLQuery} which
* access the attribute variant correspond to the given attribute suffix.
*/
public ResultSetIterator runSQLQuery(String opname,String attrA, String attrB, Object[] args) throws SQLException {
String aop = concatOpName(opname, attrA, attrB);
PreparedStatement ps = getPreparedSQLStatement(aop);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
return executeSQL(ps, aop, new ResultSetIterator());
}
/**
* Execute a named pre-prepared SQL update statement taking a set of arguments and returning
* the update count.
*/
public int runSQLUpdate(String opname, Object[] args) throws SQLException {
PreparedStatement ps = getPreparedSQLStatement(opname);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
int result = ps.executeUpdate();
returnPreparedSQLStatement(ps);
return result;
}
/**
* Variant on {@link #runSQLUpdate} which
* access the attribute variant correspond to the given attribute suffix.
*/
public int runSQLUpdate(String opname,String attrA, Object[] args) throws SQLException {
String aop = concatOpName(opname, attrA);
PreparedStatement ps = getPreparedSQLStatement(aop);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
int result = ps.executeUpdate();
returnPreparedSQLStatement(ps);
return result;
}
/**
* Variant on {@link #runSQLUpdate} which
* access the attribute variant correspond to the given attribute suffix.
*/
public int runSQLUpdate(String opname,String attrA, String attrB, Object[] args) throws SQLException {
String aop = concatOpName(opname, attrA, attrB);
PreparedStatement ps = getPreparedSQLStatement(aop);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
int result = ps.executeUpdate();
returnPreparedSQLStatement(ps);
return result;
}
/**
* Execute a named pre-prepared SQL query statement taking a set of arguments and return
* a set of results as an iterator (probably a subclass of ResultSetIterator. Returns null
* if they query is an update (as opposed to an empty iterator for a true query which happens
* to return no answers).
* <p>
* Not sure this is a good design. Reducing this to a general interface leads to lots of clunky
* wrapping and unwrapping of primitive types, coercions and lack of compile-time type checking.
* On the other hand letting the clients do this themselves with direct jdbc calls leaves us up
* to the mercy of the client to correctly use returnPreparedSQLStatement and on average seems
* to lead to more duplication of boiler plate code. Currently the client can chose either approach.
* <p>
* @param opname the name of the SQL operation to perform
* @param args the arguments to pass to the SQL operation as an array of Objects
* @param iterator the iterator to use to return the results
*/
public ResultSetIterator runSQLQuery(String opname, Object[] args, ResultSetIterator iterator) throws SQLException {
PreparedStatement ps = getPreparedSQLStatement(opname);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
return executeSQL(ps, opname, iterator);
}
/**
* Variant on {@link #runSQLQuery} which
* access the attribute variant correspond to the given attribute suffix.
*/
public ResultSetIterator runSQLQuery(String opname, String attrA, Object[] args, ResultSetIterator iterator) throws SQLException {
String aop = concatOpName(opname,attrA);
PreparedStatement ps = getPreparedSQLStatement(aop);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
return executeSQL(ps, aop, iterator);
}
/**
* Variant on {@link #runSQLQuery} which
* access the attribute variant correspond to the given attribute suffix.
*/
public ResultSetIterator runSQLQuery(String opname, String attrA, String attrB, Object[] args, ResultSetIterator iterator) throws SQLException {
String aop = concatOpName(opname,attrA, attrB);
PreparedStatement ps = getPreparedSQLStatement(aop);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1, args[i]);
}
}
return executeSQL(ps, aop, iterator);
}
/**
* Run a group of sql statements - normally used for db formating and clean up.
* All statements are executed even if one raises an error then the error is
* reported at the end.
*
* Attribute version -- substitute the ${a} attribute macro
* for the current attribute
*/
public void runSQLGroup(String opname, String [] attr) throws SQLException {
String op = null;
SQLException eignore = null;
String operror = null;
java.sql.Statement sql = getConnection().createStatement();
Iterator ops = getSQLStatementGroup(opname).iterator();
int attrCnt = attr == null ? 0 : attr.length;
if ( attrCnt > 6 )
throw new RDFRDBException("Too many parameters");
while (ops.hasNext()) {
op = (String) ops.next();
if ( attrCnt > 0 ) op = substitute(op,"${a}",attr[0]);
if ( attrCnt > 1 ) op = substitute(op,"${b}",attr[1]);
if ( attrCnt > 2 ) op = substitute(op,"${c}",attr[2]);
if ( attrCnt > 3 ) op = substitute(op,"${d}",attr[3]);
if ( attrCnt > 4 ) op = substitute(op,"${e}",attr[4]);
if ( attrCnt > 5 ) op = substitute(op,"${f}",attr[5]);
try {
sql.execute(op);
} catch (SQLException e) {
// This is debugging legacy, exception is still reported at the end
// System.out.println("Exec failure: " + op + ": " + e);
operror = op;
eignore = e;
}
}
sql.close();
if (eignore != null) {
// operror records the failed operator, mostly internal debugging use
throw eignore;
}
}
/**
* Run a group of sql statements - normally used for db formating and clean up.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -