使用ThreadLocal、Apache的dbutils的QueryRunner和dbcp2数据库连接池的BasicDataSource封装操作数据库工具
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封装操作数据库工具的更多相关文章
- Apache的DBUtils框架学习(转)
原文地址:http://www.cnblogs.com/xdp-gacl/p/4007225.html 一.commons-dbutils简介 commons-dbutils 是 Apache 组织提 ...
- Python数据库连接池DBUtils.PooledDB
DBUtils 是一套用于管理数据库连接池的包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.最常用的两个外部接口是 PersistentDB 和 PooledDB,前者 ...
- java jdbc深入理解(connection与threadlocal与数据库连接池和事务实)
1.jdbc连接数据库,就这样子 Class.forName("com.mysql.jdbc.Driver");java.sql.Connection conn = DriverM ...
- Python数据库连接池DBUtils详解
what's the DBUtils DBUtils 是一套用于管理数据库连接池的Python包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.并允许对非线程安全的数据库 ...
- flask数据库连接池DBUtils
数据库连接池 为啥要使用数据库连接池 频繁的连接和断开数据库,消耗大,效率低 DBUtils可以创建多个线程连接数据库,且一直保持连接,不会断开 执行数据库操作时,由数据池分配线程,当数据池空时,可选 ...
- java.lang.ClassNotFoundException: org.apache.commons.dbutils.QueryRunner
七月 28, 2017 11:06:33 下午 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() fo ...
- javaweb学习总结—Apache的DBUtils框架学习
注明: 本文转载自http://www.cnblogs.com/xdp-gacl/p/4007225.html 一.commons-dbutils简介 commons-dbutils 是 Apache ...
- JavaWeb学习总结(十四)--Apache的DBUtils
一.commons-dbutils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化 ...
- javaweb学习总结(四十一)——Apache的DBUtils框架学习
一.commons-dbutils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化 ...
随机推荐
- android开发------编写用户界面之线性布局(补充知识)
在前面的文章中 http://www.cnblogs.com/ai-developers/p/android_linearlayout.html 我们看到了布局中有这样一个属性: layout_wei ...
- jQuery基础--样式篇(3)
1.jQuiery对象与DOM对象 对于刚刚接触jQuery的初学者,我们要清楚认识一点:jQuery对象与DOM对象是不一样的.可能一时半会分不清楚哪些是jQuery对象,哪些是DOM对象,下面重点 ...
- android中通话录音
file = new File(Environment.getExternalStorageDirectory(), this.incomeNumber + System.currentTimeMil ...
- android之二维码扫描的实现
二维码扫描引擎有 ZBar 和ZXing 一. 使用开源ZXing扫描的缺点 1.原始代码是横屏模式,尽管可以改成竖屏,但是扫描界面的自定义和多屏幕适配不好做 2.有效扫描区域不好控制,可能是我自己技 ...
- [转] 使用Spring MVC构建REST风格WEB应用
原文地址:http://fancy888.iteye.com/blog/1629120 对于运行在网络上的MIS系统而言,处理数据的是整个系统的主要任务,翻开程序我们可以看到,80%以上的代码都在处理 ...
- 【ASP.NET Identity系列教程(二)】运用ASP.NET Identity
注:本文是[ASP.NET Identity系列教程]的第二篇.本系列教程详细.完整.深入地介绍了微软的ASP.NET Identity技术,描述了如何运用ASP.NET Identity实现应用程序 ...
- php COOKIE和SESSION的一些理解
web服务器是基于http协议的,而http协议是无状态的,导致任意两个请求之间没有联系.但是我们登录网站后,它却能记住我们的身份,这个过程中一定使用了某个标识来区别我们的身份.对于简单数据传输的我们 ...
- 【USACO 1.3】Combination Lock
/* TASK:combo LANG:C++ URL:http://train.usaco.org/usacoprob2?a=E6RZnAhV9zn&S=combo SOLVE:自己做,想的是 ...
- bash 操作 sqlite3
首先,这是个奇怪的需求...但是遇到了.我参考后文链接里的方法,做了自己的. 表是自己手动建的,数据库名字叫 new.db: create table test (sn varchar(), name ...
- .Net和C#的理解
.Net是一个微软出品的开发平台,不仅仅是适用于Windows操作系统,还适用于mono,Linux等等, .Net库包括两部分:部分库定义了一些基本类型.CTS(common Type System ...