package com.lizard.fastdb.jdbc;
import java.io.Serializable;
import java.sql.BatchUpdateException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.lizard.fastdb.DBException;
import com.lizard.fastdb.connection.ConnectionPool;
import com.lizard.fastdb.datasource.DataSource;
import com.lizard.fastdb.datasource.DataSourceUtil;
import com.lizard.fastdb.dialect.Dialect;
import com.lizard.fastdb.persistence.PersistenceUtil;
import com.lizard.fastdb.util.StringUtils;
/**
* JDBC 操作实现类, 实现了操作接口类中的接口方法
*
* @author SHEN.GANG
*/
public class JdbcHandlerImpl implements JdbcHandler, Serializable
{
private static final long serialVersionUID = -4972487968257069301L;
private static final Log logger = LogFactory.getLog(JdbcHandlerImpl.class);
private DataSource ds = null; // 对应的数据源配置
/**
* 查询对象,true -- 表示不使用getParameterType,因为Oracle不支持此功能
*/
private QueryRunner QUERY_RUNNER = new QueryRunner(true);
/**
* 存储批量分批操作大小,默认不分批操作
*/
private static final ThreadLocal<Integer> BATCH_SIZE_LOCAL = new ThreadLocal<Integer>()
{
protected Integer initialValue()
{
return -1;
}
};
/**
* 重写dbutils中的ColumnListHandler的handleRow方法,处理BigInt型数据为Long型 注意:这里处理BigInteger 和 BigDecimal 方式已经转移到 apache dbutils 源码中了,所以注释了处理代码段。
*/
private final static ColumnListHandler COLUMNLIST_HANDLER = new ColumnListHandler();
// {
// @Override
// protected Object handleRow(ResultSet rs) throws SQLException
// {
// Object obj = super.handleRow(rs);
// if (obj instanceof BigInteger)
// {
// return ((BigInteger) obj).longValue();
// }
// else if (obj instanceof BigDecimal)
// {
// return ((BigDecimal) obj).longValue();
// }
//
// return obj;
// }
// };
/**
* 创建 StringListHandler对象用于 queryForList( String.class, ...); 支持
*/
private final static StringListHandler STRINGLIST_HANDLER = new StringListHandler();
/**
* 重写dbutils中的ScalarHandler中的handle方法,处理BigInt型数据为Long型 注意:这里处理BigInteger 和 BigDecimal 方式已经转移到 apache dbutils 源码中了,所以注释了处理代码段。
*/
private final static ScalarHandler SCALAR_HANDLER = new ScalarHandler();
// {
// @Override
// public Object handle(ResultSet rs) throws SQLException
// {
// Object obj = super.handle(rs);
// if (obj instanceof BigInteger)
// {
// return ((BigInteger) obj).longValue();
// }
// else if (obj instanceof BigDecimal)
// {
// return ((BigDecimal) obj).longValue();
// }
//
// return obj;
// }
// };
/**
* 基本数据类型定义
*/
private final static Set<Class<?>> PRIMITIVE_CLASSES = new HashSet<Class<?>>()
{
private static final long serialVersionUID = -7678425758902391103L;
{
add(Long.class);
add(Integer.class);
add(String.class);
add(java.util.Date.class);
add(java.sql.Date.class);
add(java.sql.Timestamp.class);
add(Object.class); // 将Object定义为基本数据类型是为了不进入BeanHandler处理
}
};
/**
* 创建一个JdbcHandler对象,用于静态数据源和动态数据源
*
* @param ds 数据源配置对象
*/
public JdbcHandlerImpl(DataSource ds)
{
this.ds = ds;
}
/**
* 判断一个Class是否是基本数据类型
*
* @param cls 要进行判断的类
* @return 是否是基本数据类型
*/
private final static boolean isPrimitiveClass(Class<?> cls)
{
return cls.isPrimitive() || PRIMITIVE_CLASSES.contains(cls);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#query(java.lang.String, com.lizard.fastdb.jdbc.RowCallbackHandler, java.lang.Object[])
*/
public <T> T query(String sql, RowCallbackHandler<T> rch, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
try
{
return (T) QUERY_RUNNER.query(conn, sql, rch, paramValues);
}
catch (SQLException e)
{
throw new DBException("Failed to execute [ " + JdbcUtil.fillSQL(sql, paramValues) + " ] by RowCallbackHandler<T>!", e);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#query(java.lang.String, com.lizard.fastdb.jdbc.RowCallbackHandler, java.util.Map)
*/
public <T> T query(String namedSql, RowCallbackHandler<T> rch, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return query(namedSQL.getSQL(), rch, namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForBean(java.lang.Class, java.lang.String)
*/
public <T> T queryForBean(Class<T> beanClass, String sql)
{
return queryForBean(beanClass, sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForBean(java.lang.Class, java.lang.String, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T> T queryForBean(Class<T> beanClass, String sql, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
try
{
return (T) QUERY_RUNNER.query(conn, sql, isPrimitiveClass(beanClass) ? SCALAR_HANDLER : new BeanHandler<T>(beanClass), paramValues);
}
catch (SQLException e)
{
throw new DBException("Failed to query For Bean<" + beanClass.getName() + "> by [ " + JdbcUtil.fillSQL(sql, paramValues)
+ " ]!", e);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForBean(java.lang.Class, java.lang.String, java.util.Map)
*/
public <T> T queryForBean(Class<T> beanClass, String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForBean(beanClass, namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForInteger(java.lang.String)
*/
public Integer queryForInteger(String sql)
{
return queryForInteger(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForInteger(java.lang.String, java.lang.Object[])
*/
public Integer queryForInteger(String sql, Object... paramValues)
{
try
{
Object intObj = queryForObject(sql, paramValues);
if (intObj != null)
{
return Integer.parseInt(intObj.toString());
}
else
{
return null;
}
}
catch (ClassCastException e)
{
throw new DBException("Failed to query for Integer value by [" + JdbcUtil.fillSQL(sql, paramValues) + "]!", e);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForInteger(java.lang.String, java.util.Map)
*/
public Integer queryForInteger(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForInteger(namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForLong(java.lang.String)
*/
public Long queryForLong(String sql)
{
return queryForLong(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForLong(java.lang.String, java.lang.Object[])
*/
public Long queryForLong(String sql, Object... paramValues)
{
try
{
Object longObj = queryForObject(sql, paramValues);
if (longObj != null)
{
return Long.parseLong(longObj.toString());
}
else
{
return 0L;
}
}
catch (ClassCastException e)
{
throw new DBException("Failed to query for Long value by [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]", e);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForLong(java.lang.String, java.util.Map)
*/
public Long queryForLong(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForLong( namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues) );
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForMap(java.lang.String)
*/
public Map<String, Object> queryForMap(String sql)
{
return queryForMap(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForMap(java.lang.String, java.lang.Object[])
*/
public Map<String, Object> queryForMap(String sql, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
try
{
return (Map<String, Object>) QUERY_RUNNER.query(conn, sql, new MapHandler(), paramValues);
}
catch (SQLException e)
{
throw new DBException("Failed to query for Map by [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]", e);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForMap(java.lang.String, java.util.Map)
*/
public Map<String, Object> queryForMap(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForMap(namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForObject(java.lang.String)
*/
public Object queryForObject(String sql)
{
return queryForObject(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForObject(java.lang.String, java.lang.Object[])
*/
public Object queryForObject(String sql, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
try
{
return QUERY_RUNNER.query(conn, sql, SCALAR_HANDLER, paramValues);
}
catch (SQLException e)
{
throw new DBException("Failed to query for Object by [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]", e);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForObject(java.lang.String, java.util.Map)
*/
public Object queryForObject(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForObject(namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForList(java.lang.Class, java.lang.String)
*/
public <T> List<T> queryForList(Class<T> beanClass, String sql)
{
return queryForList(beanClass, sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForList(java.lang.Class, java.lang.String, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T> List<T> queryForList(Class<T> beanClass, String sql, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
try
{
return (List<T>) QUERY_RUNNER
.query(conn, sql, isPrimitiveClass(beanClass) ? ("java.lang.String".equals(beanClass.getName()) ? STRINGLIST_HANDLER
: COLUMNLIST_HANDLER) : new BeanListHandler<T>(beanClass), paramValues);
}
catch (SQLException e)
{
throw new DBException(
"Failed to query for List<" + beanClass.getName() + "> by [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]", e);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForList(java.lang.Class, java.lang.String, java.util.Map)
*/
public <T> List<T> queryForList(Class<T> beanClass, String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForList(beanClass, namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForPageList(java.lang.Class, java.lang.String, int, int, java.lang.Object[])
*/
public <T> List<T> queryForPageList(Class<T> beanClass, String sql, int pageno, int pagesize, Object... paramValues)
{
// 根据方言获取完整的分页sql语句
String pagerSql = Dialect.createPageSQL(ds.getDialect(), sql, pageno, pagesize);
return queryForList(beanClass, pagerSql, paramValues);
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForPageList(java.lang.Class, java.lang.String, int, int, java.util.Map)
*/
public <T> List<T> queryForPageList(Class<T> beanClass, String namedSql, int page, int pagesize,
Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForPageList(beanClass, namedSQL.getSQL(), page, pagesize, namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForList(java.lang.String)
*/
public List<Map<String, Object>> queryForList(String sql)
{
return queryForList(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForList(java.lang.String, java.lang.Object[])
*/
public List<Map<String, Object>> queryForList(String sql, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
try
{
return (List<Map<String, Object>>) QUERY_RUNNER.query(conn, sql, new MapListHandler(), paramValues);
}
catch (SQLException e)
{
throw new DBException("Failed to query for List<Map> by [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]!", e);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForList(java.lang.String, java.util.Map)
*/
public List<Map<String, Object>> queryForList(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForList(namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForPageList(java.lang.String, int, int, java.lang.Object[])
*/
public List<Map<String, Object>> queryForPageList(String sql, int pageno, int pagesize, Object... paramValues)
{
// 获取完整的分页sql语句
String pagerSql = Dialect.createPageSQL(ds.getDialect(), sql, pageno, pagesize);
return queryForList(pagerSql, paramValues);
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryForPageList(java.lang.String, int, int, java.util.Map)
*/
@Override
public List<Map<String, Object>> queryForPageList(String namedSql, int page, int pagesize,
Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return queryForPageList(namedSQL.getSQL(), page, pagesize, namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#execute(java.lang.String)
*/
public boolean execute(String sql)
{
return execute(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#execute(java.lang.String, java.lang.Object[])
*/
public boolean execute(String sql, Object... paramValues)
{
Connection conn = getConnection();
try
{
return execute(conn, sql, paramValues);
}
finally
{
close(conn);
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#execute(java.lang.String, java.util.Map)
*/
public boolean execute(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return execute(namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#execute(java.sql.Connection, java.lang.String, java.lang.Object[])
*/
public boolean execute(Connection conn, String sql, Object... paramValues)
{
printSQL(sql, paramValues);
try
{
QUERY_RUNNER.update(conn, sql, paramValues);
return true;
}
catch (SQLException e)
{
logger.error("Failed to execute [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]!", e);
// 如果处于事务管理,则抛出异常,用于捕获
if (ConnectionPool.isInTransaction())
{
throw new DBException("Failed to execute [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]!", e);
}
return false;
}
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#execute(java.sql.Connection, java.lang.String, java.util.Map)
*/
public boolean execute(Connection conn, String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return execute(conn, namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#save(java.lang.Object)
*/
public boolean save(Object bean)
{
Object[] bean_sql = PersistenceUtil.createInsertSQL(bean);
if (bean_sql == null || bean_sql.length == 0)
{
return false;
}
return execute(bean_sql[0].toString(), (Object[]) bean_sql[1]);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#update(java.lang.Object)
*/
public boolean update(Object bean)
{
return update(bean, null);
/*Object[] bean_sql = PersistenceUtil.createUpdateSQL(bean);
if (bean_sql == null || bean_sql.length == 0)
{
return false;
}
return execute(bean_sql[0].toString(), (Object[]) bean_sql[1]);*/
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#update(java.lang.Object, java.lang.String[])
*/
public boolean update(Object bean, String[] updatedFields)
{
Object[] bean_sql = PersistenceUtil.createUpdateSQL(bean, updatedFields);
if (bean_sql == null || bean_sql.length == 0)
{
return false;
}
return execute(bean_sql[0].toString(), (Object[]) bean_sql[1]);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#saveForGeneratedKey(java.lang.String)
*/
public long saveForGeneratedKey(String sql)
{
return saveForGeneratedKey(sql, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#saveForGeneratedKey(java.lang.String, java.lang.Object[])
*/
public long saveForGeneratedKey(String sql, Object... paramValues)
{
printSQL(sql, paramValues);
Connection conn = getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
long keyValue = -1;
try
{
pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
if (paramValues != null && paramValues.length > 0)
{
QUERY_RUNNER.fillStatement(pstmt, paramValues);
}
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if (rs.next())
{
keyValue = rs.getLong(1);
}
}
catch (SQLException e)
{
throw new DBException("Failed to save for generated key by [ " + JdbcUtil.fillSQL(sql, paramValues) + " ]!", e);
}
finally
{
close(rs);
close(pstmt);
close(conn);
}
return keyValue;
}
/* (non-Javadoc)
* @see com.lizard.fastdb.jdbc.JdbcHandler#saveForGeneratedKey(java.lang.String, java.util.Map)
*/
public long saveForGeneratedKey(String namedSql, Map<String, Object> paramValues)
{
printNamedSQL(namedSql, paramValues);
NamedSQL namedSQL = NamedSQL.parse(namedSql);
return saveForGeneratedKey(namedSQL.getSQL(), namedSQL.parseParameterValue(paramValues));
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedure(java.lang.String)
*/
public boolean callProcedure(String procedureName)
{
return callProcedure(procedureName, new Object[]{});
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedure(java.lang.String, java.lang.Object[])
*/
public boolean callProcedure(String procedureName, Object... paramValues)
{
boolean result = false;
// 存储过程的connection不归入事务管理,此处直接冲连接池获得连接
Connection conn = ConnectionPool.getIndependConnection(this.ds.getName());
CallableStatement cstmt = null;
try
{
// 语法:{ call procedure_name[(?, ?, ...)] }
// 组织调用参数
String sql = JdbcUtil.joinCallSQL(procedureName, null, paramValues);
printSQL(sql, paramValues);
// 调用存储过程
cstmt = conn.prepareCall(sql);
// 设置参数
if (paramValues != null && paramValues.length > 0)
{
for (int i = 0; i < paramValues.length; i++)
{
cstmt.setObject(i + 1, paramValues[i]);
}
}
// 执行存储过程
cstmt.execute();
sql = null;
result = true;
}
catch (SQLException e)
{
logger.error("Failed to call procedure[" + procedureName + "]"
+ (paramValues != null ? (" by params [" + Arrays.deepToString(paramValues) + "]") : ""), e);
// 如果出于事务处理,则抛出异常用于捕获
if (ConnectionPool.isInTransaction())
{
throw new DBException("Failed to call procedure[" + procedureName + "]"
+ (paramValues != null ? (" by params [" + Arrays.deepToString(paramValues) + "]") : ""), e);
}
}
finally
{
close(cstmt);
// 存储过程关闭Connection不归入事务管理,直接调用连接池关闭
ConnectionPool.closeIndependConnection(this.ds.getName(), conn);
}
return result;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String)
*/
public String callProcedureForResult(String procedureName)
{
return callProcedureForResult(procedureName, (Object[]) null);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String, java.lang.Object[])
*/
public String callProcedureForResult(String procedureName, Object... paramValues)
{
return (String) callProcedureForResult(procedureName, Types.VARCHAR, paramValues);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String, int)
*/
public Object callProcedureForResult(String procedureName, int sqlType)
{
return callProcedureForResult(procedureName, sqlType, (Object[]) null);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String, int, java.lang.Object[])
*/
public Object callProcedureForResult(String procedureName, int sqlType, Object... paramValues)
{
return callProcedureForResult(procedureName, new int[]{ sqlType }, paramValues).get(0);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String, int, int, java.lang.Object[])
*/
public Object callProcedureForResult(String procedureName, int sqlType, int sqlTypeIndex, Object... paramValues)
{
return callProcedureForResult(procedureName, new int[]{ sqlType }, new int[]{ sqlTypeIndex }, paramValues).get(0);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String, int[], java.lang.Object[])
*/
public List<Object> callProcedureForResult(String procedureName, int[] sqlTypes, Object... paramValues)
{
int[] sql_index = new int[sqlTypes.length];
for (int i = 0; i < sql_index.length; i++)
{
sql_index[i] = i;
}
return callProcedureForResult(procedureName, sqlTypes, sql_index, paramValues);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#callProcedureForResult(java.lang.String, int[], int[], java.lang.Object[])
*/
public List<Object> callProcedureForResult(String procedureName, int[] sqlTypes, int[] sqlTypesIndex, Object... paramValues)
{
// 存储过程的connection不归入事务管理,此处直接从连接池获得连接
Connection conn = ConnectionPool.getIndependConnection(this.ds.getName());
if (conn == null)
{
throw new DBException("Get connection fail!");
}
// sqlTypes 与 sqlTypesIndex 不一致
if ((sqlTypes != null && sqlTypesIndex == null) || (sqlTypes == null && sqlTypesIndex != null)
|| (sqlTypes != null && sqlTypesIndex != null && sqlTypes.length != sqlTypesIndex.length))
{
throw new DBException("[sqlTypes] and [sqlTypesIndex] is not corresponding!");
}
List<Object> list = new ArrayList<Object>();
CallableStatement cstmt = null;
try
{
// 组织调用语句
String sql = JdbcUtil.joinCallSQL(procedureName, sqlTypes == null ? new int[]{} : sqlTypes, paramValues);
cstmt = conn.prepareCall(sql);
// 参数个数
int paramCount = (sqlTypes == null ? 0 : sqlTypes.length) + (paramValues == null ? 0 : paramValues.length);
// 最终参数集
Object[] final_params = new Object[paramCount];
Set<Integer> i_set = new HashSet<Integer>();
// 设置out参数在所有参数的位置
if (sqlTypes != null && sqlTypesIndex != null)
{
for (int i = 0; i < sqlTypesIndex.length; i++)
{
i_set.add(sqlTypesIndex[i]);
final_params[sqlTypesIndex[i]] = sqlTypes[i];
}
}
// 设置in参数在所有参数的位置
if (paramValues != null)
{
int p_i = 0;
for (int i = 0; i < paramCount; i++)
{
if (final_params[i] == null)
{
final_params[i] = paramValues[p_i++];
}
}
}
printSQL(sql, final_params);
if ((sqlTypes != null && sqlTypesIndex != null) || paramValues != null)
{
for (int i = 0; i < final_params.length; i++)
{
// 注册out参数
if (i_set.contains(i))
{
cstmt.registerOutParameter(i + 1, (Integer) final_params[i]);
}
// 设置 in 参数
else
{
cstmt.setObject(i + 1, final_params[i]);
}
}
}
cstmt.execute();
if (sqlTypes != null && sqlTypesIndex != null)
{
for (int i = 0; i < sqlTypes.length; i++)
{
list.add(cstmt.getObject(sqlTypesIndex[i] + 1));
}
}
else
{
list.add(cstmt.getObject(1));
}
sql = null;
}
catch (SQLException e)
{
logger.error("Failed to call procedure [ " + procedureName + " ]");
throw new DBException("Failed to call procedure [ " + procedureName + " ]", e);
}
finally
{
close(cstmt);
// 存储过程关闭Connection不归入事务管理,直接调用连接池关闭
ConnectionPool.closeIndependConnection(this.ds.getName(), conn);
}
return list;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#batchUpdate(java.lang.String[])
*/
public BatchUpdateResult batchUpdate(String[] sqls)
{
return batchUpdate(sqls, false);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#batchUpdate(java.lang.String[], boolean)
*/
@SuppressWarnings("resource")
public BatchUpdateResult batchUpdate(String[] sqls, boolean rollback)
{
if (sqls == null || sqls.length <= 0)
{
throw new DBException("BatchUpdate sql array can not be empty!");
// return new BatchUpdateResult(true, new int[0], new int[0]);
}
Connection conn = getConnection();
if (conn == null)
{
throw new DBException("Get connection fail!");
// return new BatchUpdateResult(false, new int[0], new int[0]);
}
Statement stmt = null;
// 将所有SQL语句分为 totalBatchs 批执行,如果设置了回滚或设置了每批的大小,则分批提交
int totalBatchs = getTotalBatchs(sqls.length);
// 最终的执行结果是否成功,只有当所有批都执行没有任何错误时,才为ture
boolean _success = true;
// 执行失败的批编号
List<Integer> errorBatchList = new ArrayList<Integer>();
// 当前批执行成功的每条SQL语句的影响计数
int[] urows = null;
// 存储分批操作中的executeBatch 执行影响的计数,便于最后计算全局的计数数组
List<Integer> rowList = new ArrayList<Integer>();
// 当前线程 batchSize 值
int batchSize = BATCH_SIZE_LOCAL.get();
// 如果当前操作在事务管理器中,则将回滚置为true,便于出错后事务处理器进行统一回滚操作
// SHEN.GANG 于 2014-08-12 增加
if (ConnectionPool.isInTransaction())
{
rollback = true;
}
try
{
// 如果需要回滚 或者 需要分批批量操作
if (rollback || totalBatchs > 0)
{
conn.setAutoCommit(false);
}
stmt = conn.createStatement();
// 已经执行的批数计数
int run_batch = 0;
for (int i = 0; i < sqls.length; i++)
{
if (sqls[i] != null && sqls[i].trim().length() > 0)
{
printSQL(sqls[i], null);
stmt.addBatch(sqls[i]);
}
// 到达一个批次,则提交
if (totalBatchs > 0 && (i + 1) % batchSize == 0)
{
try
{
urows = stmt.executeBatch();
// 如果当前操作没有包含在事务管理器中,则按批次提交,否则,由事务管理器统一提交
if (!ConnectionPool.isInTransaction())
{
conn.commit();
}
}
catch (SQLException e)
{
// 该批次回滚
if (rollback)
{
// 如果当前操作没有包含在事务管理器中,则按批次回滚,否则,由事务管理器统一回滚
if (!ConnectionPool.isInTransaction())
{
conn.rollback();
}
// 如果当前 batchUpdate 处在事务管理器中,则抛出异常让事务管理器捕获,由事务管理器负责统一回滚
// SHEN.GANG 于 2014-07-12 增加
else
{
logger.error("Failed to execute the batchUpdate sqls, [totalBatchs = " + totalBatchs + ", batchSize = "
+ batchSize + ", index = " + i + "]!", e);
throw e;
}
}
// 记录失败
_success = false;
urows = ((BatchUpdateException) e).getUpdateCounts();
// 记录执行失败的批
errorBatchList.add(run_batch + 1);
}
// 记录执行命令的计数
addBatchRows(urows, rowList);
run_batch++;
}
// 循环到最后,如果未分批或最后的一批SQL还为执行
else if (i == sqls.length - 1 && (totalBatchs <= 0 || run_batch < totalBatchs))
{
try
{
// 提交未到达批次的操作(或者未分批的所有操作)
urows = stmt.executeBatch();
// 需要回滚 或者 执行分批操作
if (rollback || totalBatchs > 0)
{
// 如果当前操作没有包含在事务管理器中,则按批次提交,否则,由事务管理器统一提交
if (!ConnectionPool.isInTransaction())
{
conn.commit();
}
}
}
catch (SQLException e)
{
// 该批次回滚
if (rollback)
{
// 如果当前操作没有包含在事务管理器中,则按批次回滚,否则,由事务管理器统一回滚
if (!ConnectionPool.isInTransaction())
{
conn.rollback();
}
// 如果当前 batchUpdate 处在事务管理器中,则抛出异常让事务管理器捕获,由事务管理器负责统一回滚
// SHEN.GANG 于 2014-07-12 增加
else
{
logger.error("Failed to execute the batchUpdate sqls, [totalBatchs = " + totalBatchs + ", batchSize = "
+ batchSize + ", index = " + i + "]!", e);
throw e;
}
}
// 记录失败
_success = false;
urows = ((BatchUpdateException) e).getUpdateCounts();
// 记录失败的批次
errorBatchList.add(run_batch + 1);
}
// 记录执行命令的计数
addBatchRows(urows, rowList);
run_batch++;
}
}
// 返回最终的计数数组
int[] _rows = new int[rowList.size()];
for (int j = 0; j < rowList.size(); j++)
{
_rows[j] = rowList.get(j);
}
return initBatchUpdateResult(_success, _rows, errorBatchList);
}
catch (Exception e)
{
logger.error("Failed to execute the batchUpdate sqls " + Arrays.deepToString(sqls) + "!", e);
throw new DBException("Failed to execute the batchUpdate sqls " + Arrays.deepToString(sqls) + "!", e);
}
finally
{
close(stmt);
close(conn);
}
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#batchUpdate(java.lang.String, java.lang.Object[][])
*/
public BatchUpdateResult batchUpdate(String sql, Object[][] paramValues)
{
return batchUpdate(sql, paramValues, false);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#batchUpdate(java.lang.String, java.lang.Object[][], boolean)
*/
public BatchUpdateResult batchUpdate(String sql, Object[][] paramValues, boolean rollback)
{
Connection conn = getConnection();
if (conn == null)
{
throw new DBException("Get connection fail!");
}
PreparedStatement pstmt = null;
if (StringUtils.isEmptyString(sql))
{
throw new DBException("BatchUpdate sql can not be empty!");
}
if (paramValues == null)
{
throw new DBException("BatchUpdate paramValues[][] can not be null!");
}
// 当前线程 batchSize 的值
int batchSize = BATCH_SIZE_LOCAL.get();
// 分批次数
int totalBatchs = getTotalBatchs(paramValues.length);
// 已经执行的批次
int run_batch = 0;
// 每次 executeBatch 执行是否成功,只有当全部成功时,才算是成功
boolean _success = true;
// 执行失败的批次
List<Integer> errorBatchList = new ArrayList<Integer>();
// executeBatch 执行影响的计数
int[] urows = null;
// 存储分批操作中的executeBatch 执行影响的计数,便于最后计算全局的计数数组
List<Integer> rowList = new ArrayList<Integer>();
// 如果当前操作在事务管理器中,则默认将回滚置为true,便于事务处理器进行统一回滚操作
// SHEN.GANG 于 2014-07-12 增加
if (ConnectionPool.isInTransaction())
{
rollback = true;
}
try
{
// 需要回滚 或者 分批次操作
if (rollback || totalBatchs > 0)
{
conn.setAutoCommit(false);
}
pstmt = conn.prepareStatement(sql);
if (paramValues != null && paramValues.length > 0)
{
for (int i = 0; i < paramValues.length; i++)
{
// 为预编译SQL语句赋值
Object[] param = paramValues[i];
if (param != null && param.length > 0)
{
printSQL(sql, param);
QUERY_RUNNER.fillStatement(pstmt, param);
}
pstmt.addBatch();
// 分批次提交
if (totalBatchs > 0 && (i + 1) % batchSize == 0)
{
try
{
urows = pstmt.executeBatch();
// 如果当前操作没有包含在事务管理器中,则按批次提交,否则,由事务管理器统一提交
if (!ConnectionPool.isInTransaction())
{
conn.commit();
}
}
catch (SQLException e)
{
// 该批次回滚
if (rollback)
{
// 如果当前操作没有包含在事务管理器中,则按批次回滚,否则,由事务管理器统一回滚
if (!ConnectionPool.isInTransaction())
{
conn.rollback();
}
// 如果当前 batchUpdate 处在事务管理器中,则抛出异常让事务管理器捕获,由事务管理器负责统一回滚
// SHEN.GANG 于 2014-07-12 增加
else
{
logger.error("Failed to execute the batchUpdate sql, [totalBatchs = " + totalBatchs + ", batchSize = "
+ batchSize + ", index = " + i + "]!", e);
throw new BatchUpdateException(e);
}
}
// 记录失败
_success = false;
urows = ((BatchUpdateException) e).getUpdateCounts();
// 记录执行失败的批次
errorBatchList.add(run_batch + 1);
}
// 记录执行命令的计数
addBatchRows(urows, rowList);
run_batch++;
}
else if (i == paramValues.length - 1 && (totalBatchs <= 0 || run_batch < totalBatchs))
{
try
{
// 提交未到达批次的操作(或者未分批的所有操作)
urows = pstmt.executeBatch();
// 需要回滚 或者 执行分批操作
if (rollback || totalBatchs > 0)
{
// 如果当前操作没有包含在事务管理器中,则按批次提交,否则,由事务管理器统一提交
if (!ConnectionPool.isInTransaction())
{
conn.commit();
}
}
}
catch (SQLException e)
{
// 该批次回滚
if (rollback)
{
// 如果当前操作没有包含在事务管理器中,则按批次回滚,否则,由事务管理器统一回滚
if (!ConnectionPool.isInTransaction())
{
conn.rollback();
}
// 如果当前 batchUpdate 处在事务管理器中,则抛出异常让事务管理器捕获,由事务管理器负责统一回滚
// SHEN.GANG 于 2014-07-12 增加
else
{
logger.error("Failed to execute the batchUpdate sql, [totalBatchs = " + totalBatchs + ", batchSize = "
+ batchSize + ", index = " + i + "]!", e);
throw new BatchUpdateException(e);
}
}
// 记录失败
_success = false;
urows = ((BatchUpdateException) e).getUpdateCounts();
// 记录失败的批次
errorBatchList.add(run_batch + 1);
}
// 记录执行命令的计数
addBatchRows(urows, rowList);
}
}
}
// 返回最终的计数数组
int[] _rows = new int[rowList.size()];
for (int j = 0; j < rowList.size(); j++)
{
_rows[j] = rowList.get(j);
}
return initBatchUpdateResult(_success, _rows, errorBatchList);
}
catch (Exception e)
{
logger.error("Can't execute the batchUpdate SQL[" + sql + "] by params" + Arrays.deepToString((Object[]) paramValues), e);
throw new DBException("Can't execute the batchUpdate SQL[" + sql + "] by params" + Arrays.deepToString((Object[]) paramValues),
e);
}
finally
{
close(pstmt);
close(conn);
}
}
/**
* 计算总分批次数
*
* @param totals 数据总数
* @return 总分批次数
*/
private int getTotalBatchs(int totals)
{
int batchSize = BATCH_SIZE_LOCAL.get();
if (batchSize <= 0 || totals <= 0)
{
return 0;
}
else
{
return totals % batchSize == 0 ? totals / batchSize : totals / batchSize + 1;
}
}
/**
* 统计批量操作成功执行命令的计数
*
* @param rows
* @param rowList
*/
private void addBatchRows(int[] rows, List<Integer> rowList)
{
if (rows != null && rows.length > 0)
{
for (int i = 0; i < rows.length; i++)
{
rowList.add(rows[i]);
}
}
}
/**
* 根据执行结果初始化BatchUpdateResult对象
*
* @param success 是否全部执行成功
* @param rows 执行结果
* @param errorBatchList 错误批次列表
* @return 批量更新结果BatchUpdateResult
*/
private BatchUpdateResult initBatchUpdateResult(boolean success, int[] rows, List<Integer> errorBatchList)
{
// 批量更新返回的结果信息
BatchUpdateResult bur = new BatchUpdateResult();
// 设置批量处理最终的处理结果
bur.setSuccess(success);
bur.setBatchRows(rows);
// 保存执行失败的批次
if (errorBatchList.size() > 0)
{
int[] errorBatchs = new int[errorBatchList.size()];
for (int t = 0; t < errorBatchList.size(); t++)
{
errorBatchs[t] = errorBatchList.get(t);
}
bur.setErrorBatchs(errorBatchs);
}
return bur;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#setBatchSize(int)
*/
public void setBatchSize(int batchSize)
{
if (batchSize < 0)
{
throw new IllegalArgumentException("The batchSize must be greater than or equal to 0!");
}
BATCH_SIZE_LOCAL.set(batchSize);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#isTableExist(java.lang.String)
*/
public boolean isTableExist(String tableName)
{
// 表名为空
if (StringUtils.isEmptyString(tableName))
{
return false;
}
String sql = null;
Object[] params = null;
if (Dialect.MYSQL.equals(this.ds.getDialect()))// MySQL
{
sql = "SELECT count(1) FROM information_schema.tables WHERE table_name = ? AND table_schema = ?";
params = new Object[]{ tableName.toLowerCase(), JdbcUtil.getMySQLSchema(this.ds.getDriverUrl()) };
}
else
// Oracle
{
sql = "SELECT count(1) FROM sys.user_tables WHERE table_name = ?";
params = new Object[]{ tableName.toUpperCase() };
}
return queryForLong(sql, params) > 0;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#queryTableFields(java.lang.String)
*/
public List<String> queryTableFields(String tableName)
{
if (StringUtils.isEmptyString(tableName))
{
throw new IllegalArgumentException("TableName cannot be empty!");
}
String sql = null;
Object[] params = null;
// MySQL 数据库
if (Dialect.MYSQL.equals(this.ds.getDialect()))
{
sql = "SELECT column_name FROM information_schema.columns WHERE table_name = ? AND table_schema = ?";
params = new Object[]{ tableName.toLowerCase(), JdbcUtil.getMySQLSchema(this.ds.getDriverUrl()) };
}
// Oracle 数据库
else
{
sql = "SELECT column_name FROM sys.all_tab_columns WHERE table_name = ? AND owner = ?";
params = new Object[]{ tableName.toUpperCase(), ds.getUser().toUpperCase() };
}
return queryForList(String.class, sql, params);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#isSequenceExist(java.lang.String)
*/
public boolean isSequenceExist(String sequenceName)
{
if (StringUtils.isEmptyString(sequenceName))
{
return false;
}
String sql = "SELECT count(1) FROM sys.all_sequences WHERE sequence_name = ?";
return queryForInteger(sql, sequenceName) > 0;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#isIndexExist(java.lang.String, java.lang.String)
*/
public boolean isIndexExist(String tableName, String indexName)
{
if (StringUtils.isEmptyString(tableName) || StringUtils.isEmptyString(indexName))
{
return false;
}
String sql = null;
if (Dialect.MYSQL.equals(this.ds.getDialect()))
{
sql = "SELECT count(1) FROM information_schema.statistics WHERE TABLE_NAME = ? and INDEX_NAME = ? and TABLE_SCHEMA = '"
+ JdbcUtil.getMySQLSchema(this.ds.getDriverUrl()) + "'";
}
else
{
sql = "SELECT count(1) FROM sys.user_indexes WHERE TABLE_NAME = ? and INDEX_NAME = ?";
}
return queryForInteger(sql, tableName, indexName) > 0;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#isFunctionExist(java.lang.String)
*/
public boolean isFunctionExist(String functionName)
{
if (StringUtils.isEmptyString(functionName))
{
return false;
}
String sql = "SELECT count(1) FROM sys.user_objects WHERE object_type = 'FUNCTION' AND object_name = ?";
return queryForInteger(sql, functionName.toUpperCase()) > 0;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#isProcedureExist(java.lang.String)
*/
public boolean isProcedureExist(String procedureName)
{
if (StringUtils.isEmptyString(procedureName))
{
return false;
}
String sql = "SELECT count(1) FROM sys.user_objects WHERE object_type = 'PROCEDURE' AND object_name = ?";
return queryForInteger(sql, procedureName.toUpperCase()) > 0;
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#isConnectionReachable()
*/
public boolean isConnectionReachable()
{
Connection conn = null;
try
{
Class.forName(ds.getDriverClass());
conn = DriverManager.getConnection(ds.getDriverUrl(), ds.getUser(), ds.getPassword());
return true;
}
catch (ClassNotFoundException e)
{
logger.error("Can not found Connection Driver Class ["+ ds.getDriverClass() +"].", e);
return false;
}
catch (SQLException e)
{
logger.error("Can not get the Connection by["+ ds.getDriverUrl() +":"+ ds.getUser()+":"+ds.getPassword() +"].", e);
return false;
}
finally
{
if (conn != null)
{
try
{
conn.close();
}
catch (SQLException e)
{
logger.error("Failed to close the connection in isConnectionReachable().", e);
}
}
}
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#getDataSource()
*/
public DataSource getDataSource()
{
return DataSourceUtil.convertDataSourceToReadable(ds);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#getConnection()
*/
public Connection getConnection()
{
return ConnectionPool.getConnection(this.ds.getName());
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#closeConnection(java.sql.Connection)
*/
public void close(Connection conn)
{
ConnectionPool.closeConnection(this.ds.getName(), conn);
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#close(java.sql.Statement)
*/
public void close(Statement stmt)
{
try
{
if (stmt != null)
{
stmt.close();
stmt = null;
}
}
catch (SQLException e)
{
logger.error("Close the Statement failed!", e);
throw new DBException("Close the Statement failed!", e);
}
}
/*
* (non-Javadoc)
*
* @see com.lizard.fastdb.jdbc.JdbcHandler#close(java.sql.ResultSet)
*/
public void close(ResultSet rs)
{
try
{
if (rs != null)
{
rs.close();
rs = null;
}
}
catch (SQLException e)
{
logger.error("Close the ResultSet failed!", e);
throw new DBException("Close the ResultSet failed!", e);
}
}
/**
* 打印SQL
*
* @param sql SQL语句
* @param paramValues SQL语句参数
*/
private void printSQL(String sql, Object[] paramValues)
{
if (Boolean.valueOf(this.ds.getShowSQL()))
{
JdbcUtil.printSQL(sql, paramValues);
}
}
/**
* 打印命名参数SQL语句
*
* @param namedSql
* @param paramValues
*/
private void printNamedSQL( String namedSql, Map<String, Object> paramValues )
{
if (Boolean.valueOf(this.ds.getShowSQL()))
{
JdbcUtil.printNamedSQL(namedSql, paramValues);
}
}
}