Realm JavaScript

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/11166081.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

入门

安装

按照下面的安装说明通过npm安装Realm JavaScript ,或者在GitHub上查看源代码。

先决条件

  • 确保您的环境已设置为运行React Native应用程序。按照React Native说明开始使用。
  • 使用Realm的应用可以同时针对iOS和Android。
  • 支持React Native 0.31.0及更高版本。

安装

  • 创建一个新的React Native项目:

    react-native init <project-name>
  • 将目录更改为新项目(cd <project-name>)并添加realm依赖项:

    npm install --save realm
  • 接下来,将项目链接到本realm机模块。

    react-native link realm

Android警告:根据版本的不同,react-native link可能会生成无效配置,正确更新Gradle(android/settings.gradleandroid/app/build.gradle)但无法添加Realm模块。确认react-native link已添加Realm模块; 如果没有,请使用以下步骤手动链接到库:

  1. 将以下行添加到android/settings.gradle

    include ':realm'
    project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android')
  2. 将Realm添加到依赖项中android/app/build.gradle

    // When using Android Gradle plugin 3.0 or higher
    dependencies {
        implementation project(':realm') } // When using Android Gradle plugin lower than 3.0 dependencies { compile project(':realm') }
  3. 添加导入并链接包MainApplication.java

    import io.realm.react.RealmReactPackage; // add this import public class MainApplication extends Application implements ReactApplication { @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new RealmReactPackage() // add this line ); } }

你现在准备好了。要查看Realm的运行情况,请将class <project-name>以下内容替换为以下内容App.js

const Realm = require('realm');

class <project-name> extends Component {
  constructor(props) {
    super(props);
    this.state = { realm: null };
  }

  componentWillMount() {
    Realm.open({
      schema: [{name: 'Dog', properties: {name: 'string'}}]
    }).then(realm => {
      realm.write(() => {
        realm.create('Dog', {name: 'Rex'});
      });
      this.setState({ realm });
    });
  }

  render() {
    const info = this.state.realm
      ? 'Number of dogs in this Realm: ' + this.state.realm.objects('Dog').length
      : 'Loading...';

    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          {info}
        </Text>
      </View>
    );
  }
}

然后,您可以在设备和模拟器中运行您的应用程序。

请注意,世博会不支持Realmcreate-react-native-app不起作用。

介绍

Realm JavaScript使您能够以安全,持久和快速的方式有效地编写应用程序的模型层。它旨在与React NativeNode.js一起使用

这是一个简单的例子:

const Realm = require('realm'); // Define your models and their properties const CarSchema = { name: 'Car', properties: { make: 'string', model: 'string', miles: {type: 'int', default: 0}, } }; const PersonSchema = { name: 'Person', properties: { name: 'string', birthday: 'date', cars: 'Car[]', picture: 'data?' // optional property } }; Realm.open({schema: [CarSchema, PersonSchema]}) .then(realm => { // Create Realm objects and write to local storage realm.write(() => { const myCar = realm.create('Car', { make: 'Honda', model: 'Civic', miles: 1000, }); myCar.miles += 20; // Update a property value }); // Query Realm for all cars with a high mileage const cars = realm.objects('Car').filtered('miles > 1000'); // Will return a Results object with our 1 car cars.length // => 1 // Add another car realm.write(() => { const myCar = realm.create('Car', { make: 'Ford', model: 'Focus', miles: 2000, }); }); // Query results are updated in realtime cars.length // => 2 }) .catch(error => { console.log(error); });

请注意,如果要将Realm用于服务器端/节点,则可以在Realm Object Server文档中找到其他信息。

Realm Studio

Realm Studio是我们的首选开发人员工具,可以轻松管理Realm数据库和Realm平台。使用Realm Studio,您可以打开和编辑本地和同步的域,并管理任何Realm Object Server实例。它支持Mac,Windows和Linux。

Realm Studio

三界

开放的领域

只需openRealm类上调用静态方法即可打开Realm 。传递配置对象。我们已经看到这已经在示例中使用了包含schema密钥的配置对象:

// Get the default Realm with support for our objects
Realm.open({schema: [Car, Person]}) .then(realm => { // ...use the realm instance here }) .catch(error => { // Handle the error here if something went wrong });

有关配置对象的完整详细信息,请参阅API参考以获取配置。除此之外schema,该对象的一些更常见的键包括:

  • path:指定另一个Realm的路径
  • migration迁移功能
  • sync:一个同步对象,用于打开与Realm Object Server同步的Realm
  • inMemory:Realm将在内存中打开,并且对象不会被持久化; 一旦最后一个Realm实例关闭,所有对象都会消失
  • deleteRealmIfMigrationNeeded:如果需要迁移,删除领域; 这在开发中很有用,因为数据模型可能经常更改

默认领域

您可能已经注意到在前面的所有示例中都省略了path参数。在这种情况下,使用默认的Realm路径。您可以使用Realm.defaultPath全局属性访问和更改默认的Realm路径。

打开同步领域

您是否希望使用Realm Mobile Platform同步所有Realm数据库?所有与同步相关的文档已移至我们的平台文档中

其他领域

在不同位置持有多个领域有时很有用。例如,除了主Realm之外,您可能希望将一些数据与应用程序捆绑在Realm文件中。您可以通过path在初始化领域时指定参数来完成此操作。所有路径都相对于应用程序的可写文档目录:

// Open a realm at another path
Realm.open({ path: 'anotherRealm.realm', schema: [CarSchema] }).then(/* ... */);

架构版本

打开Realm时可用的另一个选项是schemaVersion属性。省略时,schemaVersion属性默认为0。您需要指定schemaVersion何时使用包含与先前规范不同的对象的模式初始化现有Realm。如果架构已更新且架构未更新,schemaVersion则会引发异常。

const PersonSchema = { name: 'Person', properties: { name: 'string' } }; // schemaVersion defaults to 0 Realm.open({schema: [PersonSchema]});

如果你稍后再做这样的事情:

const UpdatedPersonSchema = { // The schema name is the same, so previous `Person` object // in the Realm will be updated name: 'Person', properties: { name: 'string', dog: 'Dog' // new property } }; // this will throw because the schema has changed // and `schemaVersion` is not specified Realm.open({schema: [UpdatedPersonSchema]}); // this will succeed and update the Realm to the new schema Realm.open({schema: [UpdatedPersonSchema], schemaVersion: 1});

如果要检索Realm的当前架构版本,可以使用该Realm.schemaVersion方法执行此操作。

const currentVersion = Realm.schemaVersion(Realm.defaultPath);

同步开放的领域

您可以通过简单地调用构造函数并将配置对象传递给它来创建领域实例。通常不推荐这样做,因为它会阻塞并且可能是一个耗时的操作,特别是如果要运行迁移或者域同步并且您不希望在数据完全下载之前冒险修改数据。

如果您仍想这样做,模式很简单:

const realm = new Realm({schema: [PersonSchema]}); // You can now access the realm instance. realm.write(/* ... */);

楷模

领域数据模型由初始化期间传递到Realm的架构信息定义。对象的模式由对象name和一组属性组成。每个属性具有名称和由或包含属性的类型的字符串,或与对象描述nametypeobjectTypeoptionaldefault,和indexed字段。

const Realm = require('realm'); const CarSchema = { name: 'Car', properties: { make: 'string', model: 'string', miles: {type: 'int', default: 0}, } }; const PersonSchema = { name: 'Person', properties: { name: 'string', birthday: 'date', cars: 'Car[]' picture: 'data?', // optional property } }; // Initialize a Realm with Car and Person models Realm.open({schema: [CarSchema, PersonSchema]}) .then(realm => { // ... use the realm instance to read and modify data })

此时,通过类定义模型的支持是有限的。它在React Native中工作,但在Node中不工作。

如果要使用ES2015类(并且可能希望继承现有功能),则只需在构造函数上定义模式:

class Person {
  get fullName() { return this.firstName + ' ' + this.lastName; } } Person.schema = { name: 'Person', properties: { firstName: 'string', lastName: 'string' } };

您现在可以将类本身传递给schema打开配置的属性:

Realm.open({schema: [Person]}) .then( /* ... */ );

您可以一直访问属性:

realm.write(() => { const john = realm.create('Person', { firstName: 'John', lastName: 'Smith' }); john.lastName = 'Peterson'; console.log(john.fullName); // -> 'John Peterson' });

支持的类型

域支持下列基本类型:boolintfloatdoublestringdata,和date

  • bool属性映射到JavaScript boolean
  • int,, floatdouble属性映射到JavaScript number值。内部'int'和'double'存储为64位,而float存储为32位。
  • string 属性映射到 string
  • data 属性映射到 ArrayBuffer
  • date 属性映射到 Date

将基本属性指定为速记时,您可以仅指定类型,而不必指定具有单个条目的字典:

const CarSchema = { name: 'Car', properties: { // The following property types are equivalent make: {type: 'string'}, model: 'string', } }
可选属性

默认情况下,基本类型是非可选的,不支持存储nullundefined。通过optional在属性定义中指定指示符或使用简写语法,通过?在类型名称后附加a ,可以使属性成为可选:

const PersonSchema = { name: 'Person', properties: { realName: 'string', // required property displayName: 'string?', // optional property birthday: {type: 'date', optional: true}, // optional property } }; let realm = new Realm({schema: [PersonSchema, CarSchema]}); realm.write(() => { // optional properties can be set to null or undefined at creation let charlie = realm.create('Person', { realName: 'Charlie', displayName: null, // could also be omitted entirely birthday: new Date(1995, 11, 25), }); // optional properties can be set to `null`, `undefined`, // or to a new non-null value charlie.birthday = undefined; charlie.displayName = 'Charles'; // Setting a non-optional property to null will throw `TypeError` // charlie.realName = null; });
列表属性

除了存储单个值之外,还可以将属性声明为任何支持的基本类型的列表。这是通过附加[]类型名称来完成的:

const PersonSchema = { name: 'Person', properties: { name: 'string', testScores: 'double?[]' } }; let realm = new Realm({schema: [PersonSchema, CarSchema]}); realm.write(() => { let charlie = realm.create('Person', { name: 'Charlie', testScores: [100.0] }); // Charlie had an excused absense for the second test and was allowed to skip it charlie.testScores.push(null); // And then he didn't do so well on the third test charlie.testScores.push(70.0); });

访问列表属性时,将List返回一个对象。List具有与常规JavaScript数组非常相似的方法。最大的区别在于对a所做的任何更改都会List自动保存到底层Realm,因此它们只能在写入事务中进行修改。此外,Lists属于从中获取的基础对象 - 您只能List通过从拥有对象访问属性来获取实例,并且无法手动创建它们。

虽然list属性中的值可以是可选的,但list属性本身不能。optional使用longhand语法(values: {type: 'int[]', optional: true})指定list属性将使列表中的值可选。

关系

一对一的关系

对于一对一关系,您可以将name要引用的对象模式的属性指定为属性的类型:

const PersonSchema = { name: 'Person', properties: { // The following property definitions are equivalent car: {type: 'Car'}, van: 'Car', } };

使用对象属性时,需要确保所有引用的类型都存在于用于打开Realm的模式中:

// CarSchema is needed since PersonSchema contains properties of type 'Car'
Realm.open({schema: [CarSchema, PersonSchema]}) .then(/* ... */);

访问对象属性时,可以使用常规属性语法访问嵌套属性:

realm.write(() => { const nameString = person.car.name; person.car.miles = 1100; // create a new Car by setting the property to an object // with all of the required fields person.van = {make: 'Ford', model: 'Transit'}; // set both properties to the same car instance person.car = person.van; });

Realm中的对象属性始终是可选的,不必明确指定,也不能使其成为必需属性。

多对多关系

与基本属性一样,您也可以使用对象列表来形成多对多关系。这可以通过附加[]到目标对象模式的名称,或者通过将属性类型设置为list并指定objectType

const PersonSchema = { name: 'Person', properties: { // The following property definitions are equivalent cars: {type: 'list', objectType: 'Car'}, vans: 'Car[]' } } let carList = person.cars; // Add new cars to the list realm.write(() => { carList.push({make: 'Honda', model: 'Accord', miles: 100}); carList.push({make: 'Toyota', model: 'Prius', miles: 200}); }); let secondCar = carList[1].model; // access using an array index

与其他列表和一对一关系不同,多对多关系不能是可选的。

反向关系

链接是单向的。因此,如果to-many属性Person.dogs链接到Dog实例并且Dog.owner链接到一个属性Person,则这些链接彼此独立。将a 的属性附加DogPerson实例的dogs属性不会自动将dog的owner属性设置为this Person。因为手动同步关系对是容易出错,复杂和重复的信息,所以Realm提供链接对象属性来表示这些反向关系。

通过链接对象属性,您可以从特定属性获取链接到给定对象的所有对象。例如,一个Dog对象可以拥有一个名为的属性owners,该属性包含在其属性Person中具有此确切Dog对象的所有对象dogs。这是通过创建owners类型的属性linkingObjects然后指定它与Person对象的关系来完成的。

const PersonSchema = { name: 'Person', properties: { dogs: 'Dog[]' } } const DogSchema = { name:'Dog', properties: { // No shorthand syntax for linkingObjects properties owners: {type: 'linkingObjects', objectType: 'Person', property: 'dogs'} } }

linkingObjects属性可以指向到一个List属性(一对多的关系)或Object属性(对一的关系):

const ShipSchema = { name: 'Ship', properties: { captain: 'Captain' } } const CaptainSchema = { name: 'Captain', properties: { ships: {type: 'linkingObjects', objectType: 'Ship', property: 'captain'} } }

访问linkingObjects属性时,将Results返回一个对象,因此完全支持进一步的查询和排序linkingObject属性属于从中获取的对象,无法直接设置或操作。它们在提交事务时自动更新。

访问linkingObjects没有模式:如果你已经打开了一个域文件没有指定一个模式,例如在一个领域的功能回调,你可以得到一个linkingObjects通过调用属性linkingObjects(objectType, property)上的Object实例:

let captain = realm.objectForPrimaryKey('Captain', 1); let ships = captain.linkingObjects('Ship', 'captain');

链接对象属性不能是可选的。

默认属性值

可以通过default在属性定义中设置指示符来指定默认属性值。要使用默认值,请在对象创建期间保留未指定的属性。

const CarSchema = { name: 'Car', properties: { make: {type: 'string'}, model: {type: 'string'}, drive: {type: 'string', default: 'fwd'}, miles: {type: 'int', default: 0} } }; realm.write(() => { // Since `miles` is left out it defaults to `0`, and since // `drive` is specified, it overrides the default value realm.create('Car', {make: 'Honda', model: 'Accord', drive: 'awd'}); });

索引属性

您可以indexed向属性定义添加指示符以使该属性编入索引。这是支持的intstringbool,和date物业类型:

var BookSchema = { name: 'Book', properties: { name: { type: 'string', indexed: true }, price: 'float' } };

索引属性将极大地加速查询,其中以较慢的插入为代价比较属性的相等性。

主键

您可以primaryKey在对象模型stringint属性中指定属性。声明主键可以有效地查找和更新对象,并为每个值强制实现唯一性。将具有主键的对象添加到Realm后,无法更改主键。

const BookSchema = { name: 'Book', primaryKey: 'id', properties: { id: 'int', // primary key title: 'string', price: 'float' } };

主键属性会自动编入索引。

对领域中对象的更改 - 创建,更新和删除 - 必须在write()事务块中进行。请注意,写入事务具有不可忽略的开销; 您应该尽量减少write代码中的块数。

创建对象

使用以下create方法创建对象:

try {
  realm.write(() => { realm.create('Car', {make: 'Honda', model: 'Accord', drive: 'awd'}); }); } catch (e) { console.log("Error on creation"); }

请注意,抛出的任何异常都write()将取消该事务。该try/catch块不会在所有示例中显示,但这是一种很好的做法。

嵌套对象

如果对象具有对象属性,则可以通过为每个子属性指定JSON值来递归地创建这些属性的值:

realm.write(() => { realm.create('Person', { name: 'Joe', // nested objects are created recursively car: {make: 'Honda', model: 'Accord', drive: 'awd'}, }); });

更新对象

键入的更新

您可以通过在写入事务中设置其属性来更新任何对象。

realm.write(() => { car.miles = 1100; });
使用主键创建和更新对象

如果模型类包含主键,则可以让Realm根据其主键值智能地更新或添加对象。这是通过将true第三个参数传递给create方法来完成的:

realm.write(() => { // Create a book object realm.create('Book', {id: 1, title: 'Recipes', price: 35}); // Update book with new price keyed off the id realm.create('Book', {id: 1, price: 55}, true); });

在上面的示例中,由于对象已经存在id1并且我们已经true为第三个参数传入了值,因此更新price属性而不是尝试创建新对象。由于title省略了该属性,因此该对象保留此属性的原始值。请注意,在创建或更新具有主键属性的对象时,必须指定主键。

删除对象

可以通过delete在写入事务中调用方法来删除对象。

realm.write(() => { // Create a book object let book = realm.create('Book', {id: 1, title: 'Recipes', price: 35}); // Delete the book realm.delete(book); // Delete multiple books by passing in a `Results`, `List`, // or JavaScript `Array` let allBooks = realm.objects('Book'); realm.delete(allBooks); // Deletes all books });

查询

查询允许您从Realm获取单个类型的对象,并可选择过滤和排序这些结果。所有查询(包括查询和属性访问)在Realm中都是惰性的。只有在访问对象和属性时才会读取数据。这允许您以高效的方式表示大量数据。

执行查询时,会返回一个Results对象。结果只是您的数据视图,并且不可变。

从Realm中检索对象的最基本方法是使用a上的objects方法Realm获取给定类型的所有对象:

let dogs = realm.objects('Dog'); // retrieves all Dogs from the Realm

过滤

您可以Results通过filtered在a List或a Results上使用查询字符串调用方法来进行过滤。

例如,以下内容将更改我们之前的示例,以检索所有颜色为棕褐色且名称以“B”开头的狗:

let dogs = realm.objects('Dog'); let tanDogs = dogs.filtered('color = "tan" AND name BEGINSWITH "B"');

Realm支持的查询语言受到Apple的NSPredicate的启发。让我们简要总结一下支持的功能和语法:

  • 比较操作数可以是属性名称或常量。至少有一个操作数必须是属性名称。特殊常量falsetruenull
  • 时间戳可以以格式指定,YYYY-MM-DD@HH:MM:SS:NANOSECONDS并且YYYY-MM-DDTHH:MM:SS:NANOSECONDS可以省略纳秒。
  • 比较运算符===<=<>=>,和!=<>都支持intfloatdouble,和Date物业类型,例如age = 45
  • boolean()属性支持比较运算符===!=/ 。<>bool
  • 对于串和数据(ArrayBuffer)的属性,所述=(和==), !=(和<>), ,BEGINSWITHCONTAINSENDSWITH运营商都支持,例如name CONTAINS 'Ja'
  • 对于带有LIKE运算符的字符串,可以进行通配符比较,例如name LIKE '*an?'匹配“Jane”,“Dan”,“Shane”等。
  • 使用[c]例如字符串的字符串不区分大小写的比较CONTAINS[c] 'Ja'。请注意,只有字符“AZ”和“az”才会被忽略。
  • Realm支持以下复合运算符:AND&&OR||NOT!,例如name BEGINSWITH 'J' AND age >= 32
  • 该集合表达式@count@size@min@max@sum并且@avg都支持列表属性,如employees.@count > 5发现有更多的5个元素员工的清单。
  • 字符串和二进制属性的聚合表达式@count@size,例如name.@size = 5,查找名称为5个字母的所有字符串。
  • 关键路径可以遵循列表属性关系,例如child.age >= 13cars.@avg.milage > 1000
  • 关键路径也可以跟随链接对象(反向链接),例如parents.age > 25parents.@count == 2
  • $操作者可用于替代参数,例如child.age >= $0(见下面的示例)。
  • 排序和查找不同的值是可能的功能SORTDISTINCTage > 20 SORT(name ASC, age DESC) DISTINCT(name)
    • 用于排序的排序可以是以下不区分大小写的文字中的一个:ASCASCENDINGDESCDESCENDING
    • 括号内的逗号分隔列表中可以显示任意数量的属性。
    • 可以指示任意数量的排序/不同条件,它们将按指定的顺序应用。
    • Sort或distinct不能独立运行,这些条件必须附加到至少一个查询过滤器。

关于如何查询Realm的一个非常重要的例子是:

const Realm = require('realm'); const CarSchema = { name: 'Car', properties: { make: 'string', model: 'string', miles: {type: 'int', default: 0}, } }; const PersonSchema = { name: 'Person', properties: { name: 'string', cars: {type: 'list', objectType: 'Car'}, } }; // Initialize a Realm with Car and Person models Realm.open({schema: [CarSchema, PersonSchema]}) .then(realm => { // Add persons and their cars realm.write(() => { let john = realm.create('Person', {name: 'John', cars: []}); john.cars.push({make: 'Honda', model: 'Accord', miles: 1500}); john.cars.push({make: 'Toyota', model: 'Prius', miles: 2780}); let joan = realm.create('Person', {name: 'Joan', cars: []}); joan.cars.push({make: 'Skoda', model: 'Octavia', miles: 1120}); joan.cars.push({make: 'Ford', model: 'Fiesta', miles: 95}); joan.cars.push({make: 'VW', model: 'Golf', miles: 1270}); let jill = realm.create('Person', {name: 'Jill', cars: []}); let jack = realm.create('Person', {name

转载于:https://www.cnblogs.com/strengthen/p/11166081.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值