package hjp.smart4j.framework.helper;

import hjp.smart4j.framework.util.CollectionUtil;
import hjp.smart4j.framework.util.PropsUtil;
import org.apache.commons.dbcp2.BasicDataSource;
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.MapListHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties; /**
* 数据库操作助手类
*/
public 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(); Properties conf = PropsUtil.loadProps("config.properties");
String driver = conf.getProperty("jdbc.driver");
String url = conf.getProperty("jdbc.url");
String username = conf.getProperty("jdbc.username");
String password = conf.getProperty("jdbc.password");
DATA_SOURCE.setDriverClassName(driver);
DATA_SOURCE.setUrl(url);
DATA_SOURCE.setUsername(username);
DATA_SOURCE.setPassword(password); } /**
* 获取数据库连接
*/
public static Connection getConnection() {
Connection connection = CONNECTION_HOLDER.get();
if (connection == null) {
try {
connection = DATA_SOURCE.getConnection();
} catch (SQLException e) {
LOGGER.error("get connection failure", e);
throw new RuntimeException(e);
} finally {
CONNECTION_HOLDER.set(connection);
}
}
return connection;
} /**
* 查询实体列表
*/
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 queryEntity(Class<T> entityClass, String sql, Object... params) {
T entity;
try {
Connection connection = getConnection();
entity = QUERY_RUNNER.query(connection, sql, new BeanHandler<T>(entityClass), params);
} catch (SQLException e) {
LOGGER.error("query entity failure", e);
throw new RuntimeException(e);
}
return entity;
} /**
* 执行查询语句
*/
public static List<Map<String, Object>> executeQuery(String sql, Object... params) {
List<Map<String, Object>> result;
try {
Connection connection = getConnection();
result = QUERY_RUNNER.query(connection, sql, new MapListHandler(), params);
} catch (Exception e) {
LOGGER.error("execute query failure", e);
throw new RuntimeException(e);
}
return result;
} /**
* 执行更新语句(update、insert、delete)
*/
public static int executeUpdate(String sql, Object... params) {
int rows = 0;
try {
Connection connection = getConnection();
rows = QUERY_RUNNER.update(connection, sql, params);
} catch (SQLException e) {
LOGGER.error("execute update failure", e);
throw new RuntimeException(e);
}
return rows;
} /**
* 插入实体
*/
public static <T> boolean insertEntity(Class<T> entityClass, Map<String, Object> fieldMap) {
if (CollectionUtil.isEmpty(fieldMap)) {
LOGGER.error("can not insert entity: fieldMap is empty");
return false;
} String sql = "insert into " + getTableName(entityClass);
StringBuilder columns = new StringBuilder(" (");
StringBuilder values = new StringBuilder(" (");
for (String fieldName : fieldMap.keySet()) {
columns.append(fieldName).append(", ");
values.append("?, ");
}
columns.replace(columns.lastIndexOf(", "), columns.length(), ") ");
values.replace(values.lastIndexOf(", "), values.length(), ") ");
sql += columns + " values " + values; Object[] params = fieldMap.values().toArray();
return executeUpdate(sql, params) == 1;
} /**
* 更新实体
*/
public static <T> boolean updateEntity(Class<T> entityClass, long id, Map<String, Object> fieldMap) {
if (CollectionUtil.isEmpty(fieldMap)) {
LOGGER.error("can not update entity: fieldMap is empty");
return false;
} String sql = "update " + getTableName(entityClass) + " set ";
StringBuilder columns = new StringBuilder();
for (String fieldName : fieldMap.keySet()) {
columns.append(fieldName).append("=?, ");
}
sql += columns.substring(0, columns.lastIndexOf(", ")) + " where id=?"; List<Object> paramList = new ArrayList<Object>();
paramList.addAll(fieldMap.values());
paramList.add(id);
Object[] params = paramList.toArray();
return executeUpdate(sql, params) == 1;
} /**
* 删除实体
*/
public static <T> boolean deleteEntity(Class<T> entityClass, long id) {
String sql = "delete from " + getTableName(entityClass) + " where id=?";
return executeUpdate(sql, id) == 1;
} /**
* 通过类名获取表名
*/
private static String getTableName(Class<?> entityClass) {
return entityClass.getSimpleName();
} /**
* 执行SQL文件
*/
public static void executeSqlFile(String filePath) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
try {
String sql;
while ((sql = reader.readLine()) != null) {
executeUpdate(sql);
}
} catch (IOException e) {
LOGGER.error("execute sql file failure", e);
throw new RuntimeException(e);
}
} /**
* 开启事务
*/
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();
}
}
}
}

DatabaseHelper

相关代码下载

需要关注的地方

1、ThreadLocal<Connection>

泛型内指定存储数据类型

2、数据库连接对象创建后不再关闭,交由BasicDataSource管理

3、java中泛型T和?

  T用于指定参数类型或返回类型,泛型方法要在方法名前标记<T>

  ?用于泛型类型指定,如Class<?>,任意类型的Class类;List<?> list,任意类型集合

使用ThreadLocal、Apache的dbutils的QueryRunner和dbcp2数据库连接池的BasicDataSource封装操作数据库工具的更多相关文章

  1. Apache的DBUtils框架学习(转)

    原文地址:http://www.cnblogs.com/xdp-gacl/p/4007225.html 一.commons-dbutils简介 commons-dbutils 是 Apache 组织提 ...

  2. Python数据库连接池DBUtils.PooledDB

    DBUtils 是一套用于管理数据库连接池的包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.最常用的两个外部接口是 PersistentDB 和 PooledDB,前者 ...

  3. java jdbc深入理解(connection与threadlocal与数据库连接池和事务实)

    1.jdbc连接数据库,就这样子 Class.forName("com.mysql.jdbc.Driver");java.sql.Connection conn = DriverM ...

  4. Python数据库连接池DBUtils详解

    what's the DBUtils DBUtils 是一套用于管理数据库连接池的Python包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.并允许对非线程安全的数据库 ...

  5. flask数据库连接池DBUtils

    数据库连接池 为啥要使用数据库连接池 频繁的连接和断开数据库,消耗大,效率低 DBUtils可以创建多个线程连接数据库,且一直保持连接,不会断开 执行数据库操作时,由数据池分配线程,当数据池空时,可选 ...

  6. java.lang.ClassNotFoundException: org.apache.commons.dbutils.QueryRunner

    七月 28, 2017 11:06:33 下午 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() fo ...

  7. javaweb学习总结—Apache的DBUtils框架学习

    注明: 本文转载自http://www.cnblogs.com/xdp-gacl/p/4007225.html 一.commons-dbutils简介 commons-dbutils 是 Apache ...

  8. JavaWeb学习总结(十四)--Apache的DBUtils

    一.commons-dbutils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化 ...

  9. javaweb学习总结(四十一)——Apache的DBUtils框架学习

    一.commons-dbutils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化 ...

随机推荐

  1. python基础-PyCharm设置作者信息模板_修改解释器_设置软件UTF-8编码

    一.PyCharm 设置作者信息模板 1.File---Settings---在搜索框中搜索:File and Code Templates---Python scripts #!/usr/bin/e ...

  2. [转]Spring3 MVC + jQuery easyUI 做的ajax版本用户管理

    原文地址:http://www.iteye.com/topic/1081739 上周写了篇基于spring3.0.5 mvc 简单用户管理实例 ( http://www.iteye.com/topic ...

  3. git 格式化输出版本信息

    git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&l ...

  4. Maven_Build_Resources

    功能:主要用于打包资源文件,默认情况下maven只打包src/main/resource下的资源,通过 1.设置build_resources 2.使用build-helper-maven-plugi ...

  5. 网络流 POJ2112

    题意:K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用:并告诉了产奶机.奶牛之间的两两距离Dij(0<=i,j<K+C). 问题:如何安排使得在任何一头奶牛都有自己产奶机的条件下,奶牛 ...

  6. poj2553 强连通缩点

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10114   Accepted: ...

  7. 【转】oracle数据库开发的一些经验积累

    1.不安装Oracle客户连接Oracle 8的方法  请将以下文件拷贝到运行文件所在目录 一.ODBC动态库 : ctl3d32.dll msvcrt40.dll odbc16gt.dll odbc ...

  8. 【HDU 5810多校】Balls and Boxes(打表/数学)

    1.打表找规律,下面是打表程序: #include <iostream> #include <cstdio> #define ll long long #define N 10 ...

  9. composer更新不成功,启用国内镜像网站的配置更改办法

    通过 composer config -l -g 命令可以列出 composer 的全局配置信息 [home] 配置项就是 composer 的主目录 修改config.json { "co ...

  10. 网络爬虫3-使用LIB_http库

    LIB_http库提供了一个包装函数集,来简化复杂的PHP/CURL接口 1.http_get()函数,使用GET方法下载文件