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

Flutter启动时向SQLite表初始化写入固定常量数据实现方法

Flutter 启动自动初始化数据库预置数据实现方案

前置修复(必做,否则数据插入/查询会失败)

你现有代码存在2处字段不匹配问题,先修正:

  • 修复specializeArea表建表语句,给id列添加主键约束,避免重复插入同id数据
    找到DbHelper.dart里的_onCreate方法中创建specializeArea表的代码,替换为:
    await db.execute("CREATE TABLE $Table_specializeArea ("
        " $C_UserID INTEGER PRIMARY KEY, "
        " $C_Area TEXT )");
    
  • 修复specializeModel.dart的字段映射,和数据库列名对齐
    把toMap、fromMap方法里的user_areakey改成和数据库列一致的area:
    Map<String, dynamic> toMap() {
      var map = <String, dynamic>{
        'id': user_id,
        'area': user_area,
      };
      return map;
    }
    
    specializeModel.fromMap(Map<String, dynamic> map) {
      user_id = map['id'];
      user_area = map['area'];
    }
    

如果是开发调试阶段,修改完建表语句后建议先卸载旧应用重装,避免旧库表结构不匹配报错。

核心实现:预置数据自动写入逻辑

1. 在DbHelper中添加预置数据插入方法

该方法会先判断specializeArea表是否已有数据,无数据才写入,避免每次启动重复插入冗余数据:

// 插入预置专业领域数据
Future<void> _insertPresetSpecializeArea() async {
  var dbClient = await db;
  // 先查表内数据量
  var countRes = await dbClient.rawQuery("SELECT COUNT(*) as count FROM $Table_specializeArea");
  int count = Sqflite.firstIntValue(countRes);
  // 已有数据直接返回,不重复插入
  if (count > 0) return;

  // 这里替换成你需要的5组预置数据,id不要重复
  List<specializeModel> presetAreas = [
    specializeModel("1", "计算机科学与技术"),
    specializeModel("2", "电子信息工程"),
    specializeModel("3", "生物医学工程"),
    specializeModel("4", "材料科学与工程"),
    specializeModel("5", "机械工程"),
  ];

  // 批量插入,使用事务提升插入效率
  await dbClient.transaction((txn) async {
    for (var area in presetAreas) {
      await txn.insert(Table_specializeArea, area.toMap());
    }
  });
}

2. 修改数据库初始化逻辑,启动时自动触发预置数据写入

找到DbHelper里的initDb方法,在openDatabase完成后调用上面的预置插入方法:

initDb() async {
  io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
  String path = join(documentsDirectory.path, DB_Name);
  var db = await openDatabase(path, version: Version, onCreate: _onCreate);
  // 库初始化完成后检查并写入预置数据
  await _insertPresetSpecializeArea();
  return db;
}

这个逻辑不管是首次安装创建数据库,还是后续冷启动打开已有数据库,都会校验预置数据是否存在,不会出现重复插入问题,也不需要每次启动都删表重写。

扩展:预置数据查询(方便后续渲染交互按钮)

在DbHelper中添加查询所有专业领域数据的方法,供页面调用:

// 查询所有预置专业领域数据
Future<List<specializeModel>> getAllSpecializeAreas() async {
  var dbClient = await db;
  var res = await dbClient.query(Table_specializeArea);
  return res.map((e) => specializeModel.fromMap(e)).toList();
}

页面调用示例

在HomeForm的initState里调用查询方法,拿到数据后就可以渲染成按钮组件:

// 新增状态变量存储领域列表
List<specializeModel> areaList = [];

@override
void initState() {
  super.initState();
  getUserData();
  dbHelper = DbHelper();
  // 初始化时加载预置领域数据
  loadAreaData();
}

Future<void> loadAreaData() async {
  List<specializeModel> list = await dbHelper.getAllSpecializeAreas();
  setState(() {
    areaList = list;
  });
}

后续在build方法里,你之前预留的//Specialization area注释位置,用ListView或者Wrap组件遍历areaList渲染按钮即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 00:54:44