【问题标题】:Insert multiple records in Sqflite在 Sqflite 中插入多条记录
【发布时间】:2019-10-15 20:34:15
【问题描述】:

如何在sqflite中快速插入多条记录?标准的快速方法是:

await database.insert(table, object.toMap())

但我不认为用循环一对一地插入记录是一个好主意。 或者我可以插入所有带有事务的列表?

【问题讨论】:

  • 有批量操作,你试过吗?
  • 不,我还没试过。你有一个小例子吗?你可以用答案解释,谢谢。

标签: sqlite flutter sqflite


【解决方案1】:

在这种情况下,您可以使用批处理。

batch = db.batch();
batch.insert('Test', {'name': 'item'});
batch.update('Test', {'name': 'new_item'}, where: 'name = ?', whereArgs: ['item']);
batch.delete('Test', where: 'name = ?', whereArgs: ['item']);
results = await batch.commit();

大批量,可以使用await batch.commit(noResult: true);

【讨论】:

  • 好的,在我的提问中,我说是否有一个快速的方法:batch.insert(tableName, map);有可能吗?
  • 是的,它会起作用的,如果不看看这个例子,他已经提出了很好的例子。 github.com/AndriousSolutions/dbutils/blob/…
【解决方案2】:

正如我在评论中提到的,您可以使用Batch。这是示例。

Batch batch = db.batch();
batch.insert('Test', {'name': 'item'});
batch.update('Test', {'name': 'new_item'}, where: 'name = ?', whereArgs: ['item']);
batch.delete('Test', where: 'name = ?', whereArgs: ['item']);

现在,如果您正在寻找结果(这将花费您一些内存),您可以使用

results = await batch.commit();

如果您正在寻找快速的性能,只需忽略结果并使用

await batch.commit(noResult: true);

Source

【讨论】:

    【解决方案3】:

    如果你有一个要插入的对象列表,你可以这样做(这不是一个非常干净的代码,但它有效):

      insertClients(List<Client> clients) async {
        final db = await database;
        var buffer = new StringBuffer();
        clients.forEach((c) {
          if (buffer.isNotEmpty) {
            buffer.write(",\n");
          }
          buffer.write("('");
          buffer.write(c.firstName);
          buffer.write("', '");
          buffer.write(c.lastName);
          buffer.write("', '");
          buffer.write(c.address);
          buffer.write("')");
        });
        var raw =
            await db.rawInsert("INSERT Into Clients (firstName,lastName,address)"
                " VALUES ${buffer.toString()}");
        return raw;
      }
    

    我正在使用 SQLite 中的这条语句:

    INSERT INTO 'tablename' ('column1', 'column2') VALUES
                    ('data1', 'data2'),
                    ('data1', 'data2'),
                    ('data1', 'data2');
    

    【讨论】:

    • 虽然我更喜欢批处理解决方案,但如果您仍然需要单个语句,您应该为内容列使用参数并构建类似 sql: INSERT INTO 'tablename' ('column1', 'column2 ') 值 (?, ?), (?, ?), (?, ?);参数:['data1', 'data2', 'data1', 'data2','data1', 'data2'];
    • 正如上面评论中提到的,这种方法存在问题。对于超过 1000 个联系人, sqflite 将抛出异常 E/SQLiteLog(22159): (1) SQL 变量过多
    【解决方案4】:

    我看到了使用数据库事务的可能性,这与 Android 非常相似。 我发现使用它们更好,这里我展示了一个代码示例,如果它可能对某人有用。 在我的示例中显示了 try-catch,但可以使用 Future 函数回调来获得更清晰的代码:

    Future<List<dynamic>> insertAll(String table, List<dynamic> objects) async {
    List<dynamic> listRes = new List();
    var res;
    try {
      await DbHelper().database.transaction((db) async {
        objects.forEach((obj) async {
          try {
            var iRes = await db.insert(table, obj.toMap());
            listRes.add(iRes);
          } catch (ex) {
            DbHelper().databaseLog(CON_INSERT_MULTIPLE, "Error!", ex);
          }
        });
      });
      DbHelper().databaseLog(CON_INSERT_MULTIPLE, table, listRes);
      res = listRes;
    } catch (er) {
      res = OutComeCallClient.ERROR;
      DbHelper().databaseLog(CON_INSERT_MULTIPLE, "Error!", er);
    }
    return res;
    }
    

    【讨论】:

      【解决方案5】:

      这是我的代码,也许能帮上忙;) 感谢 MihaiV。

      insertOrUpdateAll(List<Map<String, dynamic>> ticks) async {
      
          if (ticks.length == 0) return null;
          final columns = ticks.first.keys.join(",");
      
          var valuesBuffer = new StringBuffer();
          ticks.forEach((task) {
            if (valuesBuffer.isNotEmpty) valuesBuffer.write(",\n");
            valuesBuffer.write("(");
      
            int ix = 0;
            task.forEach((key, value) {
              if (ix++ != 0) valuesBuffer.write(',');
      
              final isString =
                  columnsInfo.where((c) => c.name == key).first.type == RowType.text;
              if (isString) valuesBuffer.write("'$value'");
      
              valuesBuffer.write(value);
            });
      
            valuesBuffer.write(")");
          });
      
          return await db.rawInsert("INSERT Into Clients ($columns)"
              " VALUES ${valuesBuffer.toString()}");
      }
      

      【讨论】:

      • 此方法存在问题。对于超过 1000 个联系人, sqflite 将抛出异常 E/SQLiteLog(22159): (1) SQL 变量过多
      【解决方案6】:
         Model
      
      
      
       import 'package:sqflite/sqflite.dart';
          import 'package:path/path.dart';
          
          final String tableName = "todom";
          final String Column_id = "id";
          final String Column_name = "name";
          
          class TaskModel{
            final String name;
            int id;
          
            TaskModel({this.name, this.id});
          
            Map<String, dynamic> toMap(){
              return {
                Column_name : this.name
              };
            }
          }
          
          class TodoHelper{
            Database db;
          
            TodoHelper(){
              initDatabase();
            }
          
            Future<void> initDatabase() async{
              db = await openDatabase(
                join(await getDatabasesPath(), "databse.db"),
                onCreate: (db, version){
                  return db.execute("CREATE TABLE $tableName($Column_id INTEGER PRIMARY KEY AUTOINCREMENT, $Column_name TEXT)");
                },
                version: 1
              );
            }
          
            Future<void> insertTask(TaskModel task) async{
              try{
                db.insert(tableName, task.toMap(), conflictAlgorithm: ConflictAlgorithm.replace);
              }catch(_){
                print(_);
              }
            }
          
            Future<List<TaskModel>> getAllTask () async{
              final List<Map<String, dynamic>> tasks = await db.query(tableName);
          
              return List.generate(tasks.length, (i){
                return TaskModel(name: tasks[i][Column_name], id: tasks[i][Column_id]);
              });
            }
          
          
          }
      
      
      
      
      main.dart
      
      
      
      import 'package:flutter/material.dart';
      
      import 'TaskModel.dart';
      
      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              // This is the theme of your application.
              //
              // Try running your application with "flutter run". You'll see the
              // application has a blue toolbar. Then, without quitting the app, try
              // changing the primarySwatch below to Colors.green and then invoke
              // "hot reload" (press "r" in the console where you ran "flutter run",
              // or simply save your changes to "hot reload" in a Flutter IDE).
              // Notice that the counter didn't reset back to zero; the application
              // is not restarted.
              primarySwatch: Colors.blue,
            ),
            home: MyHomePage(),
          );
        }
      }
      
      class MyHomePage extends StatefulWidget {
        @override
        _MyHomePageState createState() => _MyHomePageState();
      }
      
      class _MyHomePageState extends State<MyHomePage> {
        final textController = TextEditingController();
      
        List<TaskModel> tasks = [];
      
        TaskModel currentTask;
      
      
      
        @override
        Widget build(BuildContext context) {
          final TodoHelper _todoHelper = TodoHelper();
          return Scaffold(
            body: Container(
              padding:EdgeInsets.all(32),
              child: Column(
                children: <Widget>[
                  TextField(
                    controller: textController,
                  ),
                  FlatButton(
                    child: Text("Insert"),
                    onPressed: (){
                      currentTask = TaskModel(name: textController.text);
                      _todoHelper.insertTask(currentTask);
                    },
                    color: Colors.blue,
                    textColor: Colors.white,
                  ),
                  FlatButton(
                    child: Text("Show All Task"),
                    onPressed: () async{
                      List<TaskModel> list = await _todoHelper.getAllTask();
      
                      setState(() {
                        tasks = list;
                      });
                    },
                    color: Colors.red,
                    textColor: Colors.white,
                  ),
      
                  Expanded(
                    child: ListView.separated(
                        itemBuilder: (context, index){
                          return ListTile(
                            leading: Text("${tasks[index].id}"),
                            title: Text("${tasks[index].name}"),
                          );
                        },
                        separatorBuilder: (context, index) => Divider(),
                        itemCount: tasks.length,
      
                    ),
                  )
                ],
              ),
            ),
          );
        }
      }
      

      【讨论】:

        【解决方案7】:

        你可以试试 rawInsert

        Database db = await instance.database;
        String sql = '''
        INSERT INTO p_tasklistproviderobjective (
            idticket,
            objective
          ) VALUES (?, ?)
        ''';
        //you can get this data from json object /API
        List<Map> data = [
          {"idticket": 5, "objective": "dono"},
          {"idticket": 6, "objective": "dono2"},
          {"idticket": 7, "objective": "dono3"},
          {"idticket": 8, "objective": "dono4"},
        ];
        //and then loop your data here
        data.forEach((element) async {
          await db.rawInsert(sql, [element['idticket'], element['objective']]);
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多