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. c++ iterator(迭代器)分类及其使用

    前言: 以下的内容为我阅读c++沉思录18,19,20章的笔记以及自己的想法. 正文: 总所周知,c++的stl中提出了iterator的概念,这是C所没有的.在一般的使用中,iterator的行为很 ...

  2. SharedPrefernces使用实例讲解

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  3. linux 配置java 环境

    下载jdk 并解压到 /usr/local/java/ 目录下 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-down ...

  4. iOS开发小技巧-修改SliderBar指针的样式(牢记这个方法,只能通过代码来修改)

    代码: // 修改进度条的指针图片 [self.progressSlider setThumbImage:[UIImage imageNamed:@"player_slider_playba ...

  5. 【NOIP 2004】虫食算

    因为一天机房都是断网状态,校内的小V评测这道题总显示Unaccept,所以下午放学后就和xiaoyimi晚上回家自习,来做一做这道题. 搜索+剪枝优化: 一开始我是顺着低位向高位填数,这么暴力在Vij ...

  6. html5标签figure、figcaption

    figure.figcaption,这俩个标签都是定义图文的 常常用到一种图片列表,图片+标题或者图片+标题+简单描述.以前的常规写法: <li> <img src="te ...

  7. 解决虚拟机 MAC10.9 不能设置1366*768分辨率问题

    首先在虚拟机设置里,显示--3d下面--固定分辨率--最大设成1024*768--保存然后打开虚拟机的.vmx文件,最后几行 svga.autodetect = "FALSE"sv ...

  8. response与文件下载

    参考博客: http://www.cnblogs.com/lcpholdon/p/4380980.html http://www.cnblogs.com/mingforyou/p/3281945.ht ...

  9. Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors

    目录 . Rowhammer Introduction . Rowhammer Principle . Track And Fix 1.  rowhammer introduction 今天的DRAM ...

  10. crawler: 爬虫的基本结构

    目前我所知道的爬虫在获取页面信息上,分为静态爬虫和动态爬虫:静态爬虫主要用于获取静态页面,获取速度一般也比较快:但是现在很多网站的页面都是采用动态页面,当我们用爬虫去获取信息的时候,页面的信息可能还没 ...