【问题标题】:What is the way to insert a huge JSON data into a SQLite DB in android在android中将大量JSON数据插入SQLite DB的方法是什么
【发布时间】:2015-08-21 13:22:27
【问题描述】:

我有一个大的 json 请求,也就是说,它有大约 50k 行和 15 列,我必须将它们插入到具有相同结构的 SQLite DB 中。也就是说,我必须将在 postgres db 中分配的相同数据复制到我的应用程序中的 sqlite db 中。有什么有效的方法吗?是否有一些 api 或可以帮助工作的东西?

我必须告诉我,我可以使用 OMRLite 处理不大的 JSON 数据,但是当我尝试处理更大的数据时,我的应用程序崩溃并且 内存错误

如果您有一些想法或一些我可以遵循的示例,我将不胜感激!提前致谢!

【问题讨论】:

  • 我会说使用带有 Asynctask 事务管理的预编译插入语句查询,并通过适当的消息通知用户。参考这个stackoverflow.com/a/31962559/1686269
  • 尝试使用 Gson 将 Json 解析为 Java 对象,然后使用这些对象写入 sqlite,sqlite 有很多 ORM 库,只需 google ORM android 即可找到结果
  • 我明白了。因此,我从 servlet 发出 JSON 请求,然后使用 GSON 解析这些数据,并使用 ORMLite 来管理 SQLite。但正如我所说,问题是当我有一个大的 json 请求时。

标签: java android sqlite ormlite


【解决方案1】:

您还可以使用 Google 的官方 Gson 流媒体库。

Gson 流媒体:Gson Streaming

JsonReader 在使用 Streaming 库解析 json 中起着非常重要的作用。

【讨论】:

  • 感谢您的回答@Durgesh!现在我就在上面。我会先尝试一下,因为我已经使用 gson 来解析数据。
  • @AndresMelgarejoLedesma 你试过了吗?你的问题解决了吗?
  • 嗨!是的,它解决了问题,感谢您的支持!
  • @AndresMelgarejoLedesma 如果这解决了你的问题,那么请接受这个答案:)
【解决方案2】:

由于 JSON 太大,您无法将其完全加载到内存中。即使使用标准 JSONObject 也会导致许多设备上的内存不足。

我在类似情况下所做的是使用 Jackson 来解析它。杰克逊可以从流中做到这一点,所以内存使用根本不是问题。缺点是 API 与普通选项相比使用起来不那么直接。

这是我找到的一个例子:Jackson Streaming

【讨论】:

  • 感谢您的回答,您对gson了解多少?我用gson来解析成java对象的工作,你以为gson是用手机内存来做那个工作的吗?可能是的,因为错误。你推荐杰克逊@azertiti?
  • 据我所知,它会一次解析整个 JSON。您还可以在开始解析时查看 Android Studio 中的内存使用情况。如果内存增加很多,你就有答案了。我没有在我的任何项目中使用它来轻松测试,但我过去使用 Jackson Streaming API 解决了同样的问题。
  • 好的,非常感谢!我马上试试!如果解决了问题,我会发布。
【解决方案3】:

GSON 流适用于我Gson - streaming,但我不得不说这需要他的时间,例如 10 列的 68K 行大约需要 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;
}

希望您了解问题所在,并希望您能帮助我解决这个问题!再次感谢!

【讨论】:

  • 我快速浏览了一下。我怀疑每个插入都按列名搜索列索引。也许这就是性能缓慢的部分原因。
猜你喜欢
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
相关资源
最近更新 更多