将数据插入数据库 - 最佳方法是什么

4
我需要将50-500个联系人的信息插入数据库中。我有4个ArrayList分别包含图像、姓名、号码和布尔变量。数据中的每一行都由这4个ArrayList的组合和一个SNO组成,请参考下面的图片。
我的问题是,假设我从用户的联系人列表中检索到了500个联系人。那么,是不是在方法中每次插入一个row并且调用方法500次是一个好方法?还是有其他方法?一个巧妙的想法是将所有的ArrayList组合在一起,传递给函数,然后在那里检索数据,并重复500次插入语句。
从性能方面来说哪种方法更好呢?
for(int i =0; i < 500; i++)
{
  dbObj.insert_row(par1, par2, par3, par4, ...);
}

或者

function insert_row(Combined ArrayLists)
{
  for(int i=0; i<500; i++)
  {
    db.execSql(//Insert Statement);
  }
}

2
首先,将您的4个ArrayList替换为一个自定义类类型的ArrayList。您可以构建一个“INSERT”查询来插入多行:https://dev59.com/lGw15IYBdhLWcg3wA28A - Sotirios Delimanolis
4个回答

6

将数据插入数据库 - 最佳方法是什么

建议您创建一个代表表格的对象,其中对象的属性将等于表格中的列,例如:

public class Contact {

   private String name;
   private String number;
   private String image;
   private boolean conn;

   //getters and setters
}

你现在的做法听起来像是"意大利面代码"。没有必要有四个ArrayList,这种设计既不高效也不正确。

现在,你只需要一个包含500个Contact对象的ArrayList。

最佳插入方式是什么?

一定要将你的插入操作封装到一个TRANSACTION中,这样可以显著加快插入速度,并且处理数据库的主要任务变得更加安全,你不再需要担心数据完整性可能会丢失。

示例事务(来自我个人项目的一个方法):

public boolean insertTransaction(int count) throws SQLException {
    boolean result = false;
    try {
        db = openWrite(DataSource.getInstance(mContext));
        ContentValues values = new ContentValues();
        if (db != null) {
            db.beginTransaction();
            for (int i = 0; i < count; i++) {
                values.put(SQLConstants.KEY_TYPE, "type" + i);
                values.put(SQLConstants.KEY_DATE, new Date().toString());
                db.insertOrThrow(SQLConstants.TEST_TABLE_NAME, SQLConstants.KEY_TYPE, values);
                values.clear();
            }
            db.setTransactionSuccessful();
            result = true;
        }
        return result;
    }
    finally {
        if (db != null) {
            db.endTransaction();
        }
        close(db);
    }
}

1
非常感谢您的输入。等待期结束后,我会接受您的答案。 - Vamsi Challa

0
将4个数组转换为一个对象数组可以使代码更好。但是你可以不用这样做就创建这些对象。
使用绑定变量(?或:vars)准备SQL语句,然后通过为每一行设置绑定变量,在循环中多次执行该语句。
String sql = "insert into..... values (?,?,?,?)";
// Get connection etc
PreparedStatement stmt = conn.prepareStatement(sql);
for(int i =0; i < 500; i++)
{
   stmt.setString(1, name.get(i));
   stmt.setNumber(2, number.get(i));
   ...

   stmt.executeUpdate();
}

0
如果您要向数据库插入500条记录,应该使用事务。
database.beginTransaction();
try {
     // perform inserts
     database.setTransactionSuccessful();
finally {
     database.endTranasction();
}

事务的范围是什么?如果单个插入失败,是否应该使所有插入都失败? - Sotirios Delimanolis
这就是事务的工作原理,如果有一个插入失败,所有插入操作都将被取消。或者一切都成功执行,或者什么都不执行。 - Mike
我知道这一点,我问你的是那是否是正确的逻辑。插入操作之间有什么关联吗?我认为每个插入操作都是独立的。 - Sotirios Delimanolis
使用事务将保证数据的一致性,这非常重要。 - Mike
我的意思是这里的事务是不必要的。他正在插入500个不同的行。如果一个插入没有成功(重复键、其他违反约束等),它不应该影响其他插入。但是在这种设置下,如果一个失败了,你将回滚并取消所有插入。此外,在这种情况下,插入已经是ACID的(他没有展示任何证据表明插入会影响其他任何东西)。 - Sotirios Delimanolis

0

如之前所述,创建自己的类来表示一行数据或使用 ContentValues class。SQlite 不像 MySQL 一样提供了在一个查询中插入多行数据的可能性,但是有一些方法可以绕过它,您可以在 这里 阅读到更多信息。

如果您决定使用此链接中描述的方法,最好创建一个函数来生成此查询并仅运行一次。否则,如其他人已经提到的,您可以使用事务来提高多次插入的性能。


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