由于项目需要存储多条记录消息,所以这里记录如何使用React-Native操作SQLite数据库
我使用的是react-native-sqlite-storage
Android端的配置为:
npm install react-native-sqlite-storage --save
安装完成后进行链接
react-native link react-native-sqlite-storage
然后进入android
子目录,在setting.gradle
文件的include ':app'
上面一行添加:
include ':react-native-sqlite-storage'
project(':react-native-sqlite-storage').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sqlite-storage/src/android')
再在app/build.gradle
文件的dependencies
中添加:
dependencies {
...
compile project(':react-native-sqlite-storage')
}
最后在app/src/java/com/[项目名]/MainApplication.java
文件中添加修改成如下内容:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new SQLitePluginPackage()
);
}
至此Android
端的配置也完成了。
IOS端的配置为:
首先在RN的根目录下安装sqlite
的包:
npm install --save react-native-sqlite-storage
然后进行link
rnpm link
rnpm 即 React Native Package Manager,是react native的专门的包管理工具。
如果还没有安装过rnpm
或者link
报错,可以尝试一下命令:
npm -g install rnpm xcode
通常情况经过上述两步即可完成依赖的配置工作。当然官方还提供了使用pod
以及手动link的教程,由于比较繁琐这里不赘述了,留个传送门
使用方式为:
在index.js
中添加
import SQLite from 'react-native-sqlite-storage';
SQLite.DEBUG(true);
SQLite.enablePromise(true);
这样添加的好处是可以将SQLite
作为一个全局对象去使用。包括数据库的打开、连接等操作均可以这么处理。
SQLite.openDatabase({name: 'my.db', location: 'default'}, successcb, errorcb);
在Android
下,由于数据库文件位于固定位置,所以location
参数是无效的。
在IOS
下,location
有以下3个可选参数:分别为
default
:数据文件会放置在Library/LocalDatabase
子目录下,对iTunes不可见,也不会被iCloud备份
Library
:数据文件会放置在Library
子目录下,对iTunes不可见,但是会iCloud备份
Documents
:数据文件会放置在Library
子目录下,对iTunes可见,同时会iCloud备份
也可以不在index.js中添加SQLite代码,而是单独定义一个sqlite.js文件,把数据库操作定义好,在其他需要进行数据库操作的地方引入sqlite.js,然后调用插入或者查询即可
示例如下:
编写sqlite.js文件,引入组件 import SQLiteStorage from 'react-native-sqlite-storage';
注意每一个transaction后面(err)=>{ console.log(err) }打印异常,不然可能看不到哪里出错了
import React,{Component} from 'react';
import SQLiteStorage from 'react-native-sqlite-storage';
SQLiteStorage.DEBUG(true);
var database_name = "notify.db";//数据库文件
var database_version = "1.0";//版本号
var database_displayname = "notifyDB";
var database_size = -1;//-1应该是表示无限制
var db;
export default class SQLiteHelper extends Component{
constructor(props){
super(props)
this.init()
}
//在组建被加载的时候进行初始化操作
componentDidMount(){
if (!db) {
this.open();
}
}
//在组件被销毁的时候关闭数据库连接
componentWillUnmount(){
if(db){
this._successCB('close');
db.close();
}else {
console.log("SQLiteStorage not open");
}
}
init(){
if (!db) {
this.open();
}
}
//打开数据库连接
open(){
db = SQLiteStorage.openDatabase(
database_name,
database_version,
database_displayname,
database_size,
()=>{
this._successCB('open');
},
(err)=>{
this._errorCB('open',err);
}
);
return db;
}
//创建表
createTable(){
if (!db) {
this.open();
}
//创建通知消息表
/**本地存储的通知消息表字段如下:
* notify_type 通知类型,0:系统通知;1:系统公告;2:平台活动
* notify_message_id 唯一标识一条通知消息的id
* notify_time 接收到通知的时间(yyyy-MM-dd HH:mm:ss)
* notify_title 通知消息的标题
* notify_content 通知消息的内容
* notify_state 通知消息的状态,0:未读;1:已读
*/
db.transaction((tx)=> {
tx.executeSql('CREATE TABLE IF NOT EXISTS NOTIFY(' +
'id INTEGER PRIMARY KEY AUTOINCREMENT,' +
'notify_user_id VARCHAR,'+
'notify_type INTEGER,'+
'notify_message_id VARCHAR,' +
'notify_time VARCHAR,' +
'notify_title VARCHAR,' +
'notify_content VARCHAR,' +
'notify_state INTEGER)'
, [], ()=> {
this._successCB('executeSql');
}, (err)=> {
this._errorCB('executeSql', err);
});
}, (err)=> {//所有的 transaction都应该有错误的回调方法,在方法里面打印异常信息,不然你可能不会知道哪里出错了。
this._errorCB('transaction', err);
}, ()=> {
this._successCB('transaction');
})
}
//删除整张表数据
deleteData(){
if (!db) {
this.open();
}
db.transaction((tx)=>{
tx.executeSql('delete from notify',[],()=>{
});
});
}
//删除表
dropTable(){
db.transaction((tx)=>{
tx.executeSql('drop table notify',[],()=>{
});
},(err)=>{
this._errorCB('transaction', err);
},()=>{
this._successCB('transaction');
});
}
//向表中插入数据
insertNotifyData(notifyData){
let len = notifyData.length;
if (!db) {
this.open();
}
this.createTable();
/**本地存储的通知消息表字段如下:
* notify_user_id 通知的用户id,用来唯一标识某一个用户
* notify_type 通知类型,0:系统通知;1:系统公告;2:平台活动
* notify_message_id 唯一标识一条通知消息的id
* notify_time 接收到通知的时间(yyyy-MM-dd HH:mm:ss)
* notify_title 通知消息的标题
* notify_content 通知消息的内容
* notify_state 通知消息的状态,0:未读;1:已读
*/
db.transaction((tx)=>{
for(let i=0; i<len; i++){
let notify = notifyData[i];
let notifyUserId = notify.notifyUserId;
let notifyType = notify.notifyType;
let notifyMessageId = notify.notifyMessageId;
let notifyTime = notify.notifyTime;
let notifyTitle = notify.notifyTitle;
let notifyContent = notify.notifyContent;
let notifyState = notify.notifyState;
let sql = "INSERT INTO NOTIFY(notify_user_id, notify_type, notify_message_id, notify_time, notify_title, notify_content, notify_state)"+
"values(?,?,?,?,?,?,?)";
tx.executeSql(sql, [notifyUserId, notifyType, notifyMessageId, notifyTime, notifyTitle, notifyContent, notifyState],
()=>{
console.log('insertNotifyData success');
},(err)=>{
console.log('insertNotifyData error: ' + err);
}
);
}
},(error)=>{
this._errorCB('transaction', error);
//ToastAndroid.show("数据插入失败",ToastAndroid.SHORT);
},()=>{
this._successCB('transaction insert data');
//ToastAndroid.show("成功插入 "+len+" 条用户数据",ToastAndroid.SHORT);
});
}
//查询表中数据
queryNotifyData(params, callback){
if (!db) {
this.open();
}
//查询
db.transaction((tx)=>{
tx.executeSql("select * from notify where notify_user_id =? order by notify_time desc", [params.userId], (tx,results)=>{
var len = results.rows.length;
let result=[]
//遍历处理返回数组的格式,方便界面上渲染处理
for(let i=0; i<len; i++){
result.push(results.rows.item(i))
}
console.log('queryNotifyData success: ' + JSON.stringify(result));
callback&&callback(true, result)
});
},(error)=>{
console.log('queryNotifyData error: ' + JSON.stringify(error));
callback&&callback(false, error)
});
}
//将所有消息的状态更新为已读
updateNotifyData(params, callback){
if (!db) {
this.open();
}
db.transaction((tx)=>{
tx.executeSql("update notify set notify_state=1 where notify_user_id=?", [params.userId],
(tx, result)=>{
console.log('updateNotifyData' + result);
callback&&callback(true, result)
},
(error)=>{
console.log('updateNotifyData error: ' + error);
callback&&callback(false, result)
}
);
})
}
//关闭数据库连接
close(){
if(db){
this._successCB('close');
db.close();
}else {
console.log("SQLiteStorage not open");
}
db = null;
}
_successCB(name){
console.log("_successCB SQLiteStorage "+name+" success");
}
_errorCB(name, err){
console.log("SQLiteStorage " + name);
console.log('_errorCB error: ' + err);
}
render(){
return null;
}
};
在其他类中调用,使用时先引入sqlite.js
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Navigator,
StyleSheet,
} from 'react-native';
import SQLite from './sqlite';
var sqLite = new SQLite();
var db;
class App extends Component{
compennetDidUnmount(){
sqLite.close();
}
componentWillMount(){
//开启数据库
if(!db){
db = sqLite.open();
}
//插入数据
let notify = {}
let { login } = store.getState();
notify.notifyUserId = login.userNo;
//系统通知,后台的CommonConst.NOTIFY_TYPE定义的常量
if(result.extras.notifyType === '0'){
notify.notifyType = '系统通知';
}else if(result.extras.notifyType === '1'){
//平台公告
notify.notifyType = '平台公告';
}else if(result.extras.notifyType === '2'){
//平台活动
notify.notifyType = '平台活动';
}
notify.notifyMessageId = result.messageID;
notify.notifyTime = moment().format('MM-DD HH:mm');
notify.notifyTitle = result.title;
notify.notifyContent = result.content;
notify.notifyState = 0; //接收到后台的消息默认都是未读
let sqlite = new SQLiteHelper();
sqlite.insertNotifyData([notify]);
//查询和更新数据
let { login } = store.getState();
let queryParams = {userId:''};
queryParams.userId = login.userNo;
sqlite.queryNotifyData(queryParams, (resultType, result) =>{
if(resultType){
console.log('queryNotifyData success result ' + JSON.stringify(result));
//本次查询之后需要再把所有的state状态修改为已读
sqlite.updateNotifyData(queryParams, (resultType, result) =>{
if(resultType){
console.log('updateNotifyData success userId: ' + queryParams.userId);
}
})
}else{
console.log('queryNotifyData error result ' + JSON.stringify(result));
}
})
render(){
return null;
}
}