com.xiaoleilu.hutool.db.DbUtil Maven / Gradle / Ivy
package com.xiaoleilu.hutool.db;
import java.io.Closeable;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import com.xiaoleilu.hutool.convert.Convert;
import com.xiaoleilu.hutool.db.dialect.Dialect;
import com.xiaoleilu.hutool.db.dialect.DialectFactory;
import com.xiaoleilu.hutool.db.ds.DSFactory;
import com.xiaoleilu.hutool.db.meta.Column;
import com.xiaoleilu.hutool.db.meta.Table;
import com.xiaoleilu.hutool.db.meta.TableType;
import com.xiaoleilu.hutool.db.sql.Condition;
import com.xiaoleilu.hutool.db.sql.Condition.LikeType;
import com.xiaoleilu.hutool.db.sql.SqlBuilder;
import com.xiaoleilu.hutool.db.sql.SqlFormatter;
import com.xiaoleilu.hutool.io.IoUtil;
import com.xiaoleilu.hutool.lang.Assert;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;
import com.xiaoleilu.hutool.util.ArrayUtil;
import com.xiaoleilu.hutool.util.CharsetUtil;
import com.xiaoleilu.hutool.util.StrUtil;
/**
* 数据库操作工具类
*
* @author Luxiaolei
*
*/
public final class DbUtil {
private final static Log log = LogFactory.get();
/**
* 实例化一个新的SQL运行对象
*
* @param dialect 数据源
* @return SQL执行类
*/
public static SqlConnRunner newSqlConnRunner(Dialect dialect) {
return SqlConnRunner.create(dialect);
}
/**
* 实例化一个新的SQL运行对象
*
* @param ds 数据源
* @return SQL执行类
*/
public static SqlConnRunner newSqlConnRunner(DataSource ds) {
return SqlConnRunner.create(ds);
}
/**
* 实例化一个新的SQL运行对象
*
* @param conn 数据库连接对象
* @return SQL执行类
*/
public static SqlConnRunner newSqlConnRunner(Connection conn) {
return SqlConnRunner.create(DialectFactory.newDialect(conn));
}
/**
* 实例化一个新的SQL运行对象,使用默认数据源
*
* @return SQL执行类
*/
public static SqlRunner newSqlRunner() {
return SqlRunner.create(getDs());
}
/**
* 实例化一个新的SQL运行对象
*
* @param ds 数据源
* @return SQL执行类
*/
public static SqlRunner newSqlRunner(DataSource ds) {
return SqlRunner.create(ds);
}
/**
* 实例化一个新的SQL运行对象
*
* @param ds 数据源
* @param dialect SQL方言
* @return SQL执行类
*/
public static SqlRunner newSqlRunner(DataSource ds, Dialect dialect) {
return SqlRunner.create(ds, dialect);
}
/**
* 新建数据库会话,使用默认数据源
*
* @return 数据库会话
*/
public static Session newSession() {
return Session.create(getDs());
}
/**
* 新建数据库会话
*
* @param ds 数据源
* @return 数据库会话
*/
public static Session newSession(DataSource ds) {
return Session.create(ds);
}
/**
* 新建数据库会话
*
* @param conn 数据库连接对象
* @return 数据库会话
*/
public static Session newSession(Connection conn) {
return Session.create(conn);
}
/**
* 连续关闭一系列的SQL相关对象
* 这些对象必须按照顺序关闭,否则会出错。
*
* @param objsToClose 需要关闭的对象
*/
public static void close(Object... objsToClose) {
for (Object obj : objsToClose) {
if (obj instanceof AutoCloseable) {
IoUtil.close((AutoCloseable) obj);
} else if (obj instanceof Closeable) {
IoUtil.close((Closeable) obj);
} else {
try {
if (obj != null) {
if (obj instanceof ResultSet) {
((ResultSet) obj).close();
} else if (obj instanceof Statement) {
((Statement) obj).close();
} else if (obj instanceof PreparedStatement) {
((PreparedStatement) obj).close();
} else if (obj instanceof Connection) {
((Connection) obj).close();
} else {
log.warn("Object {} not a ResultSet or Statement or PreparedStatement or Connection!", obj.getClass().getName());
}
}
} catch (SQLException e) {
// ignore
}
}
}
}
/**
* 获得默认数据源
*
* @return 默认数据源
*/
public static DataSource getDs() {
return DSFactory.get();
}
/**
* 获取指定分组的数据源
*
* @param group 分组
* @return 数据源
*/
public static DataSource getDs(String group) {
return DSFactory.get(group);
}
/**
* 获得JNDI数据源
*
* @param jndiName JNDI名称
* @return 数据源
*/
public static DataSource getJndiDsWithLog(String jndiName) {
try {
return getJndiDs(jndiName);
} catch (DbRuntimeException e) {
log.error(e.getCause(), "Find JNDI datasource error!");
}
return null;
}
/**
* 获得JNDI数据源
*
* @param jndiName JNDI名称
* @return 数据源
*/
public static DataSource getJndiDs(String jndiName) {
try {
return (DataSource) new InitialContext().lookup(jndiName);
} catch (NamingException e) {
throw new DbRuntimeException(e);
}
}
/**
* 获得所有表名
*
* @param ds 数据源
* @return 表名列表
*/
public static List getTables(DataSource ds) {
return getTables(ds, TableType.TABLE);
}
/**
* 获得所有表名
*
* @param ds 数据源
* @param types 表类型
* @return 表名列表
*/
public static List getTables(DataSource ds, TableType... types) {
return getTables(ds, null, null, types);
}
/**
* 获得所有表名
*
* @param ds 数据源
* @param schema 表数据库名,对于Oracle为用户名
* @param types 表类型
* @return 表名列表
* @since 3.3.1
*/
public static List getTables(DataSource ds, String schema, TableType... types) {
return getTables(ds, schema, null, types);
}
/**
* 获得所有表名
*
* @param ds 数据源
* @param schema 表数据库名,对于Oracle为用户名
* @param tableName 表名
* @param types 表类型
* @return 表名列表
* @since 3.3.1
*/
public static List getTables(DataSource ds, String schema, String tableName, TableType... types) {
final List tables = new ArrayList();
Connection conn = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
final DatabaseMetaData metaData = conn.getMetaData();
rs = metaData.getTables(conn.getCatalog(), schema, tableName, Convert.toStrArray(types));
if (rs == null) {
return null;
}
String table;
while (rs.next()) {
table = rs.getString("TABLE_NAME");
if (StrUtil.isNotBlank(table)) {
tables.add(table);
}
}
} catch (Exception e) {
throw new DbRuntimeException("Get tables error!", e);
} finally {
close(rs, conn);
}
return tables;
}
/**
* 获得结果集的所有列名
*
* @param rs 结果集
* @return 列名数组
* @throws DbRuntimeException SQL执行异常
*/
public static String[] getColumnNames(ResultSet rs) throws DbRuntimeException {
try {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
String[] labelNames = new String[columnCount];
for (int i = 0; i < labelNames.length; i++) {
labelNames[i] = rsmd.getColumnLabel(i + 1);
}
return labelNames;
} catch (Exception e) {
throw new DbRuntimeException("Get colunms error!", e);
}
}
/**
* 获得表的所有列名
*
* @param ds 数据源
* @param tableName 表名
* @return 列数组
* @throws DbRuntimeException SQL执行异常
*/
public static String[] getColumnNames(DataSource ds, String tableName) {
List columnNames = new ArrayList();
Connection conn = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
final DatabaseMetaData metaData = conn.getMetaData();
rs = metaData.getColumns(conn.getCatalog(), null, tableName, null);
while (rs.next()) {
columnNames.add(rs.getString("COLUMN_NAME"));
}
return columnNames.toArray(new String[columnNames.size()]);
} catch (Exception e) {
throw new DbRuntimeException("Get columns error!", e);
} finally {
close(rs, conn);
}
}
/**
* 创建带有字段限制的Entity对象
* 此方法读取数据库中对应表的字段列表,加入到Entity中,当Entity被设置内容时,会忽略对应表字段外的所有KEY
*
* @param ds 数据源
* @param tableName 表名
* @return Entity对象
*/
public static Entity createLimitedEntity(DataSource ds, String tableName) {
String[] columnNames = getColumnNames(ds, tableName);
return Entity.create(tableName).setFieldNames(columnNames);
}
/**
* 获得表的元信息
*
* @param ds 数据源
* @param tableName 表名
* @return Table对象
*/
@SuppressWarnings("resource")
public static Table getTableMeta(DataSource ds, String tableName) {
final Table table = Table.create(tableName);
Connection conn = null;
ResultSet rs = null;
try {
conn = ds.getConnection();
final DatabaseMetaData metaData = conn.getMetaData();
// 获得主键
rs = metaData.getPrimaryKeys(conn.getCatalog(), null, tableName);
while (rs.next()) {
table.addPk(rs.getString("COLUMN_NAME"));
}
// 获得列
rs = metaData.getColumns(conn.getCatalog(), null, tableName, null);
while (rs.next()) {
table.setColumn(Column.create(tableName, rs));
}
} catch (SQLException e) {
throw new DbRuntimeException("Get columns error!", e);
} finally {
close(rs, conn);
}
return table;
}
/**
* 填充SQL的参数。
*
* @param ps PreparedStatement
* @param params SQL参数
* @return {@link PreparedStatement}
* @throws SQLException SQL执行异常
*/
public static PreparedStatement fillParams(PreparedStatement ps, Collection
© 2015 - 2024 Weber Informatics LLC | Privacy Policy