package org.smart4j.framework.helper;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.framework.util.ClassUtil;
import org.smart4j.framework.util.CollectionUtil;
/**
* 数据库操作助手类
*
* @author huangyong
* @since 1.0.0
*/
public final class DatabaseHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseHelper.class);
private static final ThreadLocal<Connection> CONNECTION_HOLDER;
private static final QueryRunner QUERY_RUNNER;
private static final BasicDataSource DATA_SOURCE;
static {
CONNECTION_HOLDER = new ThreadLocal<Connection>();
QUERY_RUNNER = new QueryRunner();
DATA_SOURCE = new BasicDataSource();
DATA_SOURCE.setDriverClassName(ConfigHelper.getJdbcDriver());
DATA_SOURCE.setUrl(ConfigHelper.getJdbcUrl());
DATA_SOURCE.setUsername(ConfigHelper.getJdbcUsername());
DATA_SOURCE.setPassword(ConfigHelper.getJdbcPassword());
}
/**
* 获取数据源
*/
public static DataSource getDataSource() {
return DATA_SOURCE;
}
/**
* 获取数据库连接
*/
public static Connection getConnection() {
Connection conn = CONNECTION_HOLDER.get();
if (conn == null) {
try {
conn = DATA_SOURCE.getConnection();
} catch (SQLException e) {
LOGGER.error("get connection failure", e);
throw new RuntimeException(e);
} finally {
CONNECTION_HOLDER.set(conn);
}
}
return conn;
}
/**
* 开启事务
*/
public static void beginTransaction() {
Connection conn = getConnection();
if (conn != null) {
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
LOGGER.error("begin transaction failure", e);
throw new RuntimeException(e);
} finally {
CONNECTION_HOLDER.set(conn);
}
}
}
/**
* 提交事务
*/
public static void commitTransaction() {
Connection conn = getConnection();
if (conn != null) {
try {
conn.commit();
conn.close();
} catch (SQLException e) {
LOGGER.error("commit transaction failure", e);
throw new RuntimeException(e);
} finally {
CONNECTION_HOLDER.remove();
}
}
}
/**
* 回滚事务
*/
public static void rollbackTransaction() {
Connection conn = getConnection();
if (conn != null) {
try {
conn.rollback();
conn.close();
} catch (SQLException e) {
LOGGER.error("rollback transaction failure", e);
throw new RuntimeException(e);
} finally {
CONNECTION_HOLDER.remove();
}
}
}
/**
* 查询实体
*/
public static <T> T queryEntity(Class<T> entityClass, String sql, Object... params) {
T entity;
try {
Connection conn = getConnection();
entity = QUERY_RUNNER.query(conn, sql, new BeanHandler<T>(entityClass), params);
} catch (SQLException e) {
LOGGER.error("query entity failure", e);
throw new RuntimeException(e);
}
return entity;
}
/**
* 查询实体列表
*/
public static <T> List<T> queryEntityList(Class<T> entityClass, String sql, Object... params) {
List<T> entityList;
try {
Connection conn = getConnection();
entityList = QUERY_RUNNER.query(conn, sql, new BeanListHandler<T>(entityClass), params);
} catch (SQLException e) {
LOGGER.error("query entity list failure", e);
throw new RuntimeException(e);
}
return entityList;
}
/**
* 查询并返回单个列值
*/
public static <T> T query(String sql, Object... params) {
T obj;
try {
Connection conn = getConnection();
obj = QUERY_RUNNER.query(conn, sql, new ScalarHandler<T>(), params);
} catch (SQLException e) {
LOGGER.error("query failure", e);
throw new RuntimeException(e);
}
return obj;
}
/**
* 查询并返回多个列值
*/
public static <T> List<T> queryList(String sql, Object... params) {
List<T> list;
try {
Connection conn = getConnection();
list = QUERY_RUNNER.query(conn, sql, new ColumnListHandler<T>(), params);
} catch (SQLException e) {
LOGGER.error("query list failure", e);
throw new RuntimeException(e);
}
return list;
}
/**
* 查询并返回多个列值(具有唯一性)
*/
public static <T> Set<T> querySet(String sql, Object... params) {
Collection<T> valueList = queryList(sql, params);
return new LinkedHashSet<T>(valueList);
}
/**
* 查询并返回数组
*/
public static Object[] queryArray(String sql, Object... params) {
Object[] resultArray;
try {
Connection conn = getConnection();
resultArray = QUERY_RUNNER.query(conn, sql, new ArrayHandler(), params);
} catch (SQLException e) {
LOGGER.error("query array failure", e);
throw new RuntimeException(e);
}
return resultArray;
}
/**
* 查询并返回数组列表
*/
public static List<Object[]> queryArrayList(String sql, Object... params) {
List<Object[]> resultArrayList;
try {
Connection conn = getConnection();
resultArrayList = QUERY_RUNNER.query(conn, sql, new ArrayListHandler(), params);
} catch (SQLException e) {
LOGGER.error("query array list failure", e);
throw new RuntimeException(e);
}
return resultArrayList;
}
/**
* 查询并返回结果集映射(列名 => 列值)
*/
public static Map<String, Object> queryMap(String sql, Object... params) {
Map<String, Object> resultMap;
try {
Connection conn = getConnection();
resultMap = QUERY_RUNNER.query(conn, sql, new MapHandler(), params);
} catch (SQLException e) {
LOGGER.error("query map failure", e);
throw new RuntimeException(e);
}
return resultMap;
}
/**
* 查询并返回结果集映射列表(列名 => 列值)
*/
public static List<Map<String, Object>> queryMapList(String sql, Object... params) {
List<Map<String, Object>> resultMapList;
try {
Connection conn = getConnection();
resultMapList = QUERY_RUNNER.query(conn, sql, new MapListHandler(), params);
} catch (SQLException e) {
LOGGER.error("query map list fa