集合网上各类资料,自己整理封装的一个JDBC工具类,用于关系型数据库的增删改查,默认使用druid连接池,分享下方便大家平时使用(转载请注明出处)
import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.sql.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * JdbcTemplateUtil 工具类(默认使用druid连接池) */ public class JdbcTemplateUtil<JdbcAbstractMapper> { public static void main(String[] args) throws IOException { System.out.println(JdbcTemplateUtil.getConnection()); /** * 查询 */ String sql = "select account_name ,password_new from test_user where id>?"; Object[] objArr = {1}; AbstractJdbcMapper abstractJdbcMapper = new AbstractJdbcMapper() { @Override public Object mappinng(ResultSet rs) throws Exception { // return defalutMapping(rs, null); // return defalutMapping(rs, UserBean.class); UserBean userBean = new UserBean(); userBean.setAccountName(rs.getString(1)); userBean.setPasswordNew(rs.getString(2)); return userBean; } }; // List<Map<String, Object>> list = JdbcTemplateUtil.getInstance().findAllInfo(sql, objArr, abstractJdbcMapper); // for (Map<String, Object> map : list) { // System.out.println(map); // } List<UserBean> list = JdbcTemplateUtil.getInstance().findAllInfo(sql, objArr, abstractJdbcMapper); for (UserBean userBean : list) { System.out.println(userBean); } // UserBean userBean = (UserBean) JdbcTemplateUtil.getInstance().findOneInfo(sql, objArr, abstractJdbcMapper); // System.out.println(userBean); /** * 更新 */ String sql0 = "insert into test_user ( account_name ,password_new) values(?,?)"; Object[] objArr0 = {"dafa", "fdasd"}; int id = JdbcTemplateUtil.getInstance().updateOne(sql0, objArr0, Boolean.TRUE); int record = JdbcTemplateUtil.getInstance().updateOne(sql0, objArr0, Boolean.FALSE); System.out.println("返回的主键ID=" + id + ",受影响条数为" + record); } /** * 单例模式 */ private static volatile JdbcTemplateUtil instance; private JdbcTemplateUtil() { } public static JdbcTemplateUtil getInstance() { if (instance == null) { synchronized (JdbcTemplateUtil.class) { if (instance == null) { instance = new JdbcTemplateUtil(); } } } return instance; } /** * 错误描述常量 */ public static final String ERROR_DB_DATASOURCE = "初始化数据库连接池异常"; public static final String ERROR_DB_CONNECTION = "数据库获取连接异常"; public static final String ERROR_DB_SQL = "数据库SQL执行异常"; public static final String ERROR_DB_CLOSE = "数据库关闭连接异常"; /** * druid连接池 */ private static DataSource druid; /** * 静态代码块 */ static { initDataSource(); } /** * 初始化连接池 */ public static void initDataSource() { try { Properties properties = getPropertiesByName("application.properties", "spring.datasource.*", "spring.datasource.type"); druid = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { throw new RuntimeException(ERROR_DB_DATASOURCE, e); } } /** * 读取配置文件指定开头的配置项 * * @param filePath * @param prefixName 前缀【例如选择所有配置* 选择前缀开头的配置spring.datasource.*】 * @param filterProperties 过滤掉的属性,逗号分隔 (为空或者空字符串时不过滤) key1,key2,key3 * @return * @throws IOException */ public static Properties getPropertiesByName(String filePath, String prefixName, String filterProperties) throws IOException { Properties properties = new Properties(); InputStream inputStream = JdbcTemplateUtil.class.getClassLoader().getResourceAsStream(filePath); properties.load(inputStream); if (filterProperties != null && filterProperties.trim().length() > 0) { String[] keys = filterProperties.split("\\,"); for (String key : keys) { properties.remove(key); } } prefixName = prefixName.substring(0, prefixName.length() - 1); //注意List遍历时不能直接remove删除,其中set在remove操作时set集合不能再有任何修改,否则hashcode发生改变,则不能remove成功 Iterator<String> iterator = properties.stringPropertyNames().iterator(); while (iterator.hasNext()) { String key = iterator.next(); String value = properties.getProperty(key); if (key.startsWith(prefixName)) { properties.remove(key); key = key.replace(prefixName, ""); properties.setProperty(key, value); } else { properties.remove(key); } } properties.list(System.out); return properties; } /** * 获取Connection * * @return */ public static Connection getConnection() { Connection connection = null; try { connection = druid.getConnection(); connection.setAutoCommit(false); connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); } catch (SQLException e) { throw new RuntimeException(ERROR_DB_CONNECTION, e); } return connection; } /** * 关闭资源 * * @param conn * @param stmt * @param rs */ public static void closeConnection(Connection conn, Statement stmt, ResultSet rs) { try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { throw new RuntimeException(ERROR_DB_CLOSE, e); } } /** * 封装更新(增、删、改)某条记录操作 * * @param sql * @param objArr * @return */ public int updateOne(String sql, Object[] objArr, boolean isReturnGeneratedKey) { // 初始化成员变量 int record = 0; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; // 注册并链接 con = getConnection(); try { con.setAutoCommit(false); // pstmt pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); if (objArr != null) { for (int i = 1; i <= objArr.length; i++) { pstmt.setObject(i, objArr[i - 1]); } } // 执行 record = pstmt.executeUpdate(); con.commit(); //是否返回主键 if (isReturnGeneratedKey) { rs = pstmt.getGeneratedKeys(); if (rs.next()) { record = rs.getInt(1); } } } catch (SQLException e) { throw new RuntimeException(ERROR_DB_SQL, e); } finally { closeConnection(con, pstmt, rs); } return record; } /** * 封装单条查询操作 * * @param sql * @param objArr * @param mapper * @return */ public Object findOneInfo(String sql, Object[] objArr, Object mapper) { // 初始化成员变量 Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; Object rsObject = null; // pstmt try { con = getConnection(); pstmt = con.prepareStatement(sql); if (objArr != null) { for (int i = 1; i <= objArr.length; i++) { pstmt.setObject(i, objArr[i - 1]); } } // 执行 rs = pstmt.executeQuery(); System.out.println(pstmt.toString()); if (rs.next()) { if (mapper instanceof Class) { Class clazz = (Class) mapper; rsObject = new AbstractJdbcMapper() { @Override public Object mappinng(ResultSet rs) throws Exception { return defalutMapping(rs, clazz); } }; } else if (mapper instanceof AbstractJdbcMapper) { AbstractJdbcMapper abstractJdbcMapper = (AbstractJdbcMapper) mapper; rsObject = abstractJdbcMapper.mappinng(rs); } else { throw new RuntimeException("Object mapper 参数必须为Class类或者实现AbstractJdbcMapper抽象类"); } } } catch (Exception e) { throw new RuntimeException(ERROR_DB_SQL, e); } finally { // 查询 closeConnection(con, pstmt, rs); } return rsObject; } /** * 封装查询多条操作 * * @param sql * @param objArr * @param mapper * @return */ public List<? extends Object> findAllInfo(String sql, Object[] objArr, Object mapper) { List<Object> list = new ArrayList<Object>(); // 初始化变量 Object rsObject = null; // Connection.createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。 Connection con = null; // PreparedStatement表示预编译的 SQL 语句的对象,Statement 对象的子接口 PreparedStatement pstmt = null; // ResultSet查询获得的数据表,next方法将光标移动到下一行对象(对应数据库表中的行),没有下一行时返回 false; ResultSet rs = null; try { // 注册并链接 con = getConnection(); // 创建PreparedStatement对象 pstmt = con.prepareStatement(sql); if (objArr != null) { for (int i = 1; i <= objArr.length; i++) { pstmt.setObject(i, objArr[i - 1]); } } // 执行 rs = pstmt.executeQuery(); System.out.println(pstmt.toString()); while (rs.next()) { if (mapper instanceof Class) { Class clazz = (Class) mapper; rsObject = new AbstractJdbcMapper() { @Override public Object mappinng(ResultSet rs) throws Exception { return defalutMapping(rs, clazz); } }; } else if (mapper instanceof AbstractJdbcMapper) { AbstractJdbcMapper abstractJdbcMapper = (AbstractJdbcMapper) mapper; rsObject = abstractJdbcMapper.mappinng(rs); } else { throw new RuntimeException("Object mapper 参数必须为Class类或者实现AbstractJdbcMapper抽象类"); } list.add(rsObject); } } catch (Exception e) { throw new RuntimeException(ERROR_DB_SQL, e); } finally { closeConnection(con, pstmt, rs); } return list; } } abstract class AbstractJdbcMapper { /** * 下划线和驼峰互转正则常量 */ public static final Pattern LINE_PATTERN = Pattern.compile("_(\\w)"); public static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]"); /** * 抽象方法———自定义ResultSet转Object * * @param rs * @return * @throws Exception */ public abstract Object mappinng(ResultSet rs) throws Exception; /** * 成员方法———默认ResultSet转Object * * @param rs * @param clazz * @return * @throws Exception */ public Object defalutMapping(ResultSet rs, Class clazz) throws Exception { return resultSet2Object(rs, clazz); } /** * ResultSet转Object * * @param rs * @param clazz * @return * @throws Exception */ private Object resultSet2Object(ResultSet rs, Class clazz) throws Exception { Map<String, Object> resultMap = new HashMap<>(16); //获取该行元数据 ResultSetMetaData metaData = rs.getMetaData(); //获取该行总列数(根据元数据和列数可以获得该列对应的字段名称) int columnCount = metaData.getColumnCount(); for (int i = 1; i <= columnCount; i++) { String lineKey = metaData.getColumnLabel(i); //下划线转驼峰 String humpKey = lineToHump(lineKey); resultMap.put(humpKey, rs.getString(i)); } if (clazz != null) { return map2Obj(resultMap, clazz); } else { return resultMap; } } /** * Map 转 Object * * @param map * @param clazz * @return * @throws Exception */ private Object map2Obj(Map<String, Object> map, Class<?> clazz) throws Exception { Object obj = clazz.newInstance(); Field[] declaredFields = obj.getClass().getDeclaredFields(); for (Field field : declaredFields) { int mod = field.getModifiers(); if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) { continue; } field.setAccessible(true); field.set(obj, map.get(field.getName())); } return obj; } /** * 下划线转驼峰 * * @param str * @return */ private String lineToHump(String str) { str = str.toLowerCase(); Matcher matcher = LINE_PATTERN.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, matcher.group(1).toUpperCase()); } matcher.appendTail(sb); return sb.toString(); } /** * 驼峰转下划线 * * @param str * @return */ private String humpToLine(String str) { Matcher matcher = HUMP_PATTERN.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase()); } matcher.appendTail(sb); return sb.toString(); } }
上述代码抽象类AbstractJdbcMapper 也可以修改为接口如下示范:
/* * 对象映射接口 Jdk1.8 * (1) 增加default方法。default方法作用范围也是public,只是有了具体实现的方法体。对已有的接口,如果想对接口增加一个新方法,那么需要对所有实现该接口的类进行修改。而有了default方法,可以解决该问题。 * (2) 新增static方法。static修饰的方法也是非抽象方法,使用同类的静态方法一样,给方法的调用带来了方便。程序入口main方法也是static,现在接口也可以运行了。 */ public interface JdbcMapper { /** * 将结果映射为一个Object对象,亦可创建一个空的实现调用默认方法 * * @param rs * @return */ Object mappinng(ResultSet rs); /** * 使用jdk1.8接口中的static方法或者default方法 */ static Map<String, Object> defaultMappinng(ResultSet rs) { try { Map<String, Object> resultMap = new HashMap<>(16); //获取该行元数据 ResultSetMetaData metaData = rs.getMetaData(); //获取该行总列数(根据元数据和列数可以获得该列对应的字段名称) int columnCount = metaData.getColumnCount(); for (int i = 1; i <= columnCount; i++) { String lineKey = metaData.getColumnLabel(i); //下划线转驼峰 String humpKey = LineToHumpTool.lineToHump(lineKey); resultMap.put(humpKey, rs.getString(i)); } } catch (Exception e) { throw new RuntimeException("ResultSet结果映射为Map<String,Object>对象失败:", e); } return null; } }
其中常用方法(如:Map转对象,下划线转驼峰,单例模式)摘自网友分享,其他部分为个人整理编写,代码不难,但整理比较费时,个人觉得还算比较全面,特给大家分享一下!
如果有错误的地方,还希望大家留言指出!
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
原文:https://www.cnblogs.com/Zyp168/p/11996933.html