Ionic 3插入大量数据

Posted

技术标签:

【中文标题】Ionic 3插入大量数据【英文标题】:Ionic 3 inserting a lot of data 【发布时间】:2017-12-28 08:29:31 【问题描述】:

我正在开发的 ionic3 应用程序有问题。 使用我的应用程序,我连接到 JSON 服务器并下载很多行,当我所有行都带有 for 时,在每一行调用函数来插入数据。 但我认为,我的 for 比 insert funcion 更快,并在结束前显示 finalice alert。这是我的代码:

 private downloadRows()
 
this.platform.ready().then(()=>
   this.translateService.get('ACTUALIZANDOBARRANCOS').subscribe(
    value => 
    let loadingContent = value; 
    let loader = this.loadingController.create(
    content: loadingContent,
    spinner: "bubbles"
    );  

    this.servicioDownloads.downloadAllRows().then(rows=> 
        this.datosrows= rows;
        loader.present();
        for (var i = 0; i < this.datosrows.length; i++)
        
          var datos = this.datosrows[i];
          // we are going to insert rows
          this.servicioDataBase.insertRow
          ( datos.indice,
            datos.row1, 
            datos.row2,
            datos.row3, 
            datos.row4, 
            datos.row5,
            datos.row6, 
            datos.row7, 
            datos.row8, 
            datos.row9, 
            datos.row10, 
            //...
            datos.row30
          ).catch(()=>
            console.log("da error");
          );
        
        loader.dismiss();
        this.translateService.get('FINALIZADO').subscribe(
              Titulo =>
                  let titulo = Titulo;

               this.translateService.get('BARRANCOSACTUALIZADOS').subscribe(
                    Descripcion =>
                      let descripcion = Descripcion;
                      let alerta = this.alertCtrl.create(
                        title: titulo,
                        subTitle: descripcion,
                        buttons: ['OK']
                      )
                      alerta.present();
                    
                  );
              
            );


  ).catch(error=>
    loader.dismiss();
        this.translateService.get('ERROR').subscribe(
              Titulo =>
                  let titulo = Titulo;

  this.translateService.get('ERRORDESCARGABARRANCOS').subscribe(
                    Descripcion =>
                      let descripcion = Descripcion;
                      let alerta = this.alertCtrl.create(
                        title: titulo,
                        subTitle: descripcion,
                        buttons: ['OK']
                      )
                      alerta.present();
                    
                  );
              
        );
  )
);
)

//这是插入服务

public insertRow( indice: any, row1: any, row2: any,  row3: any,  row4: any, 
  row5: any,  row6: any,   row7: any,   row8: any,   row9: any,  row10: any, 
  row30: any)
     
  let sql = "INSERT INTO TableRows (id,Nombre,Rio,Pais,Comunidad, 
  Zona,Localidad,Interes,Caracter,Cascada_max,Cuerda_max,Desnivel, 
  Longitud, Tiempo_aprox,Tiempo_descenso,Tiempo_retorno,Observaciones, 
  Descripcion_barranco,Periodo_optimo,Caudal,Caudal_filtro,Aproximacion, 
  Retorno,Loc_entrada_barranco,Loc_salida_barranco,Loc_entrada_parking, 
  Loc_salida_parking,Autor,Actualizacion,Idioma,Visible) 
  VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
  console.log(sql); 
  return this.isReady()
  .then(()=>
      return this.database.executeSql(sql, 
            [indice,BARRANCO, RIO, PAIS,COMUNIDAD,
              ZONA,LOCALIDAD,INTERES,CARACTER, CASCADA_MAX, 
              CUERDA_MAX,DESNIVEL,LONGITUD,TIEMPO_APROX,
              TIEMPO_DESCENSO,TIEMPO_RETORNO, OBSERVACIONES, 
              DESCRIPCION_BARRANCO,PERIODO_OPTIMO,CAUDAL,
              CAUDAL_FILTRO,APROXIMACION, RETORNO,
              LOC_ENTRADA_BARRANCO,LOC_SALIDA_BARRANCO, 
              LOC_ENTRADA_PARKING, LOC_SALIDA_PARKING, 
              AUTOR,actualización,idioma, visible]);
  ).then((data)=>
    console.log("El insert devuelve esto " + JSON.stringify(data));
  )        


有人知道我怎样才能按时完成,我的意思是在结束时插入?

非常感谢!

【问题讨论】:

您可以尝试使用cordova-sqlite-porter。 ***.com/a/35385963/5059916 谢谢@TomislavStankovic,我去看看,我会告诉你 @TomislavStankovic 它运行良好,非常感谢,我使用 sqlite-porter 并且运行良好且速度更快!只有一个人想多了。当我导入所有数据时,我在显示所有行时进入屏幕,但在关闭应用程序并再次打开后我看不到这些行。我使用虚拟滚动。 我将其添加为答案,以便人们更容易看到解决方案。至于在屏幕上显示数据,插入后你能立即看到吗?关闭并打开应用后数据是否消失或根本没有显示? 【参考方案1】:

只需在您的函数中使用 async/await,它将允许您按顺序调用异步函数(因为Typescript 2.1 您可以将 async/await 降级到 ES3/ES5)。因此,您示例中的解决方案可能如下所示:

私人下载行() this.platform.ready().then(()=> this.translateService.get('ACTUALIZANDOBARRANCOS').subscribe( 异步值 => 让加载内容=值; 让 loader = this.loadingController.create( 内容:加载内容, 微调器:“气泡” ); 让行 = 等待 this.servicioDownloads.downloadAllRows(); loader.present(); for (let datos of rows) // 我们要插入行 尝试 等待 this.servicioDataBase.insertRow ( datos.indice, 数据.row1, 数据.row2, 数据.row3, datos.row4, datos.row5, datos.row6, datos.row7, datos.row8, datos.row9, datos.row10, //... 数据.row30 ); 捕捉(错误) 控制台日志(错误); loader.dismiss(); this.translateService.get('FINALIZADO').subscribe( 标题 => 让标题 = 标题; this.translateService.get('BARRANCOSACTUALIZADOS').subscribe( 说明 => 让描述=描述; 让 alerta = this.alertCtrl.create( 标题:标题, 副标题:描述, 按钮:['确定'] ) alerta.present(); ); ); ).catch(错误=> loader.dismiss(); this.translateService.get('ERROR').subscribe( 标题 => 让标题 = 标题; this.translateService.get('ERRORDESCARGABARRANCOS').subscribe( 说明 => 让描述=描述; 让 alerta = this.alertCtrl.create( 标题:标题, 副标题:描述, 按钮:['确定'] ) alerta.present(); ); ); ) ); )

await in for 循环防止 for 循环在插入实际完成之前完成。

【讨论】:

【参考方案2】:

SQLite Porter - 此 Cordova/Phonegap 插件可用于使用 SQL 或 JSON 向 SQLite 数据库导入/导出。

安装:

$ ionic cordova plugin add uk.co.workingedge.cordova.plugin.sqliteporter
$ npm install --save @ionic-native/sqlite-porter

用法:

import  SQLitePorter  from '@ionic-native/sqlite-porter';


constructor(private sqlitePorter: SQLitePorter)  

...

let db = window.openDatabase('Test', '1.0', 'TestDB', 1 * 1024);
// or we can use SQLite plugin
// we will assume that we injected SQLite into this component as sqlite
this.sqlite.create(
  name: 'data.db',
  location: 'default'
)
  .then((db: any) => 
    let dbInstance = db._objectInstance;
    // we can pass db._objectInstance as the database option in all SQLitePorter methods
  );


let sql = 'CREATE TABLE Artist ([Id] PRIMARY KEY, [Title]);' +
           'INSERT INTO Artist(Id,Title) VALUES ("1","Fred");';

this.sqlitePorter.importSqlToDb(db, sql)
  .then(() => console.log('Imported'))
  .catch(e => console.error(e));

您可以尝试使用cordova-sqlite-porter。将您的插入作为 使用importJsonToDb() 的JSON 结构,它将optimise the insertion 放入SQLite DB。

example project 说明插入了 15,000 多条记录。在 三星 Galaxy S4,使用单个 SQL 插入执行此操作 语句大约需要 5 分钟/300 秒,但优化的 JSON 等效(使用 UNION SELECT - see here for info) 在同一台设备上 3 秒 - 快 100 倍。 - source

【讨论】:

以上是关于Ionic 3插入大量数据的主要内容,如果未能解决你的问题,请参考以下文章

C# 通过DataTable插入大量数据,50万数据只需要3秒

Android 数据库 大量插入 事务开启

核心数据 executeFetchRequest 消耗大量内存

在MySQL中快速的插入大量测试数据

转://使用insert插入大量数据的总结

Mysql插入大量随机数据