खोज…


परिचय

दायरे मोबाइल डेटाबेस SQLite के लिए एक विकल्प है। दायरे मोबाइल डेटाबेस एक ORM की तुलना में बहुत तेज है, और अक्सर कच्चे SQLite से भी तेज है।

लाभ

ऑफ़लाइन कार्यक्षमता, तेज़ क्वेरी, सुरक्षित थ्रेडिंग, क्रॉस-प्लेटफ़ॉर्म ऐप, एन्क्रिप्शन, रिएक्टिव आर्किटेक्चर।

टिप्पणियों

जब आप Realm का उपयोग करते हैं, तो आपको याद रखना चाहिए कि आप RealmObjects, RealmResults और Realm इंस्टेंस को धागों के बीच से गुजारें। यदि आपको किसी दिए गए थ्रेड पर एक क्वेरी की आवश्यकता है, तो उस थ्रेड पर एक Realm इंस्टेंस खोलें। धागे की समाप्ति पर, आपको दायरे को बंद करना चाहिए।

कानूनी नोट : आप समझते हैं कि सॉफ़्टवेयर में क्रिप्टोग्राफ़िक फ़ंक्शन शामिल हो सकते हैं जो निर्यात प्रतिबंधों के अधीन हो सकते हैं, और आप प्रतिनिधित्व करते हैं और वारंट करते हैं कि आप किसी ऐसे देश में स्थित नहीं हैं , जो क्यूबा, ईरान, उत्तर सहित संयुक्त राज्य अमेरिका के निर्यात प्रतिबंध या प्रतिबंध के अधीन है। कोरिया, सूडान, सीरिया या क्रीमिया क्षेत्र , और यह कि आप डिपार्टमेंट ऑफ़ कॉमर्स लिस्ट ऑफ़ डेनिड पर्सन्स, अनवेरिफाइड पार्टीज़ या एक प्रतिबंधित संस्था से संबद्ध नहीं हैं।

अपने प्रोजेक्ट में दायरे जोड़ना

अपने प्रोजेक्ट स्तर build.gradle फ़ाइल के लिए निम्न निर्भरता जोड़ें।

dependencies {
    classpath "io.realm:realm-gradle-plugin:3.1.2"
}

अपने एप्लिकेशन स्तर build.gradle फ़ाइल के शीर्ष पर निम्न दाईं ओर जोड़ें।

apply plugin: 'realm-android'

एक सिंक सिंक पूरा करें और आपके पास अब Realm आपके प्रोजेक्ट के लिए एक निर्भरता के रूप में जुड़ गया है!

दायरे का उपयोग करने से पहले 2.0.0 के बाद से एक प्रारंभिक कॉल की आवश्यकता है। आप इसे अपने Application वर्ग में या अपनी पहली गतिविधि की onCreate विधि में कर सकते हैं।

Realm.init(this); // added in Realm 2.0.0
Realm.setDefaultConfiguration(new RealmConfiguration.Builder().build());

दायरे के मॉडल

दायरे मॉडल को RealmObject बेस क्लास का विस्तार करना चाहिए, वे अंतर्निहित डेटाबेस के स्कीमा को परिभाषित करते हैं।

समर्थित फ़ील्ड प्रकार boolean , byte , short , int , long , float , double , String , Date , byte[] , अन्य RealmObject s के लिंक, और RealmList<T extends RealmModel>

public class Person extends RealmObject {
    @PrimaryKey //primary key is also implicitly an @Index 
                //it is required for `copyToRealmOrUpdate()` to update the object.
    private long id;

    @Index //index makes queries faster on this field
    @Required //prevents `null` value from being inserted
    private String name; 

    private RealmList<Dog> dogs; //->many relationship to Dog

    private Person spouse; //->one relationship to Person

    @Ignore
    private Calendar birthday; //calendars are not supported but can be ignored

    // getters, setters
}

यदि आप अपने RealmObject में एक नया फ़ील्ड जोड़ते (या हटाते हैं) या (आप एक नया RealmObject क्लास जोड़ते हैं या किसी मौजूदा को हटाते हैं), तो माइग्रेशन की आवश्यकता होगी। आप या तो अपने RealmConfiguration.Builder में deleteIfMigrationNeeded() सेट कर सकते हैं, या आवश्यक माइग्रेशन को परिभाषित कर सकते हैं। @Required , या @Index , या @PrimaryKey एनोटेशन जोड़ते समय (या हटाते समय) माइग्रेशन की भी आवश्यकता होती है।

रिश्तों को मैन्युअल रूप से सेट किया जाना चाहिए, वे प्राथमिक कुंजी के आधार पर स्वचालित नहीं हैं।

0.88.0 के बाद से, RealmObject कक्षाओं में निजी क्षेत्रों / गेटर्स / सेटर के बजाय सार्वजनिक क्षेत्रों का उपयोग करना संभव है।

यदि RealmObject क्लास को @RealmClass साथ भी एनोटेट किया गया है, तो RealmObject को फैलाने के बजाय RealmModel को लागू करना संभव है।

@RealmClass
public class Person implements RealmModel {
    // ...
}

उस स्थिति में, person.deleteFromRealm() या person.addChangeListener() जैसे तरीकों को RealmObject.deleteFromRealm(person) और RealmObject.addChangeListener(person) साथ बदल दिया जाता है।

सीमाएं यह हैं कि एक RealmObject द्वारा, केवल RealmObject को बढ़ाया जा सकता है, और final , volatile और transient क्षेत्रों के लिए कोई समर्थन नहीं है।

यह महत्वपूर्ण है कि एक प्रबंधित RealmObject वर्ग को केवल लेनदेन में ही संशोधित किया जा सकता है। एक प्रबंधित RealmObject थ्रेड्स के बीच पारित नहीं किया जा सकता है।

आदिमों की सूची (RealmList) )

दायरे वर्तमान में आदिम की एक सूची भंडारण का समर्थन नहीं करता है। यह उनकी टूडू सूची ( GitHub अंक # 575 ) पर है, लेकिन इस बीच, यहां एक समाधान है।

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

public class RealmInteger extends RealmObject {
    private int val;

    public RealmInteger() {
    }

    public RealmInteger(int val) {
        this.val = val;
    }

    // Getters and setters
}

अब आप इसे अपने RealmObject में उपयोग कर सकते हैं।

public class MainObject extends RealmObject {

    private String name;
    private RealmList<RealmInteger> ints;

    // Getters and setters
}

आप उपयोग कर रहे हैं GSON अपने को भरने के लिए RealmObject , आप एक कस्टम प्रकार एडाप्टर जोड़ने की आवश्यकता होगी।

Type token = new TypeToken<RealmList<RealmInteger>>(){}.getType();
Gson gson = new GsonBuilder()
        .setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getDeclaringClass().equals(RealmObject.class);
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        })
        .registerTypeAdapter(token, new TypeAdapter<RealmList<RealmInteger>>() {

            @Override
            public void write(JsonWriter out, RealmList<RealmInteger> value) throws IOException {
                // Empty
            }

            @Override
            public RealmList<RealmInteger> read(JsonReader in) throws IOException {
                RealmList<RealmInteger> list = new RealmList<RealmInteger>();
                in.beginArray();
                while (in.hasNext()) {
                    list.add(new RealmInteger(in.nextInt()));
                }
                in.endArray();
                return list;
            }
        })
        .create();

कोशिश-साथ-संसाधनों

try (Realm realm = Realm.getDefaultInstance()) {
    realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                //whatever Transaction that has to be done
            }
    });
    //No need to close realm in try-with-resources
}

संसाधनों के साथ प्रयास केवल KITKAT से उपयोग किया जा सकता है (minSDK 19)

क्रमबद्ध प्रश्न

किसी क्वेरी को सॉर्ट करने के लिए, findAll() का उपयोग करने के बजाय, आपको findAllSorted() उपयोग करना चाहिए।

RealmResults<SomeObject> results = realm.where(SomeObject.class)
                                            .findAllSorted("sortField", Sort.ASCENDING);

ध्यान दें:

sort() एक पूरी तरह से नया RealmResults देता है जिसे क्रमबद्ध किया जाता है, लेकिन इस RealmResults को अपडेट करने से यह रीसेट हो जाएगा। यदि आप sort() उपयोग करते हैं, तो आपको हमेशा इसे अपने RealmChangeListener में पुन: सॉर्ट करना चाहिए, पिछले RealmResults से RealmChangeListener को RealmResults और इसे वापस दिए गए नए RealmResultsRealmResults पर एक sort() का उपयोग करके एक async क्वेरी द्वारा लौटाया गया है जो अभी तक लोड नहीं हुआ है।

findAllSorted() हमेशा फ़ील्ड द्वारा क्रमबद्ध परिणामों को लौटाएगा, भले ही वह अपडेट हो जाए। यह findAllSorted() का उपयोग करने के लिए अनुशंसित है।

Async प्रश्न

प्रत्येक तुल्यकालिक क्वेरी विधि (जैसे findAll() या findAllSorted() ) में एक एसिंक्रोनस समकक्ष ( findAllAsync() / findAllSortedAsync() ) होता है।

असिंक्रोनस क्वेरीज़ RealmResults के मूल्यांकन को दूसरे थ्रेड पर RealmResults करता है। वर्तमान थ्रेड पर ये परिणाम प्राप्त करने के लिए, वर्तमान थ्रेड में लूपर थ्रेड होना चाहिए (पढ़ें: async क्वेरीज़ आमतौर पर केवल UI थ्रेड पर काम करती हैं)।

RealmChangeListener<RealmResults<SomeObject>> realmChangeListener; // field variable

realmChangeListener = new RealmChangeListener<RealmResults<SomeObject>>() {
    @Override
    public void onChange(RealmResults<SomeObject> element) {
        // asyncResults are now loaded
        adapter.updateData(element);
    }
};

RealmResults<SomeObject> asyncResults = realm.where(SomeObject.class).findAllAsync();
asyncResults.addChangeListener(realmChangeListener);

RxJava के साथ दायरे का उपयोग करना

प्रश्नों के लिए, दायरे realmResults.asObservable() विधि प्रदान करता है। अवलोकन परिणाम केवल लूपर थ्रेड्स (आमतौर पर UI थ्रेड) पर संभव है।

इस कार्य के लिए, आपके कॉन्फ़िगरेशन में निम्नलिखित शामिल होने चाहिए

realmConfiguration = new RealmConfiguration.Builder(context)       //
                          .rxFactory(new RealmObservableFactory()) //
                             //...
                          .build();

बाद में, आप अपने परिणामों को एक अवलोकन के रूप में उपयोग कर सकते हैं।

Observable<RealmResults<SomeObject>> observable = results.asObservable();

अतुल्यकालिक प्रश्नों के लिए, आपको परिणाम को isLoaded() द्वारा फ़िल्टर करना चाहिए, ताकि आपको केवल एक घटना प्राप्त हो जब क्वेरी निष्पादित की गई हो। यह filter() तुल्यकालिक प्रश्नों के लिए आवश्यक नहीं है ( isLoaded() हमेशा सिंक प्रश्नों पर true )।

    Subscription subscription = RxTextView.textChanges(editText).switchMap(charSequence -> 
        realm.where(SomeObject.class)
             .contains("searchField", charSequence.toString(), Case.INSENSITIVE)
             .findAllAsync()
             .asObservable())
    .filter(RealmResults::isLoaded) //
    .subscribe(objects -> adapter.updateData(objects));

लिखने के लिए, आपको या तो executeTransactionAsync() विधि का उपयोग करना चाहिए, या बैकग्राउंड थ्रेड पर एक दायरे का उदाहरण खोलना होगा, लेन-देन को सिंक्रोनाइज़ करना होगा, फिर दायरे को बंद करें।

public Subscription loadObjectsFromNetwork() {
    return objectApi.getObjects()
        .subscribeOn(Schedulers.io())
        .subscribe(response -> {
            try(Realm realmInstance = Realm.getDefaultInstance()) {
                realmInstance.executeTransaction(realm -> realm.insertOrUpdate(response.objects));
            }
        });
}

मूल उपयोग

एक उदाहरण स्थापित करना

दायरे का उपयोग करने के लिए आपको सबसे पहले इसका एक उदाहरण प्राप्त करने की आवश्यकता है। प्रत्येक दायरे उदाहरण के लिए डिस्क पर एक फ़ाइल में मैप करता है। एक उदाहरण प्राप्त करने का सबसे मूल तरीका इस प्रकार है:

// Create configuration
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(context).build();

// Obtain realm instance
Realm realm = Realm.getInstance(realmConfiguration);
// or
Realm.setDefaultConfiguration(realmConfiguration);
Realm realm = Realm.getDefaultInstance();

यदि यह नहीं बनाया गया है, तो Realm.getInstance() डेटाबेस फ़ाइल बनाता है, अन्यथा फ़ाइल को खोलता है। RealmConfiguration ऑब्जेक्ट सभी पहलुओं को नियंत्रित करता है कि कैसे एक Realm बनाया जाता है - चाहे वह inMemory() डेटाबेस हो, Realm फ़ाइल का नाम, यदि दायरे की आवश्यकता हो, तो प्रारंभिक डेटा साफ़ किया जाना चाहिए, आदि।

कृपया ध्‍यान दें कि Realm.getInstance() कॉल Realm.getInstance() होते हैं (प्रत्येक कॉल एक काउंटर बढ़ाता है), और काउंटर को तब realm.close() जाता है जब realm.close() कहा जाता है।

एक उदाहरण बंद करना

बैकग्राउंड थ्रेड्स पर, रियलम इंस्टेंस को बंद करना बहुत महत्वपूर्ण है, एक बार इसका उपयोग नहीं किया जाता है (उदाहरण के लिए, लेन-देन पूरा हो गया है और थ्रेड निष्पादन समाप्त हो जाता है)। वर्जन पिनिंग में बैकग्राउंड थ्रेड परिणाम पर सभी दायरे को बंद करने में विफलता, और फ़ाइल आकार में बड़ी वृद्धि का कारण बन सकती है।

Runnable runnable = new Runnable() {
    Realm realm = null;
    try {
        realm = Realm.getDefaultInstance();
        // ...
    } finally {
        if(realm != null) {
            realm.close();
        }
    }
};

new Thread(runnable).start(); // background thread, like `doInBackground()` of AsyncTask

यह ध्यान देने योग्य है कि एपीआई स्तर 19 से ऊपर, आप इस कोड को इस से बदल सकते हैं:

try(Realm realm = Realm.getDefaultInstance()) {
    // ...
}

मॉडल

अगला कदम अपने मॉडल बनाना होगा। यहां एक प्रश्न पूछा जा सकता है, "एक मॉडल क्या है?"। एक मॉडल एक संरचना है जो डेटाबेस में संग्रहीत किसी वस्तु के गुणों को परिभाषित करता है। उदाहरण के लिए, निम्नलिखित में हम एक पुस्तक का मॉडल बनाते हैं।

public class Book extends RealmObject {
 
    // Primary key of this entity
    @PrimaryKey
    private long id;
 
    private String title;

    @Index // faster queries
    private String author;
 
    // Standard getters & setter
    public long getId() {
        return id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) {
        this.title = title;
    }
 
    public String getAuthor() {
        return author;
    }
 
    public void setAuthor(String author) {
        this.author = author;
    }
}

ध्यान दें कि आपके मॉडल को RealmObject क्लास का विस्तार करना चाहिए। प्राथमिक कुंजी @PrimaryKey एनोटेशन द्वारा भी निर्दिष्ट की गई है। प्राथमिक कुंजी शून्य हो सकती है, लेकिन प्राथमिक कुंजी के रूप में केवल एक तत्व null हो सकता है। साथ ही आप उन फ़ील्ड्स के लिए @Ignore एनोटेशन का उपयोग कर सकते हैं, @Ignore डिस्क पर नहीं होना चाहिए:

@Ignore
private String isbn;

डेटा डालना या अपडेट करना

अपने दायरे डेटाबेस उदाहरण के लिए एक पुस्तक ऑब्जेक्ट को संग्रहीत करने के लिए, आप पहले अपने मॉडल का एक उदाहरण बना सकते हैं और फिर इसे copyToRealm विधि के माध्यम से डेटाबेस में संग्रहीत कर सकते हैं। बनाने या अपडेट करने के लिए आप copyToRealmOrUpdate उपयोग कर सकते हैं। (एक तेज विकल्प नव जोड़ा insertOrUpdate() )।

// Creating an instance of the model
Book book = new Book();
book.setId(1);
book.setTitle("Walking on air");
book.setAuthor("Taylor Swift")

// Store to the database
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        realm.insertOrUpdate(book);
    }
});

ध्यान दें कि डेटा में सभी परिवर्तन लेनदेन में होने चाहिए। ऑब्जेक्ट बनाने का दूसरा तरीका निम्नलिखित पैटर्न का उपयोग कर रहा है:

Book book = realm.createObject(Book.class, primaryKey);
...

डेटाबेस को छोड़ना

  • सभी पुस्तकें:

    RealmResults<Book> results = realm.where(Book.class).findAll();
    
  • 10 से अधिक आईडी वाली सभी पुस्तकें:

    RealmResults<Book> results = realm.where(Book.class)
                                      .greaterThan("id", 10)
                                      .findAll();
    
  • 'Taylor Swift' या '%Peter%' पुस्तकें:

    RealmResults<Book> results = realm.where(Book.class)
                                      .beginGroup()
                                          .equalTo("author", "Taylor Swift")
                                          .or()
                                          .contains("author", "Peter")
                                      .endGroup().findAll();
    

किसी वस्तु को हटाना

उदाहरण के लिए, हम टेलर स्विफ्ट की सभी पुस्तकों को हटाना चाहते हैं:

// Start of transaction
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        // First Step: Query all Taylor Swift books
        RealmResults<Book> results = ...
        
        // Second Step: Delete elements in Realm
        results.deleteAllFromRealm();
    }
});


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow