You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TypeORM适配Ionic 5/6?附SQLite schema变更疑问

Ionic 5/6 本地数据持久化方案:TypeORM 配置与 SQLite Schema 变更管理

一、Ionic 5/6 结合 TypeORM 实现本地设备数据持久化配置

以下是经过验证的实操步骤,适配 Capacitor 环境(Ionic 5/6 主流适配方案):

1. 安装依赖

执行以下命令安装核心依赖及 Capacitor SQLite 驱动:

npm install typeorm reflect-metadata @capacitor/sqlite
npx cap sync

同时修改 tsconfig.json,启用 TypeScript 装饰器支持:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

2. 配置 TypeORM 数据源

在项目根目录创建 data-source.ts,配置数据库连接信息:

import { DataSource } from "typeorm";
import { CapacitorSQLite } from "@capacitor/sqlite";
// 导入自定义实体类,后续步骤定义
import { User } from "./entities/User";

export const AppDataSource = new DataSource({
  type: "capacitor",
  driver: CapacitorSQLite,
  database: "app_local_db", // 自定义数据库名称
  entities: [User], // 所有实体类集合
  synchronize: false, // 生产环境必须关闭,避免自动修改 schema
  migrations: ["src/migrations/**/*.ts"], // 迁移文件路径
  logging: false,
});

3. 定义实体类

在 src/entities/ 目录下创建实体文件(如 User.ts),用装饰器映射数据库表结构:

import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ nullable: false })
  username: string;

  @Column({ nullable: true })
  avatar: string;
}

4. 初始化数据源

在 app.component.ts 的初始化逻辑中启动数据源:

import { Component } from '@angular/core';
import { AppDataSource } from './data-source';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {
  constructor() {
    this.initializeApp();
  }

  async initializeApp() {
    // 其他初始化逻辑(如平台就绪)
    try {
      await AppDataSource.initialize();
      console.log('TypeORM 数据源初始化成功');
    } catch (error) {
      console.error('TypeORM 初始化失败:', error);
    }
  }
}

5. 数据操作示例

创建服务类封装 CRUD 逻辑,以 UserService.ts 为例:

import { Injectable } from '@angular/core';
import { Repository } from 'typeorm';
import { User } from '../entities/User';
import { AppDataSource } from '../data-source';

@Injectable({ providedIn: 'root' })
export class UserService {
  private userRepo: Repository<User>;

  constructor() {
    this.userRepo = AppDataSource.getRepository(User);
  }

  async getUsers(): Promise<User[]> {
    return this.userRepo.find();
  }

  async addUser(user: Omit<User, 'id'>): Promise<User> {
    return this.userRepo.save(user);
  }
}

关键注意事项

  • 开发阶段可临时开启 synchronize: true 自动同步实体与表结构,但生产环境必须关闭,改用迁移脚本管理 schema。
  • 确保 @capacitor/sqlite 与 typeorm 版本兼容(建议使用最新稳定版)。

二、SQLite Schema 变更管理方案

如果继续使用原生 SQLite,可通过版本化迁移脚本实现 schema 安全变更:

1. 初始化版本控制表

创建 schema_version 表记录当前数据库版本,确保每次启动都能识别需要执行的迁移:

CREATE TABLE IF NOT EXISTS schema_version (
  version INTEGER PRIMARY KEY NOT NULL
);
INSERT OR IGNORE INTO schema_version (version) VALUES (1);

2. 编写版本化迁移脚本

为每个 schema 变更编写独立脚本,确保脚本幂等(重复执行不会报错):

-- 迁移至版本 2:为 user 表添加 phone 字段
ALTER TABLE user ADD COLUMN phone TEXT;
UPDATE schema_version SET version = 2;
-- 迁移至版本 3:创建 orders 表
CREATE TABLE IF NOT EXISTS orders (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id INTEGER,
  amount REAL,
  FOREIGN KEY (user_id) REFERENCES user(id)
);
UPDATE schema_version SET version = 3;

3. 应用启动时执行迁移

在应用初始化逻辑中,检查当前版本并执行未完成的迁移,用事务保证原子性:

import { CapacitorSQLite } from '@capacitor/sqlite';

async runMigrations() {
  const db = await CapacitorSQLite.createConnection({ database: 'app_local_db' });
  await db.open();

  // 获取当前版本
  const versionRes = await db.query('SELECT version FROM schema_version');
  let currentVersion = versionRes.values[0]?.version || 0;

  // 按版本顺序定义迁移脚本
  const migrations = [
    {
      version: 1,
      script: `
        CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL);
        INSERT OR IGNORE INTO schema_version (version) VALUES (1);
      `
    },
    { version: 2, script: /* 版本2脚本 */ },
    { version: 3, script: /* 版本3脚本 */ }
  ];

  // 执行未完成的迁移
  for (const migration of migrations) {
    if (migration.version > currentVersion) {
      try {
        await db.run(migration.script);
        currentVersion = migration.version;
      } catch (error) {
        console.error(`迁移至版本 ${migration.version} 失败:`, error);
        // 可添加回滚或报错提示逻辑
        break;
      }
    }
  }

  await db.close();
}

关键注意事项

  • 复杂变更(如拆分表、修改字段类型)需先备份数据,迁移完成后恢复,避免数据丢失。
  • 所有迁移脚本需在测试环境验证通过后,再部署到生产环境。

内容的提问来源于stack exchange,提问作者The Sammie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:40:25