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(); } }
以上代碼都測試通了。