Ionic 3中接入外部SQLite数据库的实现方法咨询
嘿,刚入门开发就碰到这么实用的需求——离线存储建筑数据+联网同步,这在Ionic 3里用SQLite完全能搞定!我给你一步步拆解实现步骤:
一、先安装必要的SQLite插件和依赖
Ionic 3依赖的是Ionic Native 4.x版本,所以要安装对应版本的包:
- 安装Cordova SQLite插件:
ionic cordova plugin add cordova-sqlite-storage - 安装Ionic Native封装的SQLite服务:
npm install --save @ionic-native/sqlite@4
二、在App模块中注册SQLite服务
打开src/app/app.module.ts,导入SQLite并添加到服务提供者数组里,这样整个应用都能注入使用:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { IonicModule, IonicApp } from 'ionic-angular'; import { MyApp } from './app.component'; import { SQLite } from '@ionic-native/sqlite'; @NgModule({ declarations: [MyApp], imports: [BrowserModule, IonicModule.forRoot(MyApp)], bootstrap: [IonicApp], entryComponents: [MyApp], providers: [SQLite] // 注册SQLite服务 }) export class AppModule {}
三、创建数据库操作服务(推荐封装成Service)
为了代码更整洁、复用性更高,建议创建一个专门的数据服务来处理所有SQLite操作,比如src/providers/data-service/data-service.ts:
import { Injectable } from '@angular/core'; import { SQLite, SQLiteObject } from '@ionic-native/sqlite'; import { Platform } from 'ionic-angular'; @Injectable() export class DataService { private db: SQLiteObject; constructor(private sqlite: SQLite, private platform: Platform) { // 必须等平台准备好再初始化数据库(Cordova插件依赖平台环境) this.platform.ready().then(() => { this.initDatabase(); }); } // 初始化/打开本地数据库 private async initDatabase() { try { this.db = await this.sqlite.create({ name: 'building_data.db', // 数据库文件名,会存在设备本地存储 location: 'default' // 默认存储位置,不同平台自动适配 // 如果是预填充的外部数据库,需要先把.db文件放到assets,复制到可访问路径后再指定这里的参数 }); console.log('数据库连接成功!'); // 创建建筑数据表(如果不存在的话) await this.db.executeSql(`CREATE TABLE IF NOT EXISTS buildings ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, area REAL, sync_status INTEGER DEFAULT 0 -- 0=未同步,1=已同步,用于后续同步判断 )`, []); } catch (error) { console.error('数据库初始化失败:', error); } } // 示例:离线插入建筑数据 async addBuilding(building: any) { if (!this.db) throw new Error('数据库未初始化'); const result = await this.db.executeSql( 'INSERT INTO buildings (name, address, area) VALUES (?, ?, ?)', [building.name, building.address, building.area] ); return result.insertId; } // 示例:获取未同步的建筑数据(用于联网时同步到服务器) async getUnsyncedBuildings() { if (!this.db) return []; const result = await this.db.executeSql( 'SELECT * FROM buildings WHERE sync_status = 0', [] ); const buildings = []; for (let i = 0; i < result.rows.length; i++) { buildings.push(result.rows.item(i)); } return buildings; } // 示例:标记数据为已同步 async markAsSynced(buildingId: number) { if (!this.db) return; await this.db.executeSql( 'UPDATE buildings SET sync_status = 1 WHERE id = ?', [buildingId] ); } }
四、在页面中调用服务实现业务逻辑
比如在某个页面的ts文件里注入DataService,就能轻松实现离线存储和同步:
import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; import { DataService } from '../../providers/data-service/data-service'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { constructor(public navCtrl: NavController, private dataService: DataService) {} // 离线保存建筑数据 async saveBuildingOffline() { const newBuilding = { name: 'XX商业综合体', address: 'XX市XX区XX大道', area: 12000.8 }; try { const id = await this.dataService.addBuilding(newBuilding); console.log('数据已离线保存,ID:', id); } catch (error) { console.error('保存失败:', error); } } // 联网时同步数据到服务器 async syncWithServer() { // 先通过Network插件检查网络状态(需额外安装@ionic-native/network@4) // 然后获取本地未同步的数据 const unsyncedBuildings = await this.dataService.getUnsyncedBuildings(); if (unsyncedBuildings.length === 0) { console.log('没有需要同步的数据'); return; } // 调用你的服务器API上传数据(这里替换成你的实际接口逻辑) // const syncResult = await this.apiService.post('/buildings/sync', unsyncedBuildings); // if (syncResult.success) { // // 标记已同步的数据 // for (const building of unsyncedBuildings) { // await this.dataService.markAsSynced(building.id); // } // console.log('数据同步成功!'); // } } }
五、关于“外部SQLite数据库”的额外说明
如果你说的是预填充好的外部.db文件(比如已经包含大量建筑数据的数据库),需要额外做以下步骤:
- 把预填充的
building_data.db文件放到src/assets目录下 - 安装Cordova File插件和对应的Ionic Native封装:
ionic cordova plugin add cordova-plugin-file、npm install --save @ionic-native/file@4 - 在DataService的
initDatabase前添加复制文件的逻辑:
private async copyPreloadedDb() { const dbName = 'building_data.db'; const sourcePath = `assets/${dbName}`; const targetPath = this.file.dataDirectory + dbName; // 检查目标路径是否已有数据库文件,避免重复复制 const exists = await this.file.checkFile(this.file.dataDirectory, dbName); if (!exists) { await this.file.copyFile('assets/', dbName, this.file.dataDirectory, dbName); console.log('预填充数据库已复制完成'); } }
然后在initDatabase里先调用this.copyPreloadedDb(),再执行数据库连接逻辑。
一些关键注意事项
- 必须在
platform.ready()之后操作数据库,否则Cordova插件会失效 - 异步操作尽量用
async/await或Promise,避免回调嵌套 - 同步数据时要处理网络异常,比如失败后重试、标记数据状态
- 定期备份本地数据库,防止设备故障导致数据丢失
内容的提问来源于stack exchange,提问作者Minte Temple
相关产品推荐
相关产品推荐

