2012-10-05 8 views
12

मैं <path_to_SDK>/samples/android-16/NotePad/src/com/example/android/notepad में एंड्रॉइड नोटपैड एप्लिकेशन नमूना कोड देख रहा हूं।सामग्री प्रदाता में एंड्रॉइड प्रक्षेपण मानचित्र का उद्देश्य क्या है?

मैं सोच रहा था कि कोई मुझे बता सकता है कि NotepadProvider.java में निम्न कोड की आवश्यकता क्यों है?

... 
SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 
qb.setTables(NotePad.Notes.TABLE_NAME); 

/** 
* Choose the projection and adjust the "where" clause based on URI pattern-matching. 
*/ 
switch (sUriMatcher.match(uri)) { 
    // If the incoming URI is for notes, chooses the Notes projection 
    case NOTES: 
    qb.setProjectionMap(sNotesProjectionMap); 
    break; 
... 

इस प्रक्षेपण नक्शा क्यों की जरूरत है:

// Creates a new projection map instance. The map returns a column name 
// given a string. The two are usually equal. 
sNotesProjectionMap = new HashMap<String, String>(); 

// Maps the string "_ID" to the column name "_ID" 
sNotesProjectionMap.put(NotePad.Notes._ID, NotePad.Notes._ID); 

// Maps "title" to "title" 
sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_TITLE,NotePad.Notes.COLUMN_NAME_TITLE); 

// Maps "note" to "note" 
sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_NOTE, NotePad.Notes.COLUMN_NAME_NOTE); 

// Maps "created" to "created" 
sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, NotePad.Notes.COLUMN_NAME_CREATE_DATE); 

// Maps "modified" to "modified" 
sNotesProjectionMap.put(
     NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, 
     NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE) 

मैं प्रक्षेपण नक्शा बाद में query() विधि में प्रयोग किया जाता है नोटिस?

+1

के लिए दस्तावेज़ 'SQLiteQueryBuilder.setProjectionMap()' एक अच्छा व्याख्या है। – Luksprog

+0

धन्यवाद। हो सकता है कि मेरा प्रश्न पर्याप्त स्पष्ट न हो - मैं समझता हूं कि प्रक्षेपण मानचित्र क्या है, लेकिन मैं सोच रहा था कि प्रक्षेपण मानचित्र का क्या बिंदु है जिसमें केवल समान कुंजी और मूल्य वाले मैपिंग शामिल हैं (मैं समझता हूं कि कम से कम एक मैपिंग्स एक अलग कुंजी, मूल्य जोड़ी थी)। – Mewzer

+1

यह एक नमूना अनुप्रयोग है, जो कि 'एपीआई' उपयोग और उन 'एपीआई' का उपयोग करके अच्छी प्रथाओं का एक उदाहरण होना चाहिए, इस तरह वे शायद प्रक्षेपण मानचित्र का उपयोग करते हैं। उदाहरण के लिए, यदि मुझे सही याद है, तो Google इंजीनियरों में से एक द्वारा बनाए गए 'शेल्व' एप्लिकेशन अपने 'ContentProvider' में प्रक्षेपण मानचित्र का उपयोग कर रहे हैं और प्रक्षेपण मानचित्र समान कुंजी-मूल्य जोड़े के साथ एक साधारण मैपिंग नहीं है। – Luksprog

उत्तर

10

डेमो से आवेदन एक नमूना अनुप्रयोग है, जो कि एपीआई उपयोग और उन एपीआई का उपयोग करके अच्छे प्रथाओं का एक उदाहरण होना चाहिए, यही कारण है कि वे शायद प्रक्षेपण मानचित्र का उपयोग करते हैं। यद्यपि Notepad नमूना को वास्तव में प्रक्षेपण मानचित्र की आवश्यकता नहीं है, लेकिन किसी के उपयोग के लिए अधिक जटिल मामलों के लिए एक अच्छा प्रदर्शन है। उदाहरण के लिए, यदि मुझे सही याद है, तो Shelves Google इंजीनियरों में से एक द्वारा लिखित आवेदन अपने ContentProvider में प्रक्षेपण मानचित्र का उपयोग कर रहा है और यह प्रक्षेपण मानचित्र समान कुंजी-मूल्य जोड़े के साथ एक साधारण मैपिंग नहीं है।

मैंने विधि SQLiteQueryBuilder.setProjectionMap के दस्तावेज़ के लिए एक लिंक भी जोड़ा है जिसमें कुछ विवरण हैं कि आपको प्रक्षेपण मानचित्र की आवश्यकता क्यों होगी।

+0

क्या आपके पास प्रक्षेपण मानचित्र का उपयोग क्यों करना है? मुझे क्वेरी और कॉलम नामों के बीच किसी अन्य नाम का उपयोग करने के बिंदु को समझना निश्चित नहीं है? – Paul

+3

@Paul उस प्रक्षेपण मानचित्र की आवश्यकता होती है जब आपने एक बहुत ही सरल क्वेरी की तुलना में अधिक उन्नत परिदृश्यों के लिए 'SQLiteQueryBuilder' का उपयोग किया था। उदाहरण के लिए, हो सकता है कि आप एक एसक्लाइट टेबल के वर्तमान कॉलम नामों और अपने ऐप में कुछ मनमानी नामों के बीच एक उपनाम बनाना चाहते हैं ('AS' sqlite कीवर्ड http://www.sqlite.org/syntaxdiagrams.html# देखें परिणाम-स्तंभ)। साथ ही प्रश्नों में शामिल होने के लिए आपको अलग-अलग नामों की आवश्यकता हो सकती है यदि आपके टेबल में समान नाम वाले कॉलम हैं (आमतौर पर, दो टेबल जिनमें प्रत्येक के पास '_id' कॉलम होता है)। – Luksprog

+0

ठीक है धन्यवाद Luksprog – Paul

7

इसका मुख्य उद्देश्य किसी क्वेरी द्वारा उत्पादित कर्सर में पाए गए कॉलम नामों का नाम बदलना है।

@static घोषणा

SEARCH_PROJECTION_MAP = new HashMap<String, String>(); 
SEARCH_PROJECTION_MAP.put(OpenHelper.NAME, OpenHelper.NAME + " as _name"); 
SEARCH_PROJECTION_MAP.put(OpenHelper.ID , OpenHelper.ID + " as _id"); 

@your क्वेरी कार्यक्षमता

//if you query using sqliteQueryBuilder then 
    sqLiteQueryBuilder.setProjectionMap(SEARCH_PROJECTION_MAP); 

//example if you just query 
    Cursor cursor = sqLiteQueryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); 

लौटे कॉलम अब नाम_ और _ id इस उदाहरण में कर रहे हैं।

+1

स्वीकार किए गए एक से बेहतर स्पष्टीकरण। – azizbekian

+0

@azizbekian, तारीफ के लिए धन्यवाद। मुझे काम करते समय पता चला और किसी और की तलाश की जो इसे समझ में नहीं आया जैसे यह मेरे साथ हुआ। –

0

जुआन के अलावा, प्रक्षेपण मानचित्र का उद्देश्य कॉलम नामों का नाम बदलने के साथ-साथ जुड़ने के दौरान स्तंभ नामों को असंबद्ध करने के लिए है, प्रक्षेपण मानचित्र का महत्वपूर्ण उद्देश्य दुर्भावनापूर्ण तर्कों के चयन को सत्यापित करने के लिए है।

का उपयोग करके एक कथन बनाने के लिए SQLiteQueryBuilder का उपयोग करते समय, यदि कोई प्रक्षेपण मानचित्र निर्दिष्ट किया गया है, तो उस मानचित्र में फ़ील्ड को अनदेखा नहीं किया जाएगा।

(उदाहरण सामग्री प्रदाता उपभोक्ताओं के लिए) दुर्भावनापूर्ण तृतीय पक्ष एप्लिकेशन के खिलाफ अधिकतम सुरक्षा प्राप्त करने के लिए आप निम्न कर सकते हैं:

  1. सेट SQLiteQueryBuilder#setStrict(true)
  2. उपयोग एक प्रक्षेपण नक्शा।
  3. क्वेरी का प्रयोग एक के बजाय एक एसक्यूएल स्ट्रिंग
0

हो सकता है कि किसी को अधिक विस्तृत विवरण की जरूरत के रूप में बयान होने का overloads। मैंने प्रक्षेपण मानचित्र के बारे में महत्वपूर्ण तथ्यों को इकट्ठा किया है:

  1. यदि आपको प्रक्षेपण मानचित्र की आवश्यकता नहीं है तो बस इसे सेट न करें।इस तरह प्रक्षेपण नामों को "जैसा है" संसाधित किया जाता है, ठीक उसी तरह प्रक्षेपण सरणी के माध्यम से पारित किया जाता है।

  2. यहां तक ​​कि प्रोजेक्शन सरणी वैकल्पिक है। यदि आप क्वेरी में शून्य पास करते हैं, तो यह "चयन *" ऑपरेशन उत्पन्न करता है। (वास्तव में एसक्यूएल में अनुशंसित नहीं है, अगर कॉलम जोड़े/हटा दिए जाते हैं, या फिर से आदेश दिया जाता है तो टूटने की वजह से)।

  3. आपूर्ति प्रक्षेपण नक्शा ही चयन सूची पर लागू होता है! तो, आप "store_name" => "bookstore.storename" को मैप कर सकते हैं, और इसके परिणामस्वरूप "bookstore.storename चुनें ...", लेकिन यदि आपने "build_name" क्वेरी बिल्डर पैरामीटर या "में से" में "store_name" प्रदान किया है अन्य योग्य पैरामीटर, आप संभावित रूप से खराब SQL के साथ समाप्त कर सकते हैं।

  4. प्रक्षेपण मानचित्र को खारिज कर दिया जा सकता है। यदि प्रक्षेपण प्रविष्टि के मुख्य भाग में "जैसा" खंड होता है, तो मान भाग को अनदेखा किया जाता है और मुख्य भाग परिणामस्वरूप SQL में डाला जाता है। उदाहरण के लिए "तोता के रूप में तोता" => "क्रैकर" "पोल के रूप में चयन तोते" उत्पन्न करेगा और कोई "क्रैकर" नहीं होगा। "जैसा" या तो सभी ऊपरी मामले या सभी निचले मामले (मिश्रित मामले नहीं) हो सकते हैं और "as" शब्द से पहले और बाद में कम-से-कम एक स्थान होना चाहिए।

इस लेख में और अधिक जानकारी पढ़ें: http://www.mousetech.com/blog/android-projection-maps-explained/

संबंधित मुद्दे