架構探險(二):DBUtils簡單使用
阿新 • • 發佈:2018-11-29
繼續我們的冒險體驗,之前綜述了一些構建一個專案的大致流程,相信大家對於系統的框架已經瞭然於胸。 今天我們就來談一談,如何構建資料的橋樑。
這裡我們使用commons-dbutils 來簡單的封裝一個jdbc template, 幫助我們實現快速的CRUD. 廢話不多講直接上程式碼。
package org.foothold.learn2.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.foothold.learn2.util.PropsUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; /** * Created by Jaden.Gu on 2018/11/16. */ public class DatabaseHelper { private static final Logger logger = LoggerFactory.getLogger(DatabaseHelper.class); private static final QueryRunner QUERY_RUNNER = new QueryRunner(); private static final ThreadLocal<Connection> CONNECTION_HOLDER = new ThreadLocal<>(); private static final BasicDataSource basicDataSource; private static final String DRIVER; private static final String URL; private static final String USERNAME; private static final String PASSWORD; static { Properties properties = PropsUtil.loadProps("db.properties"); basicDataSource = new BasicDataSource(); DRIVER = properties.getProperty("jdbc.driver"); URL = properties.getProperty("jdbc.url"); USERNAME = properties.getProperty("jdbc.username"); PASSWORD = properties.getProperty("jdbc.password"); basicDataSource.setDriverClassName(DRIVER); basicDataSource.setUrl(URL); basicDataSource.setUsername(USERNAME); basicDataSource.setPassword(PASSWORD); // try { // Class.forName(DRIVER); // } catch (ClassNotFoundException ex) { // logger.error("DatabaseHelper ClassNotFoundException", ex); // } } public static Connection getConnection() { Connection conn = null; try { if(CONNECTION_HOLDER.get() == null) { // conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); conn = basicDataSource.getConnection(); CONNECTION_HOLDER.set(conn); } } catch (SQLException ex) { logger.error("getConnection", ex); } return CONNECTION_HOLDER.get(); } public static void closeConnection() { if(CONNECTION_HOLDER.get() != null) { try { CONNECTION_HOLDER.get().close(); } catch (SQLException ex) { logger.error("closeConnection", ex); } } } public static <T> List<T> queryEntityList(Class<T> entityClass, String sql, Object... params) { List<T> entityList = null; try { entityList = QUERY_RUNNER.query(getConnection(), sql, new BeanListHandler<T>(entityClass), params); }catch (SQLException ex) { logger.error("query entity list failure", ex); throw new RuntimeException(ex); } finally { closeConnection(); } return entityList; } public static <T> T queryEntity(Class<T> entityClass, String sql, Object... params) { T entity = null; try { Connection connection = getConnection(); entity = QUERY_RUNNER.query(connection, sql, new BeanHandler<T>(entityClass), params); } catch (SQLException ex) { logger.error("queryEntity sql exception", ex); throw new RuntimeException(ex); } finally { closeConnection(); } 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 ex) { logger.error("executeQuery sql exception", ex); throw new RuntimeException(ex); } finally { closeConnection(); } return result; } public static int executeUpdate(String sql, Object... params) { int rows = 0; try{ rows = QUERY_RUNNER.update(getConnection(), sql, params); } catch (SQLException ex) { logger.error("executeUpdate sql exception", ex); throw new RuntimeException(ex); } finally { closeConnection(); } return rows; } public static <T> boolean insertEntity(Class<T> entityClass, Map<String, Object> fieldMap) { if(fieldMap.isEmpty()) { logger.error("Can't insert entity : field is empty"); return false; } String sql = String.format("INSERT INTO %s", getTableName(entityClass)); StringBuilder columns = new StringBuilder("("); StringBuilder values = new StringBuilder("("); for(String column : fieldMap.keySet()) { columns.append(column).append(", "); values.append("?, "); } columns.replace(columns.lastIndexOf(", "), columns.length(), ")"); values.replace(values.lastIndexOf(", "), values.length(), ")"); sql += columns + " VALUES " + values; Object[] parmas = fieldMap.values().toArray(); return executeUpdate(sql, parmas) == 1; } public static <T> boolean updateEntity(Class<T> entityClass, Map<String, Object> fieldMap, long id) { if(fieldMap.isEmpty()) { logger.error("Can't update entity : field is empty"); return false; } String sql = "UPDATE " + getTableName(entityClass) + " SET "; StringBuilder columns = new StringBuilder(); for(String column : fieldMap.keySet()) { columns.append(String.format(" %s = ? ", column)); } sql += columns.substring(0, columns.length() -1) + " WHERE id = ? "; List<Object> paramList = new ArrayList<>(); paramList.addAll(fieldMap.values()); paramList.add(id); Object[] params = paramList.toArray(); return executeUpdate(sql, params) == 1; } public static <T> boolean deleteEntity(Class<T> entityClass, long id) { String sql = "DELETE FROM " + getTableName(entityClass) + " WHERE id = ?"; return executeUpdate(sql, id) == 1; } private static String getTableName(Class<?> entityClass) { return entityClass.getSimpleName().toLowerCase(); } }
在static 程式碼快裡,我們讀取了配置檔案,然後通過配置的資料庫驅動類,資料庫使用者名稱、密碼。初始化一個dpcp2 的資料來源,然後通過dpcp2資料庫連線池管理資料庫連線,這樣有助於減少頻繁建立資料庫所帶來的昂貴開銷。另外我們把從連線池中取到的連線放到了ThreadLocal中,實現了統一請求的連線複用。
若要使用dpcp2我們需要在pom.xml裡新增以下依賴:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency>
若想了解資料庫連線池可以點選下方連結:
https://www.cnblogs.com/aspirant/p/6747238.html