我正在编写包装db SELECT语句的方法,它接收SQL查询并运行它。结果收集在Object[][]
中。数据库中的每个单元格都可以是Integer或String。
我有返回数组的问题。它是Object[][]
,所以我松散了类型。
public Object[][] select(String query) {
Object[][] result = new Object[cursor.getCount()][cursor.getColumnCount()];
Cursor cursor = db.rawQuery(query, null);
//Iterate over cursor (rows)
do {
//Iterate over columns (cells with data of different type)
for(int columnIndex = 0; columnIndex < cursor.getColumnCount(); columnIndex++) {
int type = cursor.getType(columnIndex);
//assume, that there are only two types - String or Integer (actualy there are 3 more types)
if(type == Cursor.FIELD_TYPE_INTEGER) {
result[cursor.getPosition()][columnIndex] = cursor.getInt(columnIndex);
}
else if(type == Cursor.FIELD_TYPE_STRING) {
result[cursor.getPosition()][columnIndex] = cursor.getString(columnIndex);
}
}
} while (cursor.moveToNext());
return result;
}
我不想放松类型。例如。希望能够做到这一点(伪代码):
//pseudocode:
result = select("SELECT age, name FROM people")
print( "Hello, " + result[0][0] + ". In ten years you'll be " )
print( result[0][0] + 10 )
//Prints: Hello, John. In ten years you'll be 56
每本关于Java的书都说,我不能有不同类型的数组。很清楚。
但我该如何从DB中保存所有这些Integers和Strings?我尝试使用Collections和Generics,但没有运气 - 对Java来说是新手。
还尝试使用某种Result值持有者:
private class Result {
private Class type;
private Object value;
...
public ??? get() { //??? - int or string - here I have some problems :)
return this.type.cast(this.value);
}
//do NOT want to have these:
public int getInt() { return (int) value; }
public int getString() { return (String) value; }
}
在这种情况下,方法select(...)
会返回Result[][]
。
回答自己: 明白了,我试图用Java编写代码。使用强类型我无法做出简单的方法,在没有显式转换的情况下返回所有类型。
毕竟我决定创建公共数据对象并将其填入选择中。
答案 0 :(得分:3)
为什么不创建一个包装你想要的东西的Result类并实例化它?
答案 1 :(得分:2)
我可能会做类似......
public final class Row {
private final Map<String, ?> columns;
protected Row(final Map<String, ?> columns) {
this.columns = columns;
}
public <T> T get(final String name) {
return (T) columns.get(name);
}
public <T> T get(final String name, final Class<T> type) {
return (T) columns.get(name);
}
}
public final Iterable<Row> select(final String query) {
final Cursor cursor = db.rawQuery(query, null);
final int numRow = cursor.getCount();
final int numCol = cursor.getColumnCount();
final Row[] rows = new Row[numRow];
for (int row = 0; row < numRow; ++row) {
final Map<String, Object> cols = new HashMap<String, Object>(numCol);
for (int col = 0; col < numCol; ++col) {
final String name = cursor.getColumnName(col);
final Object val = null;
final int type = cursor.getType(col);
switch (type) {
case Cursor.FIELD_TYPE_INTEGER:
val = cursor.getInt(col);
break;
case Cursor.FIELD_TYPE_STRING:
val = cursor.getString(col);
break;
...
}
map.put(name, val);
}
rows[row] = new Row(cols);
cursor.moveToNext();
}
return Arrays.asList(rows);
}
private final Row selectFirst(final String query) {
return select(query).iterator().next();
}
接下来......
final Row result = selectFirst("SELECT age, name FROM people");
print("Hello, " + result.get("name") + ". In ten years you'll be "
+ (result.<Integer>get("age") + 10)).
......或等同于:
final Row result = selectFirst("SELECT age, name FROM people");
final String name = result.get("name");
final int age = result.get("age");
print("Hello, " + name + ". In ten years you'll be " + (age + 10));
使用变量允许javac分别推断get
(String
和Integer
的类型参数。)
由于select
返回Iterable<Row>
,您可以在for
循环中使用它:
for (final Row row : select(...)) {
/* operate on the row */
}
注意我不确定这是否会在没有一两次调整的情况下进行编译。没有测试过,对不起 - 但是一般的想法应该。
答案 2 :(得分:1)
最好的方法可能是创建一个带有getter / setter的java bean,其中包含从数据库中获取的属性。例如,如果您正在获得员工
class Employee
{
int empID;
String empName;
public void setEmpID(String eID)
{
empID= eID;
}
public int getEmpID()
{
return eID;
}
.......
}
答案 3 :(得分:0)
将列名称或索引作为键返回地图列表,如下所示:
public List<Map<Integer,Result>> select(String query)
提取数据时,请执行以下操作:
List<Map<Integer,Result>> data = new ArrayList<Map<Integer,Result>>();
...
Map<String,Result> elem = new...
elem.put(columnIndex, new Result(..));
data.add(elem);
集合肯定比阵列更强大。
修改强>
使用您提供的Result
持有人类。
答案 4 :(得分:0)
使用Map<String,List<Result>>
Result类可以存储实际值及其类型
class Result {
Object value;
DataType type;
}
enum DataType {
String,
Integer
}