DBUtils包是apache commons的一个工具包,主要是用来对jdbc程序的补充与封装,通过简单封装让jdbc程序更简洁,使我们的程序更加的清晰。整个工具包只有不到30个类和接口,但是功能很强大,基本使我们避免了jdbc中的很多繁琐重复的代码,昨天对这个包中的源码进行了阅读与测试,下面对主要常用的API总结一下:
API docs图:
可见其中主要的两个接口ResultSetHandler和RowProcessor都是用来对查询结果记录进行处理的接口,包中很多类都是实现这两个接口来达到其功能的。
一、DbUtils类:
这个类中提供了很多关闭资源、简单事务提交与回滚、以及loadDriver的工具方法。这个类与平时我们自己写的DB工具类差不多,只是没有看到getConnection这样的方法。
- 关闭数据库资源方法
- 这类方法有两种:close与closeQuietly,每种都有多个重载的方法,源码很简单,就是对jdbc代码的简单封装:
public static void close(Connection conn) throws SQLException { if (conn != null) {//简单的判断非null、然后关闭 conn.close(); } } public static void closeQuietly(ResultSet rs) { try { close(rs); } catch (SQLException e) { // NOPMD // quiet 捕获异常什么也没做 } }
-
当然这类方法还支持同时关闭多个资源,包括connection、resultset、preparestatment等,使用了嵌套的try catche finally 来保证资源的关闭。
- 这类方法有两种:close与closeQuietly,每种都有多个重载的方法,源码很简单,就是对jdbc代码的简单封装:
- 简单事务操作方法
- 提交和回滚事务操作,都是简单的判断connection是否为空,执行相应的提交回滚操作,并关闭链接,像close方法一样这两个方法也有quietly的方法,操作类似:
public static void commitAndClose(Connection conn) throws SQLException { if (conn != null) { try { conn.commit(); } finally { conn.close(); } } } public static void rollbackAndClose(Connection conn) throws SQLException { if (conn != null) { try { conn.rollback(); } finally { conn.close(); } } }
- 提交和回滚事务操作,都是简单的判断connection是否为空,执行相应的提交回滚操作,并关闭链接,像close方法一样这两个方法也有quietly的方法,操作类似:
- 加载Driver方法
- loadDriver方法也有一个重载的实现,一个直接使用默认的加载器加载Driver另一个可以提供一个ClassLoader参数来加载Driver:
public static boolean loadDriver(String driverClassName) { return loadDriver(DbUtils.class.getClassLoader(), driverClassName); } public static boolean loadDriver(ClassLoader classLoader, String driverClassName) { try { Class<?> loadedClass = classLoader.loadClass(driverClassName); if (!Driver.class.isAssignableFrom(loadedClass)) { return false; } @SuppressWarnings("unchecked") // guarded by previous check Class<Driver> driverClass = (Class<Driver>) loadedClass; Constructor<Driver> driverConstructor = driverClass.getConstructor(); // make Constructor accessible if it is private boolean isConstructorAccessible = driverConstructor.isAccessible(); if (!isConstructorAccessible) { driverConstructor.setAccessible(true); } try { Driver driver = driverConstructor.newInstance();//通过反射的方式来创建Driver实例,调用了一个内部私有类来注册Driver registerDriver(new DriverProxy(driver)); } finally { driverConstructor.setAccessible(isConstructorAccessible); } return true; } catch (RuntimeException e) { return false; } catch (Exception e) { return false; } }
- loadDriver方法也有一个重载的实现,一个直接使用默认的加载器加载Driver另一个可以提供一个ClassLoader参数来加载Driver:
- 打印信息方法:
- 这些方法主要是用来打印异常信息的,可以指定输出的printwriter等,没做过多研究,没怎么使用过。
这个类可以与我们自己实现的一个DbTools类一起配合使用简化jdbc代码,这样基本的jdbc常用的功能就全了:
/**
* Created by weiguang on 16-8-15.
*/
public final class DbTools {
private static final Logger logger = LoggerFactory.getLogger(DbTools.class);
private static String username;
private static String password;
private static String jdbcUrl;
private static String driverClass;
static {
InputStream in = DbTools.class.getClassLoader().getResourceAsStream("db.properties");
Properties props = new Properties();
try {
props.load(in);
} catch (IOException e) {
logger.error("db.properties 文件加载失败!!", e);
}
username = props.getProperty("username");
password = props.getProperty("password");
jdbcUrl = props.getProperty("jdbcUrl");
driverClass = props.getProperty("driverClass");
// 使用DBUtils包中的工具类避免捕获异常,是代码更整洁
DbUtils.loadDriver(driverClass);
}
public static Connection getConnection() {
try {
return DriverManager.getConnection(jdbcUrl, username, password);
} catch (SQLException e) {
logger.error("获取数据库链接失败!", e);
}
return null;
}
}