直接上代码

package org.smart4j.chapter2.helper;

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 org.smart4j.chapter2.util.CollectionUtil;
import org.smart4j.chapter2.util.PropsUtil; import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties; /**
* DbUtils 提供对 JDBC 的轻量级封装
* 通过 DbUtils 提供的 QueryRunner 对象可以面向实体(Entity)进行查询。
* 它的原理是:执行 SQL 语句并返回一个 ResultSet,随后通过反射去创建并初始化实体对象。
* Created by zhengbinMac on 2017/3/25.
*/
public class DatabaseHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseHelper.class); // 线程连接
private static final ThreadLocal<Connection> CONNECTION_THREAD_LOCAL;
// DbUtils
private static final QueryRunner QUERY_RUNNER;
// 线程池
private static final BasicDataSource DATA_SOURCE; static {
CONNECTION_THREAD_LOCAL = new ThreadLocal<>();
QUERY_RUNNER = new QueryRunner(); Properties conf = PropsUtil.loadProps("config.properties");
// 设置连接池,使用 DBCP 来获取数据库连接
DATA_SOURCE = new BasicDataSource();
DATA_SOURCE.setDriverClassName(conf.getProperty("jdbc.driver"));
DATA_SOURCE.setUrl(conf.getProperty("jdbc.url"));
DATA_SOURCE.setUsername(conf.getProperty("jdbc.username"));
DATA_SOURCE.setPassword(conf.getProperty("jdbc.password"));
} /**
* 获取数据库连接
*/
public static Connection getConnection() {
// 首先从 ThreadLocal 中获取
Connection connection = CONNECTION_THREAD_LOCAL.get();
// 若不存在,则创建一个新的 Connection,并最终将其放入 ThreadLocal 中
if (connection == null) {
try {
connection = DATA_SOURCE.getConnection();
} catch (SQLException e) {
LOGGER.error("get connection failure", e);
} finally {
CONNECTION_THREAD_LOCAL.set(connection);
}
}
return connection;
} /**
* 批量查询实体
*/
public static <T> List<T> queryEntityList(Class<T> entityClass, String sql, Object... params) {
List<T> entityList = null;
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);
}
return entityList;
} /**
* 查询单个实体
*/
public static <T> T queryEntity(Class<T> entityClass, String sql, Object... params) {
T entity = null;
try {
Connection conn = getConnection();
entity = QUERY_RUNNER.query(conn, sql, new BeanHandler<T>(entityClass), params);
} catch (SQLException e) {
LOGGER.error("query entity failure", e);
e.printStackTrace();
}
return entity;
} public static List<Map<String, Object>> executeQuery(String sql, Object... params) {
List<Map<String, Object>> result = null;
try {
Connection conn = getConnection();
result = QUERY_RUNNER.query(conn, sql, new MapListHandler(), params);
} catch (SQLException e) {
LOGGER.error("query entity failure", e);
e.printStackTrace();
}
return result;
} /**
* 执行更新语句(update、insert 和 delete)
*/
public static int executeUpdate(String sql, Object... params) {
int updateRows = 0;
try {
Connection conn = getConnection();
updateRows = QUERY_RUNNER.update(conn, sql, params);
} catch (SQLException e) {
LOGGER.error("execute update failure", e);
e.printStackTrace();
}
return updateRows;
} /**
* 插入实体
*/
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 colums = new StringBuilder("(");
StringBuilder values = new StringBuilder("("); // 插入实体的字段名,和字段值的占位符
for (String colum : fieldMap.keySet()) {
colums.append(colum).append(", ");
values.append("?, ");
}
colums.replace(colums.lastIndexOf(", "), colums.length(), ")");
values.replace(values.lastIndexOf(", "), values.length(), ")");
sql += colums + " 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;
}
// 更具 fieldMap 拼接出更新 SQL 语句
String sql = "UPDATE " + getTableName(entityClass) + " SET ";
StringBuilder columns = new StringBuilder();
// 更新实体的字段
for (String colums : fieldMap.keySet()) {
columns.append(columns).append("=?, ");
} // 去掉 SQL 最后一个 ', '
sql += columns.substring(0, columns.lastIndexOf(", ")) + " WHERE id=?"; // 更新实体的值
List<Object> paramList = new ArrayList<Object>();
paramList.addAll(fieldMap.values());
paramList.add(id); // 增加主键 id
Object[] params = paramList.toArray(); return executeUpdate(sql, params) == 1;
} /**
* 删除实体
*/
public static <T> boolean deleteEntity(Class<T> entityClass, long id) {
String sql = "DELTE FROM " + getTableName(entityClass) + "WHERE id=?";
return executeUpdate(sql, id) == 1;
} /**
* 获取操作表的表名,即实体的类名
*/
private static String getTableName(Class<?> entityClass) {
return entityClass.getSimpleName();
}
}

两个工具类

集合工具类:

package org.smart4j.chapter2.util;

import org.apache.commons.collections.MapUtils;

import java.util.Collection;
import java.util.Map; /**
* 集合工具类
*
* Created by zhengbinMac on 2017/3/25.
*/
public class CollectionUtil {
/**
* 判断 Collection 是否为空
*/
public static boolean isEmpty(Collection<?> collection) {
return CollectionUtil.isEmpty(collection);
} /**
* 判断 Collection 是否为非空
*/
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
} /**
* 判断 Map 是否为空
*/
public static boolean isEmpty(Map<?, ?> map) {
return MapUtils.isEmpty(map);
} /**
* 判断 Map 是否为非空
*/
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}
}

属性文件(properties)工具类:

package org.smart4j.chapter2.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; /**
* 属性文件工具类
*
* Created by zhengbinMac on 2017/3/25.
*/
public class PropsUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(PropsUtil.class); /**
* 加载属性文件
*/
public static Properties loadProps(String fileName) {
Properties properties = null;
InputStream is = null;
try {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
if (is == null) {
throw new FileNotFoundException(fileName + "file is not found");
}
properties = new Properties();
properties.load(is);
} catch (IOException e) {
LOGGER.error("load properties file failure", e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
LOGGER.error("close inputStream failure", e);
}
}
}
return properties;
} /**
* 获取字符型属性(默认值为空字符串)
*/
public static String getString(Properties properties, String key) {
return getString(properties, key, "");
} /**
* 获取字符型属性(可指定默认值)
*/
public static String getString(Properties properties, String key, String defaultValue) {
String value = defaultValue;
if (properties.contains(key)) {
value = properties.getProperty(key);
}
return value;
} /**
* 获取数值型属性(默认值为0)
*/
public static int getInt(Properties properties, String key) {
return getInt(properties, key, 0);
} /**
* 获取数值型属性(可指定默认值)
*/
public static int getInt(Properties properties, String key, int defaultValue) {
int value = defaultValue;
if (properties.contains(key)) {
value = CastUtil.castInt(properties.getProperty(key));
}
return value;
} /**
* 获取布尔型属性(默认值为 false)
*/
public static boolean getBoolean(Properties properties, String key) {
return getBoolean(properties, key, false);
} /**
* 获取布尔型属性(可指定默认值)
*/
public static boolean getBoolean(Properties properties, String key, boolean defaultValue) {
boolean value = defaultValue;
if (properties.contains(key)) {
value = CastUtil.castBoolean(properties.getProperty(key));
}
return value;
}
}

参考资料

[1] 架构探险, 第 2 章 - 为 Web 应用添加业务功能

使用DbUtils对JDBC封装实现面向实体查询的更多相关文章

  1. Apache—dbutils开源JDBC工具类库简介

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

  2. 优化JDBC封装

    可重用性较强的JDBC封装 以下为代码,注释中写了主要思想 主类 com.util.JDBCUtil.java package com.util; import java.lang.reflect.F ...

  3. jdbc封装代码

    jdbc封装代码 package jdbcUtil; import java.sql.Connection; import java.sql.DriverManager; import java.sq ...

  4. MyBatis Plus 将查询结果封装到指定实体

    MyBatis Plus 将查询结果封装到指定实体 思路 自定义方法,使用Wrapper,自定义映射结果集 Mapper接口 package com.mozq.boot.mpsand01.dao; i ...

  5. Phoenix的jdbc封装

    一.Phoenix版本 <dependency> <groupId>org.apache.phoenix</groupId> <artifactId>p ...

  6. JDBC封装的工具类

    1. JDBC封装的工具类 public class JDBCUtil { private static Properties p = new Properties(); private static ...

  7. Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法

    先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...

  8. 通过Java反射做实体查询

    我们在使用hibernate的时候,查询的时候都会和实体中的一些字段相结合去查询,当然字段少了,还算是比较简单,当字段多了,就不那么容易了,所以就自己写了个方法,根据实体中的字段信息去查询,废话不多说 ...

  9. JDBC_14_使用JDBC工具类实现模糊查询

    使用JDBC工具类实现模糊查询 代码: import java.sql.*; /** * 模糊查询 * 测试DBUtils */ public class JDBCTest09 { public st ...

随机推荐

  1. win7 git 安装

    下载git: https://git-scm.com/download/win 二.Git安装 去官网下载完后一路下一步完成安装,如下图:   安装完后先在系统环境变量中看下是否配置   然后在桌面右 ...

  2. Fragment使用具体解释

    fragment是Google在3.0版本号中推出的新功能,如今已经增加到V4包中,假设要使用V4兼容包中的Fragment须要将Activity换成FragmentActivity,调用的getSu ...

  3. Android Support Library 23.2介绍(翻译自官方文档)

    Android Support Library 23.2 (译者注:本文标注了部分文字链接,但须要***,要查看全部链接.请查看sukey=014c68f407f2d3e181b6b5e665f26a ...

  4. 设计模式C++实现——模板方法模式

    模式定义: 模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类能够在不改变算法结构的情况下,又一次定义算法中的某些步骤. 模板就是一个方法.更详细的说.这种方法将 ...

  5. JDK1.6新特性,基础类库篇,Jar与Zip增强

    1. API改变 增加了两个实现类 java.util.zip.DeflaterInputStream: 此类为解压缩 "deflate" 压缩格式的数据实现流过滤器.它还用作其他 ...

  6. Java:concurrent包下面的Map接口框架图(ConcurrentMap接口、ConcurrentHashMap实现类)

    Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合.Java 5之后,增加了Queue体系集合, ...

  7. iOS 中strong,weak,copy,assign区别

    1:ARC环境下,strong代替retain.weak代替assign2:weak的作用:在ARC环境下,,所有指向这个对象的weak指针都将被置为nil.这个T特性很有用,相信很多开发者都被指针指 ...

  8. Unity中yield return null和yield return WaitForEndOfFrame的区别

    2017/07/04修改 - 对WaitForEndOfFrame的LateUpdate时序进行说明. 测试结论: 1.如果只是等待下一帧执行,用yield return null即可.调用顺序在Up ...

  9. [sql]mysql5.6cmake安装/mysql5.7二进制安装

    centos7上cmake编译安装mysql-5.6.36.tar.gz 系统环境 - 环境(安装前规划好主机名,mysql编译过程会用) [root@n1 mysql-5.6.36]# cat /e ...

  10. Java中使用Oracle的客户端 load data和sqlldr命令执行数据导入到数据库中

    Windows环境下测试代码: import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundExcep ...