JDBC浅层封装
在我16年的博客中,写过"JavaEE中的MVC"系列的文章,解析了系统各个部分的基本设计,属于大学时期的作品了,原本想写在毕业设计上,不过老师们看不懂,算是大学的遗憾吧。
在不断地设计就发现,DAO的封装,几乎只会朝着这3个方向发展,一种是MyBatis这样,基于模版引擎,或者类似模版引擎的;另一种就是像Hibernate,把数据映射发挥到极致;或者像Beetl,二者兼有。
自己设计的价值基本没有,但是,这个过程,有利于加深对框架的理解。
这是最基本的封装,简单、有效,如果使用Sqlite数据库的话,会非常有用,SessionFactory可以按需求加入连接池的使用。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; /** * "org.sqlite.JDBC" * "com.mysql.jdbc.driver" * * @author 41320 * @date 2017年4月7日,21:28:33 */ public class SessionFactory { final static Logger log = LoggerFactory.getLogger(SessionFactory.class); private static String sUrl = null; public void build(String driver, String url) throws IOException { try{ Class.forName(driver); SessionFactory.sUrl = url; } catch(Exception e){ throw new IOException("无法建立数据库连接:" + url, e); } } public static Connection getConnection(){ try { return DriverManager.getConnection(sUrl); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } }
import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 作为Connection的一个包装类,提取了JDBC中常用的方法,简化数据库的操作难度, * 依托于SessionFactory,可以单独作为工具类使用,或者作为EasyDao的基类使用 * * @author 41320 * @date 2017年4月7日,21:28:33 */ public class Session implements AutoCloseable { private Connection conn; /** * 执行一条Sql语句,包括Insert、Delete、Update * @param sql * @param params * @return */ public int executeUpdate(String sql, Object... params) { try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { setParams(preparedStatement, params); return preparedStatement.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); return 0; } } /** * 执行一条带参数查询语句,通过回调函数处理结果 * @param parser * @param sql * @param params * @param <T> * @return */ public <T> T queryOne(ResultSetParser<T> parser, String sql, Object... params) { try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { setParams(preparedStatement, params); try (ResultSet resultSet = preparedStatement.executeQuery()) { resultSet.next(); return parser.parse(resultSet); } } catch (SQLException e) { e.printStackTrace(); return null; } } /** * 执行一条带参数查询语句,通过回调函数处理结果 * * @param sql * @param params * @return Object * @throws SQLException */ public Map<String, Object> queryAsMap(String sql, Object... params) { try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { setParams(preparedStatement, params); try (ResultSet resultSet = preparedStatement.executeQuery()) { ResultSetMetaData metaData = resultSet.getMetaData(); int cols = metaData.getColumnCount(); resultSet.next(); Map<String, Object> map = new HashMap<>(cols); for (int i = 0; i < cols; i++) { String key = metaData.getColumnName(i + 1); Object value = resultSet.getObject(i + 1); map.put(key.toUpperCase(), value); } return map; } } catch (SQLException e) { e.printStackTrace(); return null; } } /** * 执行一条带参数查询语句,通过回调函数处理结果 * * @param parser * @param sql * @param params * @return Object */ public <T> List<T> queryList(ResultSetParser<T> parser, String sql, Object... params) { try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { setParams(preparedStatement, params); try (ResultSet resultSet = preparedStatement.executeQuery()) { List<T> retList = new ArrayList<T>(); while (resultSet.next()) { retList.add(parser.parse(resultSet)); } return retList; } } catch (SQLException e) { e.printStackTrace(); return null; } } /** * 执行一条带参数查询语句,通过回调函数处理结果 * * @param sql * @param params * @return Object */ public List<Map<String, Object>> queryAsListMap(String sql, Object... params) { try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { setParams(preparedStatement, params); try (ResultSet resultSet = preparedStatement.executeQuery()) { ResultSetMetaData metaData = resultSet.getMetaData(); int cols = metaData.getColumnCount(); List<Map<String, Object>> res = new ArrayList<>(); while (resultSet.next()) { Map<String, Object> map = new HashMap<>(cols); for (int i = 0; i < cols; i++) { String key = metaData.getColumnName(i + 1); Object value = resultSet.getObject(i + 1); map.put(key.toUpperCase(), value); } res.add(map); } return res; } } catch (SQLException e) { e.printStackTrace(); return null; } } public int queryCount(String sql, Object... params) { try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) { setParams(preparedStatement, params); try (ResultSet resultSet = preparedStatement.executeQuery()) { resultSet.next(); return resultSet.getInt(1); } } catch (SQLException e) { e.printStackTrace(); return 0; } } private int queryCntBySql(String sql, Object... params) { int idx = sql.indexOf(" from "); if (idx < 0) { sql = sql.toLowerCase(); idx = sql.indexOf(" from "); } String cntSql = "select count(*) " + sql.substring(idx); return queryCount(cntSql, params); } public <T> Page queryPage(ResultSetParser<T> parser, String sql, Object... params) { Page page = new Page(); page.list = this.queryList(parser, sql, params); page.total = queryCntBySql(sql, params); return page; } public Page queryPage(String sql, Object... params) { Page page = new Page(); page.list = this.queryAsListMap(sql, params); page.total = queryCntBySql(sql, params); return page; } /** * 执行插入操作 * * @param sql - * @param args - * @return 自增的ID */ public Integer insert(String sql, Object... args) { try (PreparedStatement ps = conn.prepareStatement(sql)) { setParams(ps, args); ps.executeUpdate(); try (ResultSet rs = ps.getGeneratedKeys()) { if (rs != null) { return rs.getInt(1); } } } catch (SQLException e) { e.printStackTrace(); } return null; } public void beginTrancation(String methodName) { try { conn.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } /** * 提交事务,关闭连接,并且清除引用 */ public void commit() { try { conn.commit(); } catch (SQLException e) { e.printStackTrace(); } } /** * 事务回滚 */ public void rollback() { try { conn.rollback(); } catch (SQLException e) { e.printStackTrace(); } } /** * 关闭并清除引用 */ @Override public void close() { try { if (conn != null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * PreparedStatement参数注入 * @param pstmt * @param params * @throws SQLException */ private void setParams(PreparedStatement pstmt, Object... params) throws SQLException { if (params != null) { for (int i = 0; i < params.length; i++) { pstmt.setObject(i + 1, params[i]); } } } /** * 结果集处理回调 */ @FunctionalInterface public interface ResultSetParser<T> { T parse(ResultSet rs); } /** * 分页,按需调整 */ public class Page { public int total; public List<?> list; } }
2016
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY