2011-04-12 6 views
6

나는 안드로이드에서 Sqlite를 사용하고 있으며 다음과 같은 것을 사용하는 데이터베이스로부터 값을 얻고있다.안드로이드 : 내 자신의 커서 클래스를 만드는 방법?

Cursor cursor = sqliteDatabase.rawQuery("select title,category from table", null); 

int columnIndexTitle = cursor.getColumnIndex("title"); 
iny columnIndexCategory = cursor.getColumnIndex("category"); 

cursor.moveToFirst(); 
while (cursor.moveToNext()) { 
    String title = cursor.getString(columnIndexTitle); 
    String category = cursor.getString(columnIndexCategory);  
} 
cursor.close(); 

하나의 방법으로 getColumnIndex()getString()를 할 수 있도록 내 자신의 커서를 만들고 싶다.

String title = cursor.getString("title"); 

sqliteDatabase.rawQuery에서 가져온 커서를 확장하는 클래스를 만들고 싶습니다. 그러나이를 수행하는 방법을 모르겠습니다. SQLiteCursor를 확장해야합니까, 아니면 어떻게해야합니까? 그것도 가능하고 좋은 생각입니까?

+0

여러 행이 있습니까? 자신의 getString을 작성하면 getColumnIndex 대신 각 호출에 대해 맵 찾아보기가 발생합니다. – idbrii

+0

이 댓글 주셔서 감사합니다! 나는 이것이 왜 좋은 생각이 아닌지 지금 본다. – Martin

답변

0

쉽게 값을 검색하기 위해 안드로이드 SDK에 이미있는 DatabaseUtils .stringForQuery() 정적 메소드의 사용을해야입니다 db에 대해 쿼리를 실행하고 첫 번째 행의 첫 번째 열에 값을 반환합니다.

뭔가

같은
String myString=DatabaseUtils.stringForQuery(getDB(),query,selectionArgs); 
나는 그것을 확장 할 것
+0

오, 미안, 내가 필요로하는 것이 아니었다. 내 예제는 조금 단순했을 수도 있고, 내가 원하는 것을 보여주기위한 코드를 추가했다. – Martin

2

, 나는 도우미 만들어 주겠다고 :

class MartinCursor { 
    private Cursor cursor; 

    MartinCursor(Cursor cursor) { 
     this.cursor = cursor; 
    } 

    String getString(String column) { 
     .... 
    } 
} 

또는

개인적으로
class MartinCursorHelper { 
    static String getString(Cursor cursor, String column) { 
     .... 
    } 
} 

, 나는 후자를 할 거라고를 , 당신이이 여분의 주장을 항상 제공하는 것을 싫어하지 않는다면.

EDIT : pydave의 중요한 점을 언급하는 것을 잊었습니다. 루프에서 이것을 호출하면 성능에 큰 영향을 미치게됩니다. 선호되는 방법은 색인을 한 번 찾아 캐시하고 대신 사용하는 것입니다.

+0

감사합니다. 이것은 효과가있는 해결책처럼 보입니다. 그러나 대신 헬퍼를 사용하지 않고 그것을 확장 할 수 있습니까? – Martin

+0

오브젝트가 사용자가 아닌 운영 체제에 의해 인스턴스화되었으므로 실제로 서브 클래스 화 된 커서를 다른 클래스의 커서로 작성할 수 없습니다. – EboMike

0

다른 솔루션을 찾으면서이 문제가 발생했으나 답변이 만족스럽지 않다고 생각하므로이 내용을 추가하고 싶습니다.

자신 만의 커서 클래스를 쉽게 만들 수 있습니다. Cursor가 필요한 기능을 허용하려면 AbstractCursor를 확장해야합니다. 클래스를 사용하지 않는 시스템의 문제를 해결하려면 클래스를 래퍼로 만들기 만하면됩니다.

여기에 정말 좋은 예가 있습니다. 그것이 작동하는 방법의 일반적인 생각이다 https://android.googlesource.com/platform/packages/apps/Contacts/+/8df53636fe956713cc3c13d9051aeb1982074286/src/com/android/contacts/calllog/ExtendedCursor.java

public class ExtendedCursor extends AbstractCursor { 
/** The cursor to wrap. */ 
private final Cursor mCursor; 
/** The name of the additional column. */ 
private final String mColumnName; 
/** The value to be assigned to the additional column. */ 
private final Object mValue; 
/** 
* Creates a new cursor which extends the given cursor by adding a column with a constant value. 
* 
* @param cursor the cursor to extend 
* @param columnName the name of the additional column 
* @param value the value to be assigned to the additional column 
*/ 
public ExtendedCursor(Cursor cursor, String columnName, Object value) { 
    mCursor = cursor; 
    mColumnName = columnName; 
    mValue = value; 
} 
@Override 
public int getCount() { 
    return mCursor.getCount(); 
} 
@Override 
public String[] getColumnNames() { 
    String[] columnNames = mCursor.getColumnNames(); 
    int length = columnNames.length; 
    String[] extendedColumnNames = new String[length + 1]; 
    System.arraycopy(columnNames, 0, extendedColumnNames, 0, length); 
    extendedColumnNames[length] = mColumnName; 
    return extendedColumnNames; 
} 

.

이제 문제의 고기에. 성능 저하를 방지하려면 열 인덱스를 보유 할 해시를 만듭니다. 이것은 캐시 역할을합니다. getString이 불려 가면 (자), 열 인덱스의 해시를 조사합니다. 존재하지 않으면 getColumnIndex를 사용하여 가져 와서 캐시하십시오.

죄송합니다. 현재 코드를 추가 할 수 없지만 모바일 용이므로 나중에 추가하겠습니다.

4

SQLiteDatabase과 함께 사용하는 맞춤 Cursor을 만드는 가장 좋은 방법을 찾으면서이 질문을 발견했습니다. 제 경우에는 추가 정보를 전달하기 위해 Cursor에 대한 추가 속성이 필요했기 때문에 사용 사례가 질문의 본문과 정확하게 일치하지 않습니다. 내 발견을 게시하면 도움이 될 것입니다.

나를 괴롭히는 부분은 SQLiteDatabase 쿼리 메서드가 Cursor를 반환하고 Cursor에 사용자 지정 하위 클래스를 전달해야한다는 것이 었습니다.

Android API에서 해결책을 찾았습니다 : CursorWrapper 클래스를 사용하십시오. 그것은 이것을 위해 정확하게 설계된 것 같습니다.

클래스 :

public class MyCustomCursor extends CursorWrapper { 

    public MyCustomCursor(Cursor cursor) { 
     super(cursor); 
    } 

    private int myAddedAttribute; 

    public int getMyAddedAttribute() { 
     return myAddedAttribute; 
    } 

    public void setMyAddedAttribute(int myAddedAttribute) { 
     this.myAddedAttribute = myAddedAttribute; 
    } 

} 

사용법 :

public MyCustomCursor getCursor(...) { 
    SQLiteDatabase DB = ...; 
    Cursor rawCursor = DB.query(...); 
    MyCustomCursor myCursor = new MyCustomCursor(rawCursor); 
    myCursor.setMyAddedAttribute(...); 
    return myCursor; 
} 
관련 문제