2012-08-08 59 views
0

我在寫包裝數據庫SELECT語句的方法,它接收SQL查詢並運行它。結果收集在Object[][]。數據庫中的每個單元格可能是整數或字符串。如何保存不同類型的集合?

我有返回數組的問題。這是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的書都說,我不能擁有不同類型的數組。很明顯。

但是我應該如何從數據庫中保存所有的整數和字符串?我試圖使用集合和泛型,但沒有運氣 - 新的Java。

還試圖用某種結果值持有者:

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中編寫代碼,就像我在php中所做的那樣。使用強類型時,我無法做出直接的方法,返回所有類型而不顯式投射。

畢竟我決定創建通用數據對象並將它們填充到選擇中。

回答

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持有人類。

+0

但是db單元值仍然是'Object'。 – Oroboros102 2012-08-08 19:24:34

+0

使用提供的結果更新瞭解決方案。 – davidmontoyago 2012-08-08 19:35:13

+0

我該如何處理'Result' getter?保持db結果,因爲'Object'不是問題。一個問題是不使用'if'或'result.getInt()'''result.getString()'來使用它。 – Oroboros102 2012-08-08 19:37:39

1

最好的方法可能是創建一個帶有getter/setter的java bean,其中的屬性將從數據庫中獲得。例如,如果你正在獲得員工

class Employee 
{ 
int empID; 
String empName; 

public void setEmpID(String eID) 
{ 
empID= eID; 
} 

public int getEmpID() 
{ 
return eID; 
} 
....... 
} 
3

爲什麼不創建一個Result類,它包裝任何你想要的並實例化它?

+0

如果你知道該怎麼做,最好和最清晰的答案。 – Maxim 2012-08-08 19:25:03

+0

如何在結果類中創建getter,該函數有時會返回int,othertime字符串? – Oroboros102 2012-08-08 19:26:05

+0

我會在幾分鐘內將我的Result類的代碼(已經嘗試過這種方法)添加到我的答案中。請看看它。 – Oroboros102 2012-08-08 19:27:10

0

使用Map<String,List<Result>>

結果類可以存儲的實際值和它的類型

class Result { 

    Object value; 
    DataType type; 

} 

enum DataType { 

    String, 
    Integer 

} 
+0

如何在此Result類中創建多用途getter?我試過'公共??? get(){return this.type.cast(this.value); '',但我應該把smthing而不是???。 – Oroboros102 2012-08-08 19:29:11

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推斷類型參數getStringInteger,分別地)。

由於select回報Iterable<Row>,您可以在for循環使用它:

for (final Row row : select(...)) { 
    /* operate on the row */ 
} 

注意那我不知道這是否會甚至沒有一個或兩個的調整編譯。沒有測試過,抱歉 - 但總的想法應該。

相關問題