sql.java
来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 1,263 行 · 第 1/4 页
JAVA
1,263 行
public DataSource getDataSource() {
return dataSource;
}
public void commit() {
try {
this.useConnection.commit();
}
catch (SQLException e) {
log.log(Level.SEVERE, "Caught exception commiting connection: " + e, e);
}
}
public void rollback() {
try {
this.useConnection.rollback();
}
catch (SQLException e) {
log.log(Level.SEVERE, "Caught exception rollbacking connection: " + e, e);
}
}
/**
* @return Returns the updateCount.
*/
public int getUpdateCount() {
return updateCount;
}
/**
* If this instance was created with a single Connection then the connection
* is returned. Otherwise if this instance was created with a DataSource
* then this method returns null
*
* @return the connection wired into this object, or null if this object
* uses a DataSource
*/
public Connection getConnection() {
return useConnection;
}
/**
* Allows a closure to be passed in to configure the JDBC statements before they are executed
* to do things like set the query size etc.
*
* @param configureStatement
*/
public void withStatement(Closure configureStatement) {
this.configureStatement = configureStatement;
}
// Implementation methods
//-------------------------------------------------------------------------
/**
* @return the SQL version of the given query using ? instead of any
* parameter
*/
protected String asSql(GString gstring, List values) {
String[] strings = gstring.getStrings();
if (strings.length <= 0) {
throw new IllegalArgumentException("No SQL specified in GString: " + gstring);
}
boolean nulls = false;
StringBuffer buffer = new StringBuffer();
boolean warned = false;
Iterator iter = values.iterator();
for (int i = 0; i < strings.length; i++) {
String text = strings[i];
if (text != null) {
buffer.append(text);
}
if (iter.hasNext()) {
Object value = iter.next();
if (value != null) {
if(value instanceof ExpandedVariable){
buffer.append(((ExpandedVariable)value).getObject());
iter.remove();
}else{
boolean validBinding = true;
if (i < strings.length - 1) {
String nextText = strings[i + 1];
if ((text.endsWith("\"") || text.endsWith("'")) && (nextText.startsWith("'") || nextText.startsWith("\""))) {
if (!warned) {
log.warning("In Groovy SQL please do not use quotes around dynamic expressions " +
"(which start with $) as this means we cannot use a JDBC PreparedStatement " +
"and so is a security hole. Groovy has worked around your mistake but the security hole is still there. " +
"The expression so far is: " + buffer.toString() + "?" + nextText);
warned = true;
}
buffer.append(value);
iter.remove();
validBinding = false;
}
}
if (validBinding) {
buffer.append("?");
}
}
}
else {
nulls = true;
buffer.append("?'\"?"); // will replace these with nullish
// values
}
}
}
String sql = buffer.toString();
if (nulls) {
sql = nullify(sql);
}
return sql;
}
/**
* replace ?'"? references with NULLish
*
* @param sql
*/
protected String nullify(String sql) {
/*
* Some drivers (Oracle classes12.zip) have difficulty resolving data
* type if setObject(null). We will modify the query to pass 'null', 'is
* null', and 'is not null'
*/
//could be more efficient by compiling expressions in advance.
int firstWhere = findWhereKeyword(sql);
if (firstWhere >= 0) {
Pattern[] patterns = { Pattern.compile("(?is)^(.{" + firstWhere + "}.*?)!=\\s{0,1}(\\s*)\\?'\"\\?(.*)"),
Pattern.compile("(?is)^(.{" + firstWhere + "}.*?)<>\\s{0,1}(\\s*)\\?'\"\\?(.*)"),
Pattern.compile("(?is)^(.{" + firstWhere + "}.*?[^<>])=\\s{0,1}(\\s*)\\?'\"\\?(.*)"), };
String[] replacements = { "$1 is not $2null$3", "$1 is not $2null$3", "$1 is $2null$3", };
for (int i = 0; i < patterns.length; i++) {
Matcher matcher = patterns[i].matcher(sql);
while (matcher.matches()) {
sql = matcher.replaceAll(replacements[i]);
matcher = patterns[i].matcher(sql);
}
}
}
return sql.replaceAll("\\?'\"\\?", "null");
}
/**
* Find the first 'where' keyword in the sql.
*
* @param sql
*/
protected int findWhereKeyword(String sql) {
char[] chars = sql.toLowerCase().toCharArray();
char[] whereChars = "where".toCharArray();
int i = 0;
boolean inString = false; //TODO: Cater for comments?
boolean noWhere = true;
int inWhere = 0;
while (i < chars.length && noWhere) {
switch (chars[i]) {
case '\'':
if (inString) {
inString = false;
}
else {
inString = true;
}
break;
default:
if (!inString && chars[i] == whereChars[inWhere]) {
inWhere++;
if (inWhere == whereChars.length) {
return i;
}
}
}
i++;
}
return -1;
}
/**
* @return extracts the parameters from the expression as a List
*/
protected List getParameters(GString gstring) {
Object[] values = gstring.getValues();
List answer = new ArrayList(values.length);
for (int i = 0; i < values.length; i++) {
if (values[i] != null) {
answer.add(values[i]);
}
}
return answer;
}
/**
* Appends the parameters to the given statement
*/
protected void setParameters(List params, PreparedStatement statement) throws SQLException {
int i = 1;
for (Iterator iter = params.iterator(); iter.hasNext();) {
Object value = iter.next();
setObject(statement, i++, value);
}
}
/**
* Strategy method allowing derived classes to handle types differently
* such as for CLOBs etc.
*/
protected void setObject(PreparedStatement statement, int i, Object value)
throws SQLException {
if (value instanceof InParameter || value instanceof OutParameter) {
if(value instanceof InParameter){
InParameter in = (InParameter) value;
Object val = in.getValue();
if (null == val) {
statement.setNull(i, in.getType());
} else {
statement.setObject(i, val, in.getType());
}
}
if(value instanceof OutParameter){
try{
OutParameter out = (OutParameter)value;
((CallableStatement)statement).registerOutParameter(i,out.getType());
}catch(ClassCastException e){
throw new SQLException("Cannot register out parameter.");
}
}
} else {
statement.setObject(i, value);
}
}
protected Connection createConnection() throws SQLException {
if (dataSource != null) {
//Use a doPrivileged here as many different properties need to be
// read, and the policy
//shouldn't have to list them all.
Connection con = null;
try {
con = (Connection) AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws SQLException {
return dataSource.getConnection();
}
});
}
catch (PrivilegedActionException pae) {
Exception e = pae.getException();
if (e instanceof SQLException) {
throw (SQLException) e;
}
else {
throw (RuntimeException) e;
}
}
return con;
}
else {
//System.out.println("createConnection returning: " +
// useConnection);
return useConnection;
}
}
protected void closeResources(Connection connection, Statement statement, ResultSet results) {
if (results != null) {
try {
results.close();
}
catch (SQLException e) {
log.log(Level.SEVERE, "Caught exception closing resultSet: " + e, e);
}
}
closeResources(connection, statement);
}
protected void closeResources(Connection connection, Statement statement) {
if (statement != null) {
try {
statement.close();
}
catch (SQLException e) {
log.log(Level.SEVERE, "Caught exception closing statement: " + e, e);
}
}
if (dataSource != null) {
try {
connection.close();
}
catch (SQLException e) {
log.log(Level.SEVERE, "Caught exception closing connection: " + e, e);
}
}
}
private void warnDeprecated() {
if (!warned) {
warned = true;
log.warning("queryEach() is deprecated, please use eachRow() instead");
}
}
/**
* Provides a hook to be able to configure JDBC statements, such as to configure
*
* @param statement
*/
protected void configure(Statement statement) {
if (configureStatement != null) {
configureStatement.call(statement);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?