为数据库类创建通用的“ getColumn”方法(Java)

时间:2018-11-27 04:44:49

标签: java database generics parameters

我有一个数据库类,其中封装了java.sql.*类的功能。基本上,您可以将其子类化以创建到特定数据库的连接,然后可以使用其方法执行常见操作。

我要实现的一种操作是getColumn()方法。如果预期的数据库列是String数据类型,则可以执行以下操作:

public List<String> getColumn(String sql) throws SQLException
{
    List<String> results = new ArrayList<>();
    ResultSet rs = _stmt.executeQuery(sql);
    while (rs.next())
    {
        results.add(rs.getString(1));
    }
    return results;
}

但是我想使用模板参数来泛化此方法,并使用适当的ResultSet.get*方法填充ArrayList

类似这样的东西:

public <T> List<T> getColumn(String sql) throws SQLException
{
    List<T> results = new ArrayList<>();
    ResultSet rs = _stmt.executeQuery(sql);
    while (rs.next())
    {
        // if T is String, do:
        // results.add(rs.getString(1));
        // if T is Integer, do:
        // results.add(rs.getInt(1));
        // etc.
    }
    return results;

我确信必须有一种优雅的方法来做到这一点。有什么想法吗?我会以错误的方式处理吗?     }

2 个答案:

答案 0 :(得分:1)

这是一种方法,

public <T> List<T> getColumn(String sql) throws SQLException {
    List<T> results = new ArrayList<>();
    ResultSet rs = _stmt.executeQuery(sql);
    while (rs.next()) {
        @SuppressWarnings("unchecked")
        final T colVal = (T) rs.getObject(1);
        results.add(colVal);
    }
    return results;
}

答案 1 :(得分:1)

一个常见的错误是尝试使用签名如下的方法:

<T> T fn()

在Java中,无法在fn的调用中找出什么T。选项包括返回null,不安全地强制转换可能为T的对象或引发异常。如果您有类似的东西,但是返回类型为List<T>,那么您可以存储在该列表中的唯一内容就是null

那该怎么办。通常,您将传入一个参数以创建所需的类型。例如,一个功能对象。 (我会使用java.util.function.Function,但检查的异常会妨碍您。)

List<String> names = getColumn(
    "SELECT [...]",
    (result, column) -> result.getString(column)
);
[...]

interface ResultFunction<T> {
    T get(ResultSet results, int column) throws SQLException;
}

public <T> List<T> getColumn(
    String sql, ResultFunction<T> function
) throws SQLException {
    List<T> values = new ArrayList<>();
    try (ResultSet result = _stmt.executeQuery(sql)) {
        while (result.next()) {
            values.add(function.get(result, 1));
        }
    }
    return values;
}

您可能想扩展ResultFunction的功能并可能使用枚举。