package jef.database; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.PersistenceException; import jef.common.log.LogUtil; import jef.common.pool.PoolStatus; import jef.database.cache.Cache; import jef.database.innerpool.IConnection; import jef.database.innerpool.PartitionSupport; import jef.database.meta.AbstractRefField; import jef.database.meta.Feature; import jef.database.meta.Reference; import jef.database.query.Query; import jef.tools.StringUtils; /** * 用于编写一些直接操作数据库的特殊用法,以得到最好的性能 * * @author Administrator * */ public class DebugUtil { static java.lang.reflect.Field sqlState; static { try { sqlState = SQLException.class.getDeclaredField("SQLState"); if (sqlState != null) { sqlState.setAccessible(true); } } catch (Throwable t) { LogUtil.exception(t); } } public static ILazyLoadContext getLazy(DataObject o) { return o.lazyload; } public static void addLazy(DataObject o, LazyLoadProcessor lazy) { if (o.lazyload == null) { o.lazyload = new LazyLoadContext(lazy); } else { throw new IllegalStateException(); } } private DebugUtil() { } public static void bindQuery(DataObject d, Query<?> e) { d.query = e; } /** * 将指定的文本,通过反射强行赋值到SQLException类的seqState字段,用于在不重新封装SQLException的情况下, * 在SQLException中携带一些自定义的Message。 * * @param e * @param sql */ public static void setSqlState(SQLException e, String sql) { if (sqlState != null) { try { sqlState.set(e, sql); } catch (Exception e1) { LogUtil.exception(e1); } } } public static PartitionSupport getPartitionSupport(Session db) { return db.getPartitionSupport(); } public static PoolStatus getPoolStatus(DbClient db) { return db.getPool().getStatus(); } public static String getTransactionId(Session db) { return db.getTransactionId(null); } public static IConnection getConnection(SqlTemplate db) { return ((OperateTarget) db).getRawConnection(); } public static IConnection getIConnection(TransactionalSession db) throws SQLException { if(db instanceof Transaction){ return ((Transaction) db).getConnection(); }else{ throw new IllegalArgumentException(db.getClass().getName()); } } public static IConnection getPooledConnection(DbClient db) { try { return db.getPool().getConnection(Thread.currentThread()); } catch (SQLException e) { throw new PersistenceException(e.getMessage() + " " + e.getSQLState(), e); } } /** * 得到表的全部字段,小写 * * @param db * @param tableName * @return * @throws SQLException */ public static Set<String> getColumnsInLowercase(OperateTarget db, String tableName) throws SQLException { Set<String> set = new HashSet<String>(); tableName = db.getProfile().getObjectNameToUse(tableName); IConnection conn = DebugUtil.getConnection(db); try { DatabaseMetaData databaseMetaData = conn.getMetaData(); String schema = null; if (db.getProfile().has(Feature.USER_AS_SCHEMA)) { schema = StringUtils.upperCase(databaseMetaData.getUserName()); } else if (db.getProfile().has(Feature.DBNAME_AS_SCHEMA)) schema = db.getDbName(); int n = tableName.indexOf('.'); if (n > 0) {// 尝试从表名中计算schema schema = tableName.substring(0, n); tableName = tableName.substring(n + 1); } ResultSet rs = databaseMetaData.getColumns(null, schema, tableName, "%"); try { while (rs.next()) { String columnName = rs.getString("COLUMN_NAME"); set.add(columnName.toLowerCase()); } } finally { rs.close(); } return set; } finally { db.releaseConnection(); } } /** * 判断表中是否有指定的列 * * @param db * @param tableName * @param column * @return * @throws SQLException */ public static boolean hasColumn(OperateTarget db, String tableName, String column) throws SQLException { if (StringUtils.isEmpty(column)) return false; boolean has = false; tableName = db.getProfile().getObjectNameToUse(tableName); IConnection conn = DebugUtil.getConnection(db); try { DatabaseMetaData databaseMetaData = conn.getMetaData(); String schema = null; if (db.getProfile().has(Feature.USER_AS_SCHEMA)) { schema = StringUtils.upperCase(databaseMetaData.getUserName()); } else if (db.getProfile().has(Feature.DBNAME_AS_SCHEMA)) schema = db.getDbName(); int n = tableName.indexOf('.'); if (n > 0) {// 尝试从表名中计算schema schema = tableName.substring(0, n); tableName = tableName.substring(n + 1); } ResultSet rs = databaseMetaData.getColumns(null, schema, tableName, "%"); try { while (rs.next()) { String columnName = rs.getString("COLUMN_NAME"); if (column.equalsIgnoreCase(columnName)) { has = true; break; } } } finally { rs.close(); } return has; } finally { db.releaseConnection(); } } public static LazyLoadTask getLazyTaskMarker(Map.Entry<Reference, List<AbstractRefField>> entry, Map<Reference, List<Condition>> filters, Session session) { return new CascadeLoaderTask(entry, filters); } public static Cache getCache(Session session) { return session.getCache(); } }