جستارها - Android

پیش‌نیازها

  1. در صورتی که با سرویس پایگاه‌داده آشنایی ندارید، به معرفی سرویس پایگاه‌داده مراجعه کنید.
  2. در صورتی که هنوز در پنل توسعه‌دهنده خود تنظیمات لازم برای سرویس پایگاه‌داده خود را انجام نداده‌اید، به تنظیمات پنل مراجعه کنید.
  3. در صورتی که هنوز SDK اندروید را راه‌اندازی نکرده‌اید، به راه‌اندازی SDK بکتوری در اندروید مراجعه کنید.
  4. در صورتی که هنوز کار با اشیاء پایگاه داده را به کمک SDK اندروید فرا نگرفته‌اید، به کار با اشیاء مراجعه کنید.

مقدمه

بعد از ذخیره کردن اشیاء در پایگاه داده، بسیار پیش می‌آید که بخواهید آنها را بازیابی کنید. عملیات بازیابی عموما با تعیین چندین شرط (Constraint) صورت می‌گیرد و ما اشیایی را می‌خواهیم که در این شروط صدق کنند. به مجموعه شروط تعیین شده برای یک عملیات بازیابی «جُستار» (Query) گفته می‌شود.

بکتوری برای ساخت Query کلاس BacktoryQuery را در اختیار شما می‌گذارد. به صورت معمول شما یک BacktoryQuery با اسم جدولی که می‌خواهید سطرهای آنرا بازیابی کنید می‌سازید، روی آن شرایطی اعمال می‌کنید و سپس با تابع findInBackground لیست اشیایی را که در این جستار صدق می‌کنند، می‌گیرید.

جستارهای ساده

ساده‌ترین و معمول ترین حالت، حالتی است که ‌می‌خواهیم مقدار ستون خاصی از سطرهای جدول، با مقداری که در جستار تعیین می‌کنیم برابر باشد. مثلا از جدول “Note” در پایگاه داده، تمامی یادداشت‌هایی را می‌خواهیم که عنوانشان “Todo” است. برای این بازیابی کد زیر می‌تواند استفاده شود:

BacktoryQuery todoQuery = new BacktoryQuery("Note");
todoQuery.whereEqualTo("title", "Todo");
todoQuery.findInBackground(new BacktoryCallBack<List<BacktoryObject>>() {
    @Override
    public void onResponse(BacktoryResponse<List<BacktoryObject>> response) {
        if (response.isSuccessful()) {
            List<BacktoryObject> todoNotes = response.body();
            // for (BacktoryObject todo : todoNotes)
            //   todo.getString("content")...

        } else {
            // see response.message() to know the cause of error

        }
    }
});

شروط جستار

برای تعیین شرط روی محتوای یک ستون، BacktoryQuery توابع متنوعی را فراهم کرده که با کلمه “where” شروع می‌شوند. در زیر به طور مثال چند مورد از صدا زدن این توابع آورده شده است:

BacktoryQuery query = new BacktoryQuery("Note");
query.whereNotEqualTo("title", "shopping"); // all the notes with titles other than "shopping"
query.whereGreaterThan("priority", 4);      // notes with priority more than 4

می‌توان تعداد نتایج یک جستار را محدود کرد:

query.setLimit(5);  // limit the notes to at most 5 results

می‌توان به صورت زیر اولین نتایج جستار را صرف نظر کرد. این حرکت در صفحه‌صفحه کردن (pagination) مفید خواهد بود.

query.setSkip(5); // skip the first 5 results

برای ستون‌هایی که قابل مرتب سازی هستند، می‌توان نتیجه را بر اساس آن ستون، صعودی (ascending) یا نزولی (descending)، مرتب کرد. به شکل زیر:

// Sorts the results in ascending order by the priority field
query.orderByAscending("priority");
// Sorts the results in descending order by the priority field
query.orderByDescending("priority");

اگر می‌خواهید مقدار ستون نتایج جزو لیستی از مقادیر مشخص باشد، به این صورت می‌توانید عمل کنید:

// notes whose color column’s value is one of the red, blue or yellow
query.whereContainedIn("color", Arrays.asList("red", "blue", "yellow"));

جستار روی ستون‌های لیستی

اگر یک ستون از جنس لیست است، می‌توانید در اعضای آن لیست جستجو کنید. فرض کنید هر یادداشت لیستی از سایر یادداشت‌ها را دارد که به آن‌ها پیشنیازی دارد. در این صورت، جستار زیر یادداشت‌هایی را برمی‌گرداند که در لیست پیشنیازیشان، یادداشت شماره 2 وجود دارد.

// notes that have dependency on the note with id of 2
query.whereEqualTo("dependsOn", 2);

حال اگر بخواهیم یادداشت‌هایی که به یادداشت‌های ۱ و ۲ و ۷ پیش‌نیازی دارند، را بازیابی کنیم، به صورت زیر عمل می‌کنیم:

// notes that have dependency on the notes of 1, 2 and 7
query.whereContainsAll("dependsOn", Arrays.asList(1, 2, 7));

گرفتن چند نمونه‌ی تصادفی از یک جستار

می‌توان تعدادی تصادفی از سطرهایی که در یک جستار صدق می‌کنند را برگرداند. به طور مثال فرض کنید که جدول یادداشت شامل ستون tags است و برخی از یادداشت‌ها را با برچسب خاطره (diary) نشان کرده‌اید و می‌خواهید هر روز یک خاطره‌ی تصادفی را به کاربر نشان دهید.

BacktoryQuery query = new BacktoryQuery("Note");
query.whereEqualTo("tags", "diary");
query.setSample(1);
query.findInBackground(new BacktoryCallBack<List<BacktoryObject>>() {
    @Override
    public void onResponse(BacktoryResponse<List<BacktoryObject>> response) {
        if (response.isSuccessful()) {
            BacktoryObject randomDiary = response.body().get(0);
            Log.d("TAG", "Your daily memory is: \n"
                    + randomDiary.getString("content"));
        } else {
            // see response.message() to know the cause of error
        }
    }
});

جستار روی ستون‌های رشته‌ای

چنانچه جنس ستون رشته باشد، می‌توانید شرط‌های خاصی را روی آن اعمال کنید. مثلا یادداشت‌هایی را میخواهید که عنوانشان با “Call” شروع می‌شود و محتوایشان شامل عبارت “number” است. در این صورت کد زیر خواسته‌ی شما را برآورده می‌کند:

query.whereStartsWith("title", "Call");     // matches "Call Backtory", "Call of Duty",
                                            //      but doesn’t match "call me baby!"
query.whereContains("content", "number");

دیتابیس بکتوری از regular expression پشتیبانی می‌کند و شما با استفاده از تابع whereMatches می‌توانید شروط دلخواه خود را روی ستون‌های رشته‌ای اعمال کنید.

توجه: جستارهای حاوی شروط regular expression سنگین و کندتر از سایر جستارها هستند.

شمارگان نتیجه‌ی یک جستار (Count query)

مواقعی پیش می‌آید که شما تنها «تعداد» سطرهایی را می‌خواهید که در یک جستار صدق می‌کنند و نه «خود» سطرها را. به طور مثال، فرض کنید جدول یادداشت ستونی به اسم tags از جنس آرایه دارد و تعداد یادداشت‌هایی را می‌خواهید که برچسب «وظیفه» (task) خورده‌اند. بدین منظور، کدی مانند زیر را می‌توانید اجرا کنید:

BacktoryQuery query = new BacktoryQuery("Note");
query.whereEqualTo("tags", "task");
query.countInBackground(new BacktoryCallBack<Integer>() {
    @Override
    public void onResponse(BacktoryResponse<Integer> response) {
        if (response.isSuccessful()) {
            int count = response.body();
            Log.d("TAG", "You have " + count + " task to complete!");
        } else {
            // see response.message() to know the cause of error
        }
    }
});

جستارهای ترکیبی

اگر بخواهید اشیایی را بیابید که در یکی از چندین جستار صدق می‌کنند، می‌توانید از تابع BacktoryQuery.or استفاده کنید که لیستی از جستارها را گرفته و از ترکیب آنها یک جستار می‌سازد. دقت کنید که جستارها باید متعلق به یک جدول باشند. روی جستار ترکیبی می‌توانید با توابع where مجددا شرط اعمال کنید، اما نمی‌توانید فیلترهای setLimit، setSkip و orderBy را استفاده کنید.

BacktoryQuery highPriorityNotes = new BacktoryQuery("Note");
highPriorityNotes.whereGreaterThanOrEqualTo("priority", 5);
BacktoryQuery importantNotes = new BacktoryQuery("Note");
importantNotes.whereContains("content", "important");
BacktoryQuery compoundImportantQuery =
        BacktoryQuery.or(Arrays.asList(highPriorityNotes, importantNotes));

compoundImportantQuery.findInBackground(new BacktoryCallBack<List<BacktoryObject>>() {
    @Override
    public void onResponse(BacktoryResponse<List<BacktoryObject>> response) {
        if (response.isSuccessful()) {
            // response.body() is the list of objects having
            //          either priority of 5 and more,
            //          or content with "important" substring.
        } else {
            // see response.message() to know the cause of error
        }
    }
});

دیتابیس بکتوری از regular expression پشتیبانی می‌کند و شما با استفاده از تابع whereMatches می‌توانید شروط دلخواه خود را روی ستون‌های رشته‌ای اعمال کنید.

توجه: جستارهای حاوی شروط regular expression سنگین و کندتر از سایر جستارها هستند.

گرفتن تمام سطر‌های جدول

اگر بخواهید تمام سطر‌های یک جدول را دریافت کنید کافی است یک شیء BacktoryQuery بسازید و بعد روی آن تابع FindInBackground را صدا بزنید. البته لازم است که دقت کنید که یک جستار به صورت پیش فرض تنها ۱۰۰ نتیجه را باز می‌گرداند ولی می‌توانید این مقدار را تا ۱۰۰۰ افزاش دهید. پس اگر تعداد داده‌های جدول شما بیش از ۱۰۰۰ بود باید با استفاده از setLimit و setSkip محدوده‌های خود را تعیین کنید و سطر‌های آن محدوده را دریافت نمایید.

BacktoryQuery query = new BacktoryQuery("Note");

query.findInBackground(new BacktoryCallBack<List<BacktoryObject>>() {
    @Override
    public void onResponse(BacktoryResponse<List<BacktoryObject>> response) {
        if (response.isSuccessful()) {
            // response.body() is the list of all objects.
        } else {
            // see response.message() to know the cause of error
        }
    }
});