【设计】设计一个web版的数据库管理平台后端(之二)

发布于:2025-07-28 ⋅ 阅读:(11) ⋅ 点赞:(0)

在之前,我写过一篇【设计】设计一个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;
    }

    @Override
    public 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);
        }
    }

    @Override
    public 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();
    }

    @Override
    public 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 {
    @Override
    public 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);
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到