2011-04-12 22 views
6

मैं Android में 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 बनाना केवल कॉल कॉलम इंडेक्स के बजाय प्रत्येक कॉल के लिए मानचित्र लुकअप का कारण बनता है। – idbrii

+0

इस टिप्पणी के लिए धन्यवाद! अब मैं देखता हूं कि यह एक अच्छा विचार क्यों नहीं है .. – Martin

उत्तर

3

अपना खुद का getString बनाना केवल कॉल कॉलम इंडेक्स के बजाय प्रत्येक कॉल के लिए मानचित्र लुकअप का कारण बन जाएगा।

यहां the code for SQLiteCursor.getColumnIndex और AbstractCursor.getColumnIndex है। यदि आपके पास कई पंक्तियां हैं, तो इस फ़ंक्शन पर कॉल को कम करने से अनावश्यक स्ट्रिंग प्रोसेसिंग और मैप लुकअप को रोका जा सकेगा।

0

आप आसानी से मान प्राप्त करने के लिए DatabaseUtils .stringForQuery() स्थिर विधि Android SDK में है कि पहले से ही का उपयोग करना चाहिए, इस उदाहरण String बॉट के लिए वहाँ भी Long

stringForQuery(SQLiteDatabase db, String query, String[] selectionArgs) 

उपयोगिता विधि के लिए विधि है डीबी पर क्वेरी चलाने के लिए और पहली पंक्ति के पहले कॉलम में मान वापस करें।

कुछ

तरह
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) { 
     .... 
    } 
} 

व्यक्तिगत रूप से, मैं बाद करना चाहते हैं , जब तक कि आप हर बार इस अतिरिक्त तर्क प्रदान करने से नफरत करते हैं।

संपादित करें: मैं पाइडव के महत्वपूर्ण बिंदु का उल्लेख करना भूल गया: यदि आप इसे एक लूप में कहते हैं, तो आप एक उल्लेखनीय प्रदर्शन प्रभाव के लिए स्वयं को स्थापित कर रहे हैं। पसंदीदा तरीका एक बार इंडेक्स को देखना है, इसे कैश करना है, और इसके बजाए इसका उपयोग करना है।

+0

धन्यवाद! यह एक समाधान की तरह लगता है जो काम करेगा। लेकिन क्या इसके बजाय इसे विस्तारित करना और एक सहायक का उपयोग करना संभव है? – Martin

+0

वास्तव में, क्योंकि ऑब्जेक्ट ऑपरेटिंग सिस्टम द्वारा तत्काल नहीं किया गया है, आपके द्वारा नहीं, और किसी अन्य से उप-वर्गीकृत कर्सर बनाने का कोई तरीका नहीं है। – EboMike

0

इस पर एक अलग समाधान की तलाश में आया, लेकिन बस इसे जोड़ना चाहते हैं क्योंकि मुझे विश्वास है कि उत्तर असंतोषजनक हैं।

आप आसानी से अपना कर्सर क्लास बना सकते हैं। कर्सर को स्वीकार करने के लिए आवश्यक कार्यों को अनुमति देने के लिए, इसे सार कर्सर का विस्तार करना होगा। सिस्टम के मुद्दे को दूर करने के लिए अपनी कक्षा का उपयोग न करें, आप बस अपनी कक्षा को एक रैपर बनाते हैं।

यहां वास्तव में एक अच्छा उदाहरण है। 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 बनाने का सबसे अच्छा तरीका ढूंढने के लिए इस प्रश्न पर आया। मेरे मामले में मुझे कर्सर को अतिरिक्त जानकारी रखने के लिए एक अतिरिक्त विशेषता की आवश्यकता थी, इसलिए मेरा उपयोग मामला बिल्कुल सवाल के शरीर में नहीं है। आशा में मेरे निष्कर्ष पोस्ट करना यह सहायक होगा।

मेरे लिए मुश्किल हिस्सा यह था कि SQLiteDatabase क्वेरी विधियां कर्सर लौटाती हैं, और मुझे कर्सर को कस्टम उप-वर्ग पर जाने की आवश्यकता होती है।

मुझे एंड्रॉइड एपीआई में समाधान मिला: 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; 
} 
संबंधित मुद्दे