存储:与AsyncStorage相比,Realm更应该作为重点掌握内容

储存

本章提要
1.AsyncStorage
2.Realm
一个应用总是要存些东西的,我们要怎么做才能把数据存起来呢?我们这里有两个选择,一个是使用官方提供的AsyncStorage另一个是使用小型数据库。

当数据量不大,结构很简单的时候,我们来使用AsyncStorage这个key-value储存系统,当数据量较大的时候,我们就需要使用小型数据库了,这里我们
会学习一个叫做Realm的数据库。

首先,我们来看看AsyncStorage吧~

AsyncStorage

与数据打交道,免不了对数据进行增加,删除,更改和查找。我们来看看如何用AsyncStorage实现这些。

增加数据:

1
2
3
4
5
6
7
8
9
10
11
12
``
save(key, value) {
AsyncStorage.setItem(key,value).then(
(errs)=>{
if (!errs) {
//xxx
}else {
//xxx
}
})
}
``

在这里,我们使用了promise,这样会使代码看起来舒服很多。虽然看起来很多,实际上,只要知道

1
AsyncStorage.setItem(key,value)

就可以了,我们用setItem来将key和value存储起来,看到这里想必你已经知道了为什么AsyncStorage是key-value系统了。

由于有了key,所以我们可以用key进行查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
get(key) {
AsyncStorage.getItem(key)
.then(
(result)=> {
if (!result) {
//xxx
}
//返回结果
}
).catch((error)=> {
//错误处理
}
}

数据我们存完了,但是如果数据没用了怎么办?删掉呗。和查询数据很像,删除也需要用到key:

1
2
3
4
5
6
7
8
9
10
del(key) {
AsyncStorage.removeItem(key).
then(
()=>{
//删除成功
}
).catch((error)=> {
//错误处理
}
}

至于修改数据,其实写法和增加数据一样,当你需要修改一项数据的时候,直接传入key和一个新的值就可以了。

Realm

前面的AsyncStorage只能存些小东西,数据量一大就开始捉襟见肘了,到了这种时候就该用Realm了。
其实用SQLite也行,不过不怎么好用,索性就不用了。当初作者君在用Realm的时候版本号才是0.14转眼间就到1.0.0了,所以请放心的使用Realm吧。

Realm并不是React Native自己就有的,所以我们需要安装Realm:

1
npm install --save realm

安装好后大概是这样:

PNG

然后执行

1
react-native link realm

PNG

装完Realm之后得重新构建一下App:

1
react-native run-android

Tips:由于网络的问题呢,可能会构建失败,多试几次就可以构建完成了

接下来测试一下Realm是不是安装成功了,先是引入Realm:

1
import Realm from 'realm';

下面是Realm官方文档的例子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export default class <project-name> extends Component {
render() {
let realm = new Realm({
schema: [{name: 'Dog', properties: {name: 'string'}}]
});
realm.write(() => {
realm.create('Dog', {name: 'Rex'});
});
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Count of Dogs in Realm: {realm.objects('Dog').length}
</Text>
</View>
);
}
}

<project-name>是你的项目名称,别弄错了。然后刷新一下,界面上的数字就会加1。如果程序可以顺利运行,
Realm就已经安装好了。

先简单的解释一下上面的代码,首先我们新建了一个叫做Dog的Schema,下面的write是写入数据,组件中的
realm.objects('Dog').length会返回Dog中的数据个数。每次刷新App,都会写入一条数据,所以数字会加一。

有了一个简单的认识之后,让我们来详细的了解Realm吧!

Schema

在使用Realm的时候离不开Schema,一个大些的App一般会用到多个Schema,所以在正式使用Realm的时候
不能像上面的例子一样敷衍,我们需要进行一个简单的封装。新建一个叫Schema.js文件,它可以在app文件夹下(没有app文件夹就自己新建一个),

在文件头部引入Realm:

1
import Realm from 'realm';

然后创建一个叫Todo的class:

1
class Todo extends Realm.Object {}

不喜欢这个名字的话,你可以自己随便起一个名字。

然后来写Schema:

1
2
3
4
5
6
7
8
Todo.schema = {
name:'Todo',
primaryKey: 'id',
properties: {
title: {type: 'string'},
id: {type: 'string', indexed: true},
}
}

这里我们用id来作为主键,由于这个id具有唯一性,我们一会儿会写一个小程序来生成id。

然后导出模块:

1
2
3
4
export default new Realm({schema: [Todo]})
```
如果你需要多个Schema,在后面加上就好:

export default new Realm({schema: [Todo, Category, xxx, xxx]})

1
2
3
4
然后在你需要使用储存的地方引入Schema.js。
比如这样引入:

import realm from ‘./Schema’;
//注意文件位置

1
2
然后写一个生成id(为了不生成重复的id,我们使用guid,别管这是啥,只要知道这东西一般不会重复就好了)的函数:

const guid = () => {
return ‘xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx’
.replace(/[xy]/g, (c) => {
var r = Math.random() * 16 | 0, v = c == ‘x’ ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

1
2
3
4
接下来,我们来看如何去用Realm(也就是增删改查)。
我们来写一个输入框来收集数据:

1
2
3
4
![PNG](https://meowv.github.io/images/6.4.png)
不出意外的话,下边会有一个黄色的提示(前边的章节有说过),先不要管它,我们一会儿解决。
为了储存数据,我们需要把输入的文字放到state里面,上面的`onChangeText`就是干这个的,对了,别忘记加一个叫title的状态:

constructor(props){
super(props);
this.state = {
text: null
};
}

1
2
Ok,搞定这些后我们来写一个写入数据的方法,我们起名叫write,write应该写在constructor下边:

write(){
realm.write(()=>{
realm.create(‘Todo’,{ title: this.state.title, id: guid() });
});
}

1
2
3
4
写入数据需要用到`realm.write()`和`realm.create()`,Todo是Schema,后边跟着的是要写入的数据,title是从
state中取出来的,然后我们调用`guid()`来生成一个不重复的id。
接下来把这个方法绑到按钮上,实现点击添加数据:

{‘\n’}

1
2
然后把数据放到state里:

this.state = {
text: null,
data: realm.objects(‘Todo’)
};

1
2
在换行符下面继续写:

{ this.state.data.length }

1
2
然后才是重点,Realm是可以使数据实时更新的,只要增加一个监听就好了,我们把这个监听写在构造里面:

this.state = {…}
realm.addListener(‘change’, () => {
this.forceUpdate()
});

1
2
3
4
然后输入一个数据,保存,下面的数字就可以实时的变化了~
然后我们来看查询是怎样的,界面的话把上面的代码复制过去,改几个字就好:

1
2
然后把find放到state里,正如我们之前做过的一样:

this.state = {
text: null,
find: null,
data: realm.objects(‘Todo’)
};

1
2
然后我们写一个叫find的方法,这个方法稍稍有些复杂:

find () {
realm.objects(‘Todo’)
.filtered(‘title = ‘ + ‘“‘ + this.state.find + ‘“‘)
.forEach(result => ToastAndroid.show(result.id, ToastAndroid.SHORT));
}

1
2
3
4
5
6
7
8
9
10
11
12
我们借助了一个叫做`ToastAndroid`的组件来实现显示查找结果的id,所以别忘记引入这个组件。
`filtered`是一个过滤器,我们在里面写查询代码,注意喽,查询的值应该是一个字符串所以在外面包裹了双引号。
由于返回的结果稍稍有些复杂,所以我们用`forEach`来处理一下,使其获得id。
效果应该是这个样子的:
![PNG](https://meowv.github.io/images/6.5.png)
至于修改和删除就很简单了,所以这里只给出核心代码,作者君知道你很聪明,所以来想想具体怎么用把~
修改:

realm.write(() => {
realm.create(‘Todo’, { id: xxx, title: xxx }, true);
});

1
2
删除:

realm.write(() => {
const todo = realm.objects(‘Todo.filtered(‘id = xxxxx’);
realm.delete(todo);
});
```

小提示:

唔?ID真的没有用吗?具体可以起到什么作用呢?

想明白这两点,修改和删除就没问题了。另外,有没有发现修改,增加,删除都是在write中进行的呢?

×

谢谢你请我吃辣条

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 储存
    1. 1.1. AsyncStorage
    2. 1.2. Realm
      1. 1.2.1. Schema
,