如何在Android中将大量JSON数据插入SQLite数据库?

4
我有一个庞大的 JSON 请求,大约有 50k 行和 15 列,我需要将它插入到具有相同结构的 SQLite 数据库中。也就是说,我必须将在 PostgreSQL 数据库中分配的相同数据复制到我的应用程序中的 SQLite 数据库中。有没有一些有效的方法可以做到这一点?是否有一些 API 或其他东西可以帮助完成工作?
我必须告诉你,我能够使用 OMRLite 处理不是很大的 JSON 数据,但是当我尝试处理更大的数据时,我的应用程序会崩溃并显示内存不足的错误。
如果您有任何想法或示例可供我参考,我将非常感激!提前致谢!

我会建议使用预编译的插入语句查询来实现事务管理,使用Asynctask并发送适当的消息通知用户。请参考此链接:http://stackoverflow.com/a/31962559/1686269 - Durgesh Patel
尝试使用Gson将Json解析为Java对象,然后使用这些对象写入sqlite。有很多适用于sqlite的ORM库,只需在Google上搜索ORM android即可找到结果。 - Bhargav
我明白了。所以,我从servlet发出JSON请求,然后使用GSON解析这些数据,并使用ORMLite管理SQLite。但正如我所说的,当我有一个大的JSON请求时问题就来了。 - Andres Melgarejo Ledesma
3个回答

2

您还可以使用Google官方的Gson Streaming库。

Gson Streaming:Gson Streaming

JsonReader在使用流式库解析json时起着非常重要的作用。


感谢您的回答@Durgesh!我现在正在处理这个问题。我将首先尝试,因为我已经使用gson解析数据。 - Andres Melgarejo Ledesma
@AndresMelgarejoLedesma 你试过了吗?你的问题解决了吗? - Durgesh Patel
嗨!是的,它解决了问题,感谢您的支持! - Andres Melgarejo Ledesma
@AndresMelgarejoLedesma 如果这解决了你的问题,请接受这个答案 :) - Durgesh Patel

1
由于JSON文件太大,无法完全加载到内存中。即使使用标准的JSONObject,在许多设备上也会导致内存不足。
在类似的情况下,我所做的是使用Jackson进行解析。Jackson可以从流中解析,因此内存使用量不成问题。缺点是API与普通选项相比不那么直观易用。
以下是我找到的一个示例:Jackson Streaming

谢谢你的回答,你对gson了解多少?我使用gson将数据解析为Java对象,你认为gson是在使用手机内存进行这项工作吗?很可能是因为出现了错误。你推荐使用jackson吗,@azertiti? - Andres Melgarejo Ledesma
据我所知,是的,它将一次性解析整个JSON。当开始解析它时,您还可以查看Android Studio中的内存使用情况。如果内存大幅上升,那么您就有了答案。我在任何项目中都没有使用它来进行简单测试,但我过去用Jackson Streaming API解决了同样的问题。 - azertiti
好的,非常感谢!我现在会尝试一下!如果问题得到解决,我会发布的。 - Andres Melgarejo Ledesma

0

GSON 流 Gson - streaming 在我的项目中可行,但我必须说它需要一定的时间,例如 68K 行,每行有 10 列,大约需要 4 分钟。不过无论如何,它解决了我的问题。所以我现在拥有这个 JSON 响应:

- preciosArtPK: {
                   codLista: 1,
                   codArticulo: 11348,
                   cansiVenta: 1,
                   fecVigencia: 1435781252000
},
  siglaVenta: "UN",
  precioVenta: 0,
  margenPct: 100,
  codUsuario: 1,
  vigente: "S",
  nomModulo: "MIGRACION"

上面的 JSON 是数组响应的一部分,但我有那些 "preciosArtPK" 要包含在使用 gson 进行序列化中。我该怎么做?我有处理我的序列化的类:

@DatabaseTable(tableName = "preciosart")
public class PreciosArt {

public static final String PRECIOS_COD_LISTA = "_id";
public static final String PRECIOS_COD_ARTICULO = "cod_articulo";
public static final String PRECIOS_CANSI_VENTA = "cansi_venta";
public static final String PRECIOS_FEC_VIGENCIA = "fec_vigencia";
public static final String PRECIOS_SIGLA_VENTA = "sigla_venta";
public static final String PRECIOS_PRECIO_VENTA = "precio_venta";
public static final String PRECIOS_MARGEN_PCT = "margen_pct";
public static final String PRECIOS_COD_USUARIO = "cod_usuario";
public static final String PRECIOS_VIGENTE = "vigente";
public static final String PRECIOS_NOM_MODULO = "nom_modulo";


@DatabaseField(id = true, unique = true, columnName = PRECIOS_COD_LISTA)    
private Integer codLista;

@DatabaseField(unique = true, columnName = PRECIOS_COD_ARTICULO)
@SerializedName("codArticulo") // probar
private Integer codArticulo;

@DatabaseField(unique = true, columnName = PRECIOS_CANSI_VENTA)
private Integer cansiVenta;

@DatabaseField(unique = true, columnName = PRECIOS_FEC_VIGENCIA)
private Long fecVigencia;

@DatabaseField(columnName = PRECIOS_SIGLA_VENTA)
@SerializedName("siglaVenta")
private String siglaVenta;

@DatabaseField(columnName = PRECIOS_PRECIO_VENTA)
@SerializedName("precioVenta")
private Double precioVenta;

@DatabaseField(columnName = PRECIOS_MARGEN_PCT)
@SerializedName("margenPct")
private Float margenPct;

@DatabaseField(columnName = PRECIOS_COD_USUARIO)
@SerializedName("codUsuario")
private Integer codUsuario;

@DatabaseField(columnName = PRECIOS_VIGENTE)
@SerializedName("vigente")
private String vigente;

@DatabaseField(columnName = PRECIOS_NOM_MODULO)
@SerializedName("nomModulo")
private String nomModulo;

但是这并没有填充那些字段(codArticulo、cansiVenta 和 fecVigencia)。我阅读了关于反序列化这些 JSON 格式的文章,制作了另一个类:

@SerializedName("codLista")
private Integer codLista;

@SerializedName("codArticulo")
private Integer codArticulo;

@SerializedName("cansiVenta")
private Integer cansiVenta;

@SerializedName("fecVigencia")
private Long fecVigencia;

问题是:我如何使用我的JSON反序列化填充这些字段?我使用OMRLite来完成这项工作,这个类就是为此而设计的:
public long updatePreciosart(PreciosArt preciosArt){
    long resultUpdate = -1;
    try {
        getHelper().getPreciosartDao().createOrUpdate(preciosArt);
        resultUpdate = 0;
    } catch (SQLException e) {
        e.printStackTrace();
        resultUpdate = -1;
    }
    return resultUpdate;
}

希望你能理解问题所在,并希望你能帮助我解决它!再次感谢!

我快速地浏览了一下这个程序。我怀疑每次插入操作都是通过列名来搜索列索引的。也许这就是性能缓慢的原因之一。 - f470071

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接