commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。
commons-dbutilsAPI介绍:
- org.apache.commons.dbutils.QueryRunner
- org.apache.commons.dbutils.ResultSetHandler
工具类
- org.apache.commons.dbutils.DbUtils
直接上代码:
1.先建立一个jdbc的连接相关类:
package com.ming.core.db; import java.io.InputStream; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.Statement; import java.util.Properties; import java.util.logging.Logger; import javax.sql.DataSource; import org.apache.commons.dbutils.ResultSetHandler; public class JdbcUtils { private static String driver = "com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql://localhost:3306/test"; private static String username = "root"; private static String password = "root"; static { try { // 加载数据库驱动 Class.forName(driver); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } /** * @Method: getConnection * @Description: 获取数据库连接对象 * @Anthor:孤傲苍狼 * * @return Connection数据库连接对象 * @throws SQLException */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } /** * @Method: release * @Description: 释放资源, 要释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象, * 存储查询结果的ResultSet对象 * @Anthor:孤傲苍狼 * * @param conn * @param st * @param rs */ public static void release(Connection conn, Statement st, ResultSet rs) { if (rs != null) { try { // 关闭存储查询结果的ResultSet对象 rs.close(); } catch (Exception e) { e.printStackTrace(); } rs = null; } if (st != null) { try { // 关闭负责执行SQL命令的Statement对象 st.close(); } catch (Exception e) { e.printStackTrace(); } } if (conn != null) { try { // 关闭Connection数据库连接对象 conn.close(); } catch (Exception e) { e.printStackTrace(); } } } /** * @Method: update * @Description: 万能更新 所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已, * 因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句 * @Anthor:孤傲苍狼 * @param sql * 要执行的SQL * @param params * 执行SQL时使用的参数 * @throws SQLException */ public static void update(String sql, Object params[]) throws SQLException { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = getConnection(); st = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { st.setObject(i + 1, params[i]); } st.executeUpdate(); } finally { release(conn, st, rs); } } /** * @Method: query * @Description:万能查询 实体的R操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet的映射也各不相同, * 因此可义一个query方法,除以参数形式接收变化的SQL语句外, * 可以使用策略模式由qurey方法的调用者决定如何把ResultSet中的数据映射到实体对象中。 * @Anthor:孤傲苍狼 * * @param sql * 要执行的SQL * @param params * 执行SQL时使用的参数 * @param rsh * 查询返回的结果集处理器 * @return * @throws SQLException */ public static Object query(String sql, Object params[], ResultSetHandler rsh) throws SQLException { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = getConnection(); st = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { st.setObject(i + 1, params[i]); } rs = st.executeQuery(); /** * 对于查询返回的结果集处理使用到了策略模式, * 在设计query方法时,query方法事先是无法知道用户对返回的查询结果集如何进行处理的,即不知道结果集的处理策略, * 那么这个结果集的处理策略就让用户自己提供,query方法内部就调用用户提交的结果集处理策略进行处理 * 为了能够让用户提供结果集的处理策略,需要对用户暴露出一个结果集处理接口ResultSetHandler * 用户只要实现了ResultSetHandler接口,那么query方法内部就知道用户要如何处理结果集了 */ return rsh.handle(rs); } finally { release(conn, st, rs); } } public static DataSource getDataSource(){ return new DataSource() { @Override public Connection getConnection(String username, String password) throws SQLException { return null; } @Override public Connection getConnection() throws SQLException { return JdbcUtils.getConnection(); } @Override public PrintWriter getLogWriter() throws SQLException { return null; } @Override public int getLoginTimeout() throws SQLException { return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { } @Override public void setLoginTimeout(int seconds) throws SQLException { } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return null; } }; } }
2.建立一个与数据相关的实体类
package com.ming.user.entity; public class User { private int id; private String account; private int user_id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public int getUser_id() { return user_id; } public void setUser_id(int user_id) { this.user_id = user_id; } }
3.数据库操作类及测试方法
package com.ming.core.db; 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 com.ming.user.entity.User; public class QueryRunnerCRUDTest { /* *测试表 CREATE TABLE `users` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `account` VARCHAR(50) NULL DEFAULT NULL, `user_id` BIGINT(20) NOT NULL, PRIMARY KEY (`id`) ) COMMENT='user表' COLLATE='latin1_swedish_ci' ENGINE=InnoDB ; */ public void add() throws SQLException { //将数据源传递给QueryRunner,QueryRunner内部通过数据源获取数据库连接 QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "INSERT INTO `test`.`users` (`account`, `user_id`) VALUES (?, ?);"; Object params[] = {"hello world",2323}; qr.update(sql, params); } public void delete() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "delete from users where id=?"; qr.update(sql, 1); } public void update() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "update users set account=? where id=?"; Object params[] = { "ddd", 2}; qr.update(sql, params); } public void find() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users where id=?"; Object params[] = {2}; User user = (User) qr.query(sql, params, new BeanHandler(User.class)); System.out.println(user.getId()); } public void getAll() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; List<User> list = (List<User>) qr.query(sql, new BeanListHandler(User.class)); for(User u : list){ System.out.println(u.getUser_id()); } } public void testBatch() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "INSERT INTO `test`.`users` (`account`, `user_id`) VALUES (?, ?)"; Object params[][] = new Object[10][]; for (int i = 0; i < 10; i++) { params[i] = new Object[] {"123"+i, i}; } qr.batch(sql, params); } public static void main(String[] args) throws Exception { QueryRunnerCRUDTest t=new QueryRunnerCRUDTest(); t.add(); t.find(); t.delete(); } }
以上代码都测试通了。