You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何改造DbUtils的executeQuery方法支持带?参数的动态查询

DbUtils类executeQuery方法改造方案(支持带占位符的动态SQL)

核心改造思路

基于原有的无参数查询方法,新增重载方法支持带?占位符的动态SQL,通过Map<Integer, Object>传递参数位置与对应值(key为占位符的位置索引,从1开始;value为参数值,支持String、Integer等任意JDBC兼容类型),利用JDBC的PreparedStatement.setObject()自动适配参数类型,简化多类型参数的处理逻辑。

改造后完整代码示例

假设原DbUtils类已有getConnection()方法用于获取数据库连接,以下是改造后的实现:

import java.sql.*;
import java.util.*;

public class DbUtils {

    // 原有无参数查询方法(保留)
    public List<Map<String, Object>> executeQuery(String sql) throws SQLException {
        return executeQuery(sql, null);
    }

    // 新增支持带参数的查询方法
    public List<Map<String, Object>> executeQuery(String sql, Map<Integer, Object> params) throws SQLException {
        // 使用try-with-resources自动关闭资源,避免手动关闭遗漏
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            // 设置占位符参数
            if (params != null && !params.isEmpty()) {
                for (Map.Entry<Integer, Object> entry : params.entrySet()) {
                    int paramIndex = entry.getKey();
                    Object paramValue = entry.getValue();
                    // setObject自动适配参数类型,JDBC驱动会处理String、Integer、Long等常见类型
                    pstmt.setObject(paramIndex, paramValue);
                }
            }

            // 执行查询并处理结果集
            try (ResultSet rs = pstmt.executeQuery()) {
                return convertResultSetToList(rs);
            }
        }
    }

    // 通用结果集转换方法:把ResultSet转为List<Map>
    private List<Map<String, Object>> convertResultSetToList(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> rowMap = new HashMap<>();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i);
                rowMap.put(columnName, rs.getObject(i));
            }
            resultList.add(rowMap);
        }
        return resultList;
    }

    // 假设已有获取数据库连接的方法(根据实际场景实现)
    private Connection getConnection() throws SQLException {
        // 示例:加载驱动并获取连接,实际需替换为你的数据库配置
        Class.forName("com.mysql.cj.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");
    }
}

使用示例

单个参数场景

查询ID大于100的商品:

String sql = "select id,description,quantity from products where id>?";
Map<Integer, Object> params = new HashMap<>();
params.put(1, 100); // 第一个占位符(索引1)的值为Integer类型的100

DbUtils dbUtils = new DbUtils();
List<Map<String, Object>> products = dbUtils.executeQuery(sql, params);

多个参数场景

查询ID大于100且库存小于50的商品:

String sql = "select * from products where id>? and quantity<?";
Map<Integer, Object> params = new HashMap<>();
params.put(1, 100);
params.put(2, 50);

List<Map<String, Object>> products = dbUtils.executeQuery(sql, params);

关键细节说明

  1. 参数索引规则:JDBC中PreparedStatement的占位符索引从1开始,而非0,所以Map的key必须对应正确的位置。
  2. 自动类型适配:setObject()方法会根据参数的实际类型,自动映射为对应的SQL类型(如Integer对应INT,String对应VARCHAR等),无需手动判断类型调用setString()、setInt()等方法,简化代码。
  3. 资源安全:使用try-with-resources语法,自动关闭Connection、PreparedStatement、ResultSet,避免数据库资源泄漏。
  4. 兼容原有逻辑:保留原无参数方法,通过重载实现扩展,不影响原有代码的使用。

可选优化:支持可变参数传参

如果觉得Map传递参数不够直观,可再新增一个支持可变参数的重载方法,按占位符顺序传递参数:

public List<Map<String, Object>> executeQuery(String sql, Object... params) throws SQLException {
    try (Connection conn = getConnection();
         PreparedStatement pstmt = conn.prepareStatement(sql)) {

        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
        }

        try (ResultSet rs = pstmt.executeQuery()) {
            return convertResultSetToList(rs);
        }
    }
}

调用时更简洁:

List<Map<String, Object>> products = dbUtils.executeQuery(sql, 100, 50);

内容的提问来源于stack exchange,提问作者Alberto Manuguerra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:05:21