在之前,我写过一篇【设计】设计一个web版的数据库管理平台后端精要 的文章,文章讲了一个web版数据库管理平台的实现思路及主要代码。
最近,我看了下Mybatis的源码,觉得Mybatis的分层架构挺好,所以想到了完善下web版数据库管理平台中,关于sql查询的功能。

在上期文章中,关于sql的执行,代码是最简单的

// 执行SQL
jdbcTemplate.execute(sql);

对于sql查询功能来说,这是远远不够的,sql查询需要查询出数据库中的结果,并显示在网页上。这里我们比Mybatis简单,我们不需要实现结果与java类型的映射,只是显示出来就好。

网上有个图片(原图地址,如有侵权,请联系我),很好的反应了我即将要做的事情
在这里插入图片描述

方案

也就是说,我要将原来直接执行sql的方式进行解耦,改为调用SQL执行器去执行。
参考Mybatis,我们添加了

SqlSession│├── Configuration (配置中心)│└── Executor (执行器)│├── StatementHandler (语句处理器)│└── ResultSetHandler (结果集处理器)

以下是本次完善的类图。
在这里插入图片描述

类图说明:

  1. 核心类关系:
  • SqlSession 是入口类,包含Configuration和Executor
  • Executor 接口定义了执行SQL的核心方法
  • SimpleExecutor 是基础实现,使用StatementHandler执行SQL
  1. 执行流程相关类:
  • StatementHandler 负责SQL语句准备和执行
  • SimpleStatementHandler 是基础实现,使用PreparedStatement
  • ResultSetHandler 负责结果集处理
  • MapResultSetHandler 将ResultSet转为List
  1. 配置类:
  • Configuration 持有数据源等配置信息
  1. 依赖关系:
  • 实线箭头表示组合关系(强拥有)
  • 虚线箭头表示依赖关系(临时使用)
  • 空心三角箭头表示接口实现

详细设计

Configuration 配置类

public class Configuration {private DataSource dataSource;private boolean cacheEnabled = false;// 其他配置项...public Configuration(DataSource dataSource) {this.dataSource = dataSource;}// getters and setters...
}

SqlSession 实现

public class SqlSession {private final Configuration configuration;private final Executor executor;public SqlSession(Configuration configuration) {this.configuration = configuration;this.executor = new SimpleExecutor(configuration);}public List<Map<String, Object>> selectList(String sql, Object... parameters) {return executor.query(sql, parameters);}public void close() {executor.close();}
}

Executor 执行器

public interface Executor {List<Map<String, Object>> query(String sql, Object... parameters);void close();
}public class SimpleExecutor implements Executor {private final Configuration configuration;private Connection connection;public SimpleExecutor(Configuration configuration) {this.configuration = configuration;}@Overridepublic List<Map<String, Object>> query(String sql, Object... parameters) {try {StatementHandler statementHandler = new SimpleStatementHandler(configuration);return statementHandler.query(sql, parameters);} catch (SQLException e) {throw new RuntimeException("Error executing query: " + sql, e);}}@Overridepublic void close() {if (connection != null) {try {connection.close();} catch (SQLException e) {// ignore}}}
}

StatementHandler 语句处理器

public interface StatementHandler {List<Map<String, Object>> query(String sql, Object... parameters) throws SQLException;
}public class SimpleStatementHandler implements StatementHandler {private final Configuration configuration;private final ResultSetHandler resultSetHandler;public SimpleStatementHandler(Configuration configuration) {this.configuration = configuration;this.resultSetHandler = new MapResultSetHandler();}@Overridepublic List<Map<String, Object>> query(String sql, Object... parameters) throws SQLException {Connection connection = null;PreparedStatement stmt = null;ResultSet rs = null;try {connection = configuration.getDataSource().getConnection();stmt = connection.prepareStatement(sql);// 设置参数for (int i = 0; i < parameters.length; i++) {stmt.setObject(i + 1, parameters[i]);}rs = stmt.executeQuery();return resultSetHandler.handleResultSets(rs);} finally {if (rs != null) {try {rs.close();} catch (SQLException e) {// ignore}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {// ignore}}if (connection != null) {try {connection.close();} catch (SQLException e) {// ignore}}}}
}

ResultSetHandler 结果集处理器

public interface ResultSetHandler {List<Map<String, Object>> handleResultSets(ResultSet rs) throws SQLException;
}public class MapResultSetHandler implements ResultSetHandler {@Overridepublic List<Map<String, Object>> handleResultSets(ResultSet rs) throws SQLException {List<Map<String, Object>> resultList = new ArrayList<>();ResultSetMetaData metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();while (rs.next()) {Map<String, Object> row = new LinkedHashMap<>();for (int i = 1; i <= columnCount; i++) {String columnName = metaData.getColumnLabel(i);if (columnName == null || columnName.isEmpty()) {columnName = metaData.getColumnName(i);}row.put(columnName, rs.getObject(i));}resultList.add(row);}return resultList;}
}

使用示例

// 初始化配置
DataSource dataSource = ... // 创建数据源
Configuration configuration = new Configuration(dataSource);// 创建SqlSession
try (SqlSession sqlSession = new SqlSession(configuration)) {// 执行查询List<Map<String, Object>> result = sqlSession.selectList("SELECT * FROM users WHERE age > ?", 18);// 处理结果for (Map<String, Object> row : result) {System.out.println(row);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90758.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90758.shtml
英文地址,请注明出处:http://en.pswp.cn/web/90758.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Visual tudio 各版本下 C++ 开发的核心区别与实践指南

C语言的发展经历了数十年的演进&#xff0c;从 C98 到现代的 C20/23&#xff0c;语言本身发生了巨大的变革。与此同时&#xff0c;Visual Studio 作为主流的 C 开发环境之一&#xff0c;其编译器对各个 C 标准的支持程度也随版本不断演进&#xff0c;直接影响着开发者的编程方式…

怎样让阿里云服务器(centos)有界面

要让阿里云服务器 CentOS 有图形界面&#xff0c;可以按照以下步骤进行操作&#xff1a;登录服务器&#xff1a;使用 SSH 客户端工具&#xff0c;通过 IP 地址和账号登录到阿里云服务器。更新系统软件源&#xff1a;输入命令sudo yum update&#xff0c;更新系统软件源&#xf…

Qt 异步编程模式与应用

在现代软件开发中&#xff0c;异步编程已成为提升应用性能和响应性的关键技术。Qt 作为一个强大的跨平台框架&#xff0c;提供了多种异步编程模式&#xff0c;包括信号槽机制、事件循环、线程池、异步 I/O 等。本文将深入探讨 Qt 异步编程的各种模式及其应用场景&#xff0c;帮…

面试150 数字范围按位与

思路 只要 left < right&#xff0c;说明两者在某些低位上存在不同&#xff0c;为了找到它们的公共前缀&#xff08;高位相同部分&#xff09;&#xff0c;不断将 left 和 right 同时右移&#xff08;即除以2&#xff09;&#xff0c;直到它们相等&#xff0c;记录右移的次数…

数据库HB OB mysql ck startrocks, ES存储特点,以及应用场景

这些数据库和存储引擎主要有:HB(HBase)、OB(OceanBase)、MySQL、ClickHouse(CK)、StarRocks、Elasticsearch(ES),下面分别介绍它们的存储特点以及典型应用场景。 1. HBase (HB) 存储特点 分布式、面向列的NoSQL数据库 采用HDFS存储,数据以表、row key、列族、时间戳…

Java技术栈/面试题合集(17)-Git篇

场景 Java入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享: Java入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享_java高级进阶-CSDN博客 通过对面试题进行系统的复习可以对Java体系的知识点进行查漏补缺。…

破局与重构:King’s LIMS 引领电子行业实验室智能化转型

在全球化高新技术竞争白热化背景下&#xff0c;电子行业正经历从规模导向扩张向质量效益跃升的战略转型。终端用户对产品性能的极致化追求、行业质量合规标准的持续迭代升级&#xff0c;以及检测数据的指数级增长&#xff0c;共同形成"需求牵引供给、供给创造需求"的…

暑期算法训练.9

目录 43 .力扣75 颜色分类 43.1 题目解析&#xff1a; 43.2 算法思路&#xff1a; 43.3 代码演示&#xff1a; 43.4 总结反思&#xff1a; 44. 力扣 912 排序数组 44.1 题目解析&#xff1a; 44.2 算法思路&#xff1a; 44.3 代码演示&#xff1a; ​编辑 44.4 总结反…

2.安装CUDA详细步骤(含安装截图)

2.安装CUDA 第一步&#xff1a;安装anaconda 注意&#xff1a;安装CUDA之前需要安装好anaconda&#xff0c;详见安装anaconda详细步骤&#xff08;含安装截图&#xff09; 文章目录2.安装CUDA2.0 CUDA是什么&#xff0c;为什么要安装它&#xff1f;2.1 验证计算机是否安装CUDA2…

Triton IR

Triton IR语法 Triton IR的语句遵从MLIR Dialect的语法定义规范&#xff0c;示例如下&#xff1a; %3 tt.splat %1 : i32 -> tensor<1024xi32> loc(#loc5) 其中&#xff1a; %0&#xff1a;右边expression的结果值的名字&#xff08;Value的name&#xff09; tt…

掌握JavaScript函数封装与作用域

JavaScript 基础 - 第4天笔记理解封装的意义&#xff0c;能够通过函数的声明实现逻辑的封装&#xff0c;知道对象数据类型的特征&#xff0c;结合数学对象实现简单计算功能。理解函数的封装的特征掌握函数声明的语法理解什么是函数的返回值知道并能使用常见的内置函数函数理解函…

Datawhale AI 夏令营—科大讯飞AI大赛(大模型技术)—让大模型理解表格数据(列车信息表)

目录 一、本次赛事目标&#xff1a;让大模型理解表格数据&#xff08;列车信息表&#xff09; 二、分析赛题、对问题进行建模 赛事背景 赛题解读 数据分析与探索 赛题要点与难点 解题思考过程 三、Baseline方案 Baseline概况 Baseline运行步骤 Baseline文件概况 Ba…

SSH连接失败排查与解决教程: Connection refused

前言 当使用云服务器&#xff08;如阿里云、腾讯云、AWS 等&#xff09;时&#xff0c;尝试在本地PC端使用图形化工具如 FinalShell、XShell可能会遇到 SSH 连接失败的问题。本文列举 SSH 连接失败的常见原因&#xff0c;并提供对应解决方案&#xff0c;帮助快速定位并解决问题…

性能优化:Vue 3 `v-memo` 指令详解

v-memo 是 Vue 3 提供的一个性能优化工具&#xff0c;能帮助开发者缓存模板内容&#xff0c;减少不必要的渲染开销。本文将介绍 v-memo 的引入版本、作用、使用方法和实现原理&#xff0c;并通过示例说明如何使用它。内容基于 Vue 3.5.18&#xff08;截至 2025 年 7 月的最新版…

标准库开发和寄存器开发的区别

1.标准库void GPIO_Toggle_INIT(void)//初始化GPIO {GPIO_InitTypeDef GPIO_InitStructure {0};//定义GPIO结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能GPIO时钟GPIO_InitStructure.GPIO_Pin GPIO_Pin_2;//GPIO引脚选择GPIO_InitStructure.GPIO_Mode …

在 WebSocket 中使用 @Autowired 时遇到空指针异常

背景&#xff1a;在websocket在有新的连接加入进来时&#xff0c;调用servier中的服务&#xff0c;使用 Autowired 注入的 Bean 竟然是 null&#xff01;这并非 Spring 的 Bug&#xff0c;而是对 WebSocket 生命周期管理理解不足导致的。了解这个问题&#xff0c;我们需要区分两…

MGER实验

一、实验拓扑图二、配置1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址R1侧为15.1.1.1&#xff0c;对应R5为15.1.1.2R2侧为25.1.1.2&#xff0c;对应R5为25.1.1.1R3侧为35.1.1.2&#xff0c;对应R5为35.1.1.1R4侧为45.1.1.2&#xff0c;对应R…

基于 XGBoost 与 SHAP 的医疗自动化办公与可视化系统(下)

— 登录接口 — @app.post(“/token”) def login(form_data: OAuth2PasswordRequestForm = Depends()): user = fake_users_db.get(form_data.username) if not user or form_data.password != user[“password”]: raise HTTPException(status_code=400, detail=“用户名或密…

python学智能算法(二十九)|SVM-拉格朗日函数求解中-KKT条件

引言 前序学习进程中&#xff0c;对拉格朗日函数执行了初步求导&#xff0c;并获得了简化后的拉格朗日函数极值计算式&#xff1a; L(w,b,α)∑i1mαi−12∑i,j1mαiαjyiyjxiTxjL(w,b,\alpha)\sum_{i1}^{m}\alpha_{i}-\frac{1}{2}\sum_{i,j1}^{m}\alpha_{i}\alpha_{j}y_{i}y_…

【AI论文】MiroMind-M1:通过情境感知多阶段策略优化实现数学推理的开源新进展

摘要&#xff1a;近期&#xff0c;大型语言模型已从流畅的文本生成发展至能在多个领域进行高级推理&#xff0c;由此催生了推理语言模型&#xff08;RLMs&#xff09;。在众多领域中&#xff0c;数学推理堪称代表性基准&#xff0c;因为它需要精确的多步骤逻辑与抽象推理能力&a…