确定Android SQLite数据库中的位置

时间:2014-08-13 06:18:29

标签: android sqlite

我希望能够在列中找到字符串的位置。我有一个应用程序,用户添加到一个列表,形成一张卡,当他们刷卡时,它删除。我是SQLite的新手,我正在努力删除我想要的项目。

这是我到目前为止所拥有的:

c2.moveToFirst();
String contentLabel = c2.getString(c2.getColumnIndex("Content"));
db.delete("Lists", "Content = '" + contentLabel + "'", null);

现在问题在于,当我将卡从第三张卡上移开时,第一张卡被移除,而被刷掉的卡移动到列表的顶部。

4 个答案:

答案 0 :(得分:2)

从Sqlite数据库中删除正确项目的最准确方法是指定要删除的项目的唯一ID。

您是否使用_id列创建了数据库?如果没有,你可能会使用Sqlite的默认ROWID列 - 从未尝试过,但我相信android会自动将其映射到_id。 您必须将ID号添加到加载程序的投影中,以便在使用数据填充卡片视图时在光标中显示此值。

假设您的列表项(或卡)正在使用自定义布局,您应该具有CursorAdapter的实现,通过回收现有视图或为每个列表创建新视图来为卡填充数据显示的项目。

当您使用数据填充每个列表项时,在游标适配器中,您还应该在卡片视图上调用listItemView.setTag(cursor.getString(cursor.getColumnIndex('_id')));。这将在卡片视图中存储关联的Sqlite行ID号。我认为这很长。

在您的项目被解雇的处理程序中,您可以调用listItemViewToDismiss.getTag();来了解您要从数据库中删除的ID号。请注意,我们已将其存储为String,但View.getTag()将返回一个Object,因此需要将其强制转换为字符串,如下所示:

String storedRowId = (String) listItemViewToDismiss.getTag();

一旦您可以轻松访问数据库行ID,其余的很简单:

db.delete(URI, "_id=?", new String[] { (String) cardViewToDismiss.getTag() });

这将只删除列表项标记中指定了唯一ID的行 - 如果你在_id列上使用SQLite的AUTOINCREMENT - 我希望你是 - 那么这应该只删除一行,或者为零行如果已被另一个进程删除。

如果您的内容提供商可以处理单个项目的URI,那么我认为您还可以将当前项目的完整URI(带有附加ID)插入到视图的标记中,然后只需调用

db.delete( (String) viewToDismiss.getTag() );

...让内容提供商删除正确的项目。

部分参考

Cursor Adapter的getView方法: [http://developer.android.com/reference/android/widget/Adapter.html](请参阅该页面上的getView())

设置标签: http://developer.android.com/reference/android/view/View.html#setTag(java.lang.Object)

免责声明

我已经做了一段时间了,我从内存中编写了代码,所以如果这不再是Android开发的最佳实践,或者如果我犯了一个愚蠢的错误,我希望有人会纠正我

答案 1 :(得分:0)

正如您的代码现在,您始终删除第一项。使用方法cursor.moveToPosition(int position)将光标移动到要删除的元素。

将您的代码更改为:

// position = position of the "swiped card" (e.g. for the third card position is 3)
c2.moveToPosition(position - 1); 
String contentLabel = c2.getString(c2.getColumnIndex("Content"));
db.delete("Lists", "Content = '" + contentLabel + "'", null);
如果

moveToPosition(int position)无法移动到该位置(例如没有这样的位置),则返回false,因此您可能需要添加一些代码来检查:

if (!c2.moveToPosition(position - 1)) {
    //failed to move!
}
String contentLabel = c2.getString(c2.getColumnIndex("Content"));
db.delete("Lists", "Content = '" + contentLabel + "'", null);

答案 2 :(得分:0)

也许这可能会有所帮助?

String cardLabel;    

card.setOnSwipeListener(new Card.OnSwipeListener() {
        @Override
        public void onSwipe(Card card) {
            lable = "[code to get the swiped card's text]"
        }
    });
    db.delete("Lists", "Content = '" + cardLabel + "'",    null);

基本上只需添加一些类型的侦听器即可在刷卡时获取卡的文本,并删除文本等于侦听器找到的文本。通过文本删除的问题可能是用户可能有两张具有相同文本的卡,可能会意外地将其添加两次,但是当他们尝试删除副本时,这将删除两者。

使用用户定义的文本查询这种方式也可能会打开你的sql注入。我不确定Android是否有任何机制来处理这个问题,但值得考虑。我同意其他人说正确的方法是按ID搜索。如果您想自动执行ID,可以在数据库帮助程序中的CREATE TABLE SQL语句中添加类似的内容。

   Lists._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +  

希望这很有用。

答案 3 :(得分:0)

我应该使用ormLitegreenDao并专注于您的应用,而不是使用sql。