[英]Create a generic “getColumn” method for a database class (Java)
I have a Database class that encapsulates the functionality of java.sql.*
classes. 我有一个数据库类,其中封装了
java.sql.*
类的功能。 Basically you subclass it in order to create a connection to a particular database, and then you can use its methods to perform common operations. 基本上,您可以将其子类化以创建到特定数据库的连接,然后可以使用其方法执行常见操作。
One operation I'd like to implement is a getColumn()
method. 我要实现的一个操作是
getColumn()
方法。 If the expected database column is a String datatype, I could do the following: 如果期望的数据库列是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;
}
But I would like to genericize this method with a template parameter, and use the proper ResultSet.get*
method to populate the ArrayList
. 但是我想使用模板参数来泛化此方法,并使用适当的
ResultSet.get*
方法填充ArrayList
。
Something like this: 像这样:
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;
I'm sure there must be an elegant way to do this. 我相信必须有一种优雅的方法来做到这一点。 Thoughts?
思考? Am I going about this the wrong way?
我会以错误的方式处理吗? }
}
Here's one way of doing it, 这是一种方法,
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;
}
A common mistake is attempting a method with signature like: 一个常见的错误是尝试使用签名这样的方法:
<T> T fn()
In Java there is no way to find out within an invocation of fn
what T
. 在Java中,无法在
fn
的调用中找出T
The choices are return null
, unsafely cast an object that may or may not be a T
or throw an exception. 选择返回return
null
,不安全地强制转换可能是T
或可能不是T
的对象或引发异常。 If you have something similar but a return type of List<T>
the only thing you could store in that list is null
. 如果您有类似的东西,但是返回类型为
List<T>
则您可以存储在该列表中的唯一内容为null
。
So what to do. 那么该怎么办。 Typically you would pass in an argument to create the required type.
通常,您将传入一个参数以创建所需的类型。 A function object, for instance.
例如,一个功能对象。 (I would use
java.util.function.Function
, but checked exceptions get in the way.) (我将使用
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;
}
You may want to expand the functionality of ResultFunction
and perhaps use enums. 您可能要扩展
ResultFunction
的功能,并可能使用枚举。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.