Java -- JDBC 学习--使用 DBUtils
Apache—DBUtils简介
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。
API介绍:
org.apache.commons.dbutils.QueryRunner
org.apache.commons.dbutils.ResultSetHandler
工具类
org.apache.commons.dbutils.DbUtils
如下利用DbUtils进行常用操作的封装:
DAO接口:
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List; /**
* 访问数据的 DAO 接口.
* 里边定义好访问数据表的各种方法
* @param T: DAO 处理的实体类的类型.
*/
public interface DAO<T> { /**
* 批量处理的方法
* @param connection
* @param sql
* @param args: 填充占位符的 Object [] 类型的可变参数.
* @throws SQLException
*/
void batch(Connection connection,
String sql, Object [] ... args) throws SQLException; /**
* 返回具体的一个值, 例如总人数, 平均工资, 某一个人的 email 等.
* @param connection
* @param sql
* @param args
* @return
* @throws SQLException
*/
<E> E getForValue(Connection connection,
String sql, Object ... args) throws SQLException; /**
* 返回 T 的一个集合
* @param connection
* @param sql
* @param args
* @return
* @throws SQLException
*/
List<T> getForList(Connection connection,
String sql, Object ... args) throws SQLException; /**
* 返回一个 T 的对象
* @param connection
* @param sql
* @param args
* @return
* @throws SQLException
*/
T get(Connection connection, String sql,
Object ... args) throws SQLException; /**
* INSRET, UPDATE, DELETE
* @param connection: 数据库连接
* @param sql: SQL 语句
* @param args: 填充占位符的可变参数.
* @throws SQLException
*/
void update(Connection connection, String sql,
Object ... args) throws SQLException; }
实现DAO类:
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List; 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.ScalarHandler; /**
* 使用 QueryRunner 提供其具体的实现
* @param <T>: 子类需传入的泛型类型.
*/
public class JdbcDaoImpl<T> implements DAO<T> { private QueryRunner queryRunner = null;
private Class<T> type; public JdbcDaoImpl() {
queryRunner = new QueryRunner();
type = ReflectionUtils.getSuperGenericType(getClass());
} @Override
public void batch(Connection connection, String sql, Object[]... args) throws SQLException {
queryRunner.batch(connection, sql, args);
} @Override
public <E> E getForValue(Connection connection, String sql, Object... args) throws SQLException {
return (E) queryRunner.query(connection, sql, new ScalarHandler(), args);
} @Override
public List<T> getForList(Connection connection, String sql, Object... args)
throws SQLException {
return queryRunner.query(connection, sql,
new BeanListHandler<>(type), args);
} @Override
public T get(Connection connection, String sql, Object... args) throws SQLException {
return queryRunner.query(connection, sql,
new BeanHandler<>(type), args);
} @Override
public void update(Connection connection, String sql, Object... args) throws SQLException {
queryRunner.update(connection, sql, args);
} }
public class CustomerDao
extends JdbcDaoImpl<Customer>{ }
Customer.java对象类:
import java.sql.Date;
public class Customer {
private Integer id;
private String name;
private String email;
private Date birth;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCustomerName() {
return name;
}
public void setCustomerName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", email=" + email
+ ", birth=" + birth + "]";
}
public Customer(Integer id, String name, String email, Date birth) {
super();
this.id = id;
this.name = name;
this.email = email;
this.birth = birth;
}
public Customer() {
// TODO Auto-generated constructor stub
}
}
调用示例:
@Test
public void testGet() {
Connection connection = null; try {
connection = JDBCTools.getConnection();
String sql = "SELECT id, name customerName, " +
"email, birth FROM customers " +
"WHERE id = ?";
Customer customer = customerDao.get(connection, sql, 5);
System.out.println(customer);
} catch (Exception e) {
e.printStackTrace();
} finally{
JDBCTools.releaseDB(null, null, connection);
}
}
相关反射类:
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; /**
* 反射的 Utils 函数集合
* 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
* @author Administrator
*
*/
public class ReflectionUtils { /**
* 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
* 如: public EmployeeDao extends BaseDao<Employee, String>
* @param clazz
* @param index
* @return
*/
@SuppressWarnings("unchecked")
public static Class getSuperClassGenricType(Class clazz, int index){
Type genType = clazz.getGenericSuperclass(); if(!(genType instanceof ParameterizedType)){
return Object.class;
} Type [] params = ((ParameterizedType)genType).getActualTypeArguments(); if(index >= params.length || index < 0){
return Object.class;
} if(!(params[index] instanceof Class)){
return Object.class;
} return (Class) params[index];
} /**
* 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
* 如: public EmployeeDao extends BaseDao<Employee, String>
* @param <T>
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static<T> Class<T> getSuperGenericType(Class clazz){
return getSuperClassGenricType(clazz, 0);
} /**
* 循环向上转型, 获取对象的 DeclaredMethod
* @param object
* @param methodName
* @param parameterTypes
* @return
*/
public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){ for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
try {
//superClass.getMethod(methodName, parameterTypes);
return superClass.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
//Method 不在当前类定义, 继续向上转型
}
//..
} return null;
} /**
* 使 filed 变为可访问
* @param field
*/
public static void makeAccessible(Field field){
if(!Modifier.isPublic(field.getModifiers())){
field.setAccessible(true);
}
} /**
* 循环向上转型, 获取对象的 DeclaredField
* @param object
* @param filedName
* @return
*/
public static Field getDeclaredField(Object object, String filedName){ for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
try {
return superClass.getDeclaredField(filedName);
} catch (NoSuchFieldException e) {
//Field 不在当前类定义, 继续向上转型
}
}
return null;
} /**
* 直接调用对象方法, 而忽略修饰符(private, protected)
* @param object
* @param methodName
* @param parameterTypes
* @param parameters
* @return
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
Object [] parameters) throws InvocationTargetException{ Method method = getDeclaredMethod(object, methodName, parameterTypes); if(method == null){
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
} method.setAccessible(true); try {
return method.invoke(object, parameters);
} catch(IllegalAccessException e) {
System.out.println("不可能抛出的异常");
} return null;
} /**
* 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
* @param object
* @param fieldName
* @param value
*/
public static void setFieldValue(Object object, String fieldName, Object value){
Field field = getDeclaredField(object, fieldName); if (field == null)
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]"); makeAccessible(field); try {
field.set(object, value);
} catch (IllegalAccessException e) {
System.out.println("不可能抛出的异常");
}
} /**
* 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
* @param object
* @param fieldName
* @return
*/
public static Object getFieldValue(Object object, String fieldName){
Field field = getDeclaredField(object, fieldName); if (field == null)
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]"); makeAccessible(field); Object result = null; try {
result = field.get(object);
} catch (IllegalAccessException e) {
System.out.println("不可能抛出的异常");
} return result;
}
}
Java -- JDBC 学习--使用 DBUtils的更多相关文章
- Java JDBC学习实战(二): 管理结果集
在我的上一篇博客<Java JDBC学习实战(一): JDBC的基本操作>中,简要介绍了jdbc开发的基本流程,并详细介绍了Statement和PreparedStatement的使用:利 ...
- Java -- JDBC 学习--批量处理
批量处理JDBC语句提高处理速度 当需要成批插入或者更新记录时.可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理.通常情况下比单独提交处理更有效率JDBC的批量处理语句包 ...
- Java -- JDBC 学习--处理Blob
Oracle LOB LOB,即Large Objects(大对象),是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据).LOB 分为两种类型:内部LOB和外部L ...
- Java -- JDBC 学习--通过 ResultSet 执行查询操作
ResultSet: 结果集. 封装了使用 JDBC 进行查询的结果. 1. 调用 Statement 对象的 executeQuery(sql) 可以得到结果集. 2. ResultSet 返回的实 ...
- Java -- JDBC 学习--通过Statement进行数据库更新操作
通过 JDBC 向指定的数据表中插入一条记录. 1. Statement: 用于执行 SQL 语句的对象 1). 通过 Connection 的 createStatement() 方法来获取 2). ...
- Java -- JDBC 学习--获取数据库链接
数据持久化 持久化(persistence): 把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大 ...
- Java JDBC学习实战(一): JDBC的基本操作
一.JDBC常用接口.类介绍 JDBC提供对独立于数据库统一的API,用以执行SQL命令.API常用的类.接口如下: DriverManager,管理JDBC驱动的服务类,主要通过它获取Connect ...
- Java -- JDBC 学习--调用函数&存储过程
调用函数&存储过程 /** * 如何使用 JDBC 调用存储在数据库中的函数或存储过程 */ @Test public void testCallableStatment() { Connec ...
- Java -- JDBC 学习--数据库连接池
JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet.beans)中建立数据库连接. 进行sql操作 断开数据库连接. 这种模式开 ...
随机推荐
- ML.NET 示例:开篇
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- RabbitMQ在特来电的深度应用
特来电是一个互联网公司,而且是技术领先的互联网公司.互联网公司的标配是什么?答案就是缓存+MQ.没错,您没看错,就是MQ--消息队列,我们今天要讨论的RabbitMQ就是消息队列中功能非常强大的一种. ...
- Rancher + k8s + docker 部署资料
一.k8s 文档: https://jimmysong.io/kubernetes-handbook/concepts/deployment.html 命令行大全 https://kubernetes ...
- 系统重启后DNS地址默认修改修改引起的一次事故(Tomcat报错:java.net.UnknownHostException)
事故描述:公司的一个内部业务系统由于程序bug,导致系统崩溃,需要强制重启服务器.系统重启后,赶紧将业务程序启动.随后发现/etc/resolv.conf文件的DNS地址被修改成了默认地址.发现之后, ...
- Linux系统下CPU使用(load average)梳理
在平时的运维工作中,当一台服务器的性能出现问题时,通常会去看当前的CPU使用情况,尤其是看下CPU的负载情况(load average).对一般的系统来说,根据cpu数量去判断.比如有2颗cup的机器 ...
- Uniform Generator HDU1014
题意 给你公式seed(x+1) = [seed(x) + STEP] % MOD ,输入step和mod, 问你是否可以从第一项0,算到mod,它们是否都不同 是 good choice 否则 ba ...
- Linux内核分析作业 NO.7
可执行程序的装载 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实 ...
- Linux内核分析-系统中断在内核中的实现
分析system_call中断处理过程 在MenuOS中添加上周所运用到的系统调用 即在Linuxkernel/menu/test.c文件中,添加代码如下: int Mkdir() { const c ...
- wordpress升级出错
服务器是腾讯云 搜索到的解决方案有几个,试了好几个,不知道哪个是根本原因,反正都操作了. 设置wordpress文件夹和子文件夹的权限 编辑wp-config.php,在文末添加如下: define( ...
- centos7 服务操作命令
systemctl list-unit-files --type service --all 操作防火墙: https://www.jianshu.com/p/411274f96492 操作VNC: ...