热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SQLite更改数据库中项目的排序顺序-SQLiteChangeSortOrderforitemsondatabase

Soimaginethisisaquickmockupofmydatabase:所以想象一下这是我的数据库的快速模型:Theitemsfromthedatabas

So imagine this is a quick mockup of my database:

所以想象一下这是我的数据库的快速模型:

enter image description here

The items from the database are presented to the user per list, each list being displayed on a new fragment, which are displayed on a viewpager. So let's say in this hypotetical case, there would be two fragments on the viewpager, first fragment would display first_list and second fragment would display second_list. Here's the code for that query:

来自数据库的项目按列表呈现给用户,每个列表显示在新片段上,该片段显示在viewpager上。所以让我们说在这个hypotetical案例中,viewpager上会有两个片段,第一个片段显示first_list,第二个片段显示second_list。这是该查询的代码:

 public static Cursor getListItems (final Context context, String listName) {
    if (mDatabase == null || !mDatabase.isOpen())
        open(context);  //This gets the writable db.

    String where = LIST_NAME + " = '" + listName + "'";
    return mDatabase.query(TABLE_LIST_ITEMS, PROJECTION_LIST_ITEMS, 
    where, null, null, null, SORT_ORDER);
}

Where SORT_ORDER is order_in_list, this works well, to begin with.

在SORT_ORDER是order_in_list的地方,这很有效,首先。

Now, the listviews are re-arrangeable using a public library, which attempts to allow the user to control the order of the items in each list. Here's where I am having issues, there is no add(int index, Object object) for the cursor, or some other easy way to manage the sorting. I first thought I could simply call mDatabase.update() to change the value for order_in_list but that works, but the results are not as intended. For example, user drags item two to position zero, remeber: zero-index values, we would now have two items with order_in_list as zero. And although I can call mDatabase.update() on item one to update his position to one, imagine how much work that'd be to handle several items on a well-formed database.

现在,可以使用公共库重新排列列表视图,该公共库试图允许用户控制每个列表中项目的顺序。这是我遇到问题的地方,没有为游标添加(int索引,Object对象),或者其他一些简单的方法来管理排序。我首先想到我可以简单地调用mDatabase.update()来更改order_in_list的值,但这样可行,但结果并非如预期的那样。例如,用户将第二项拖到零位,记住:零指数值,我们现在有两个项目,order_in_list为零。虽然我可以在第一项上调用mDatabase.update()来将其位置更新为一,但想象一下在一个格式良好的数据库上处理多个项目需要做多少工作。

Does anyone have any good suggestions on how I could work this out? I thought I had been clever by adding the extra col for sorting purposes :(

有没有人对如何解决这个问题有任何好的建议?我认为通过添加额外的col用于分类目的我很聪明:(

INB4:

INB4:

Yes, I Know arrays handle this well. But the database doesn't only store 4 cols, it has many more fields. Populating arrays each time from the database would be a waste of time and effort. And I would, anyways, have to write back to the database when the app is closed.

是的,我知道数组处理得很好。但是数据库不仅存储4个cols,还有更多的字段。每次从数据库填充数组都是浪费时间和精力。无论如何,当应用程序关闭时,我会写回数据库。

EDIT So I changed the listview to only display one String of text, and further columns upon actual clicking on the item (and therefore displaying a new fragment with the specified list item data). This allowed me to simply keep an ArrayAdapter which easily handles the drag and drop. During onStop, I update the reference only if there was a change that required to be saved:

编辑因此我将listview更改为仅显示一个文本字符串,并在实际单击该项目时显示更多列(因此显示具有指定列表项数据的新片段)。这让我可以简单地保留一个可以轻松处理拖放的ArrayAdapter。在onStop期间,只有在需要保存更改时才更新引用:

@Override
public void onStop() {
    if (updateDbOnExit) {
        //Update rows on database.
        for (int i = 0; i 

Where MoveListItemTo updates the value for order_in_list:

其中MoveListItemTo更新order_in_list的值:

 public static void moveTaskItemTo (final Context context, String item, int to) {
    if (mDatabase == null || !mDatabase.isOpen())
        open(context);  

    String where = COL_CONTENT + " = '" + item+ "'";

    ContentValues mCOntentValues= new ContentValues();
    mContentValues.put(ORDER_IN_LIST, to);  
    int rows = mDatabase.update(TABLE_LIST_ITEMS, mContentValues, where, null);

    Constants.LogMessage(rows + " row updated. Item moved to position: " + to);

    close();
}

That will work for now. However, I am still interested on knowing if there is an alternate way, especially when for example, the adapter is using data from more than one column on the database, and is therefore required to use a CusorAdapter and not a regular ArrayAdapter, which in turn requires the Database itself to update upon each Drag and Drop to reflect the change on the UI via cursorAdapter.swapCursor(). As stated, updating ALL of the items on a database upon each drag (which realistically doesn´t happen that often btw), is expensive, updating only Two rows, would be a saner choice.

那将是有效的。但是,我仍然有兴趣知道是否有另一种方法,特别是当例如适配器使用数据库中多个列的数据时,因此需要使用CusorAdapter而不是常规的ArrayAdapter, turn需要数据库本身在每次拖放时更新,以通过cursorAdapter.swapCursor()反映UI上的更改。如上所述,在每次拖动时更新数据库上的所有项目(实际上不会经常发生这种情况),这样做很昂贵,只更新两行,这将是一个更健全的选择。

2 个解决方案

#1


1  

I would suggest that you have an additional column, user_specified_order which would represent the user's reordering of the rows in the UI via drag-drop.

我建议你有一个额外的列user_specified_order,它代表用户通过拖放重新排序UI中的行。

You must update each row when its user_specified_order value is invalidated by the drag-drop repositioning. When to persist that value is up to you -- either at the "end" of the user's manipulations, however that be defined (e.g. click on Save button) or after each drag/drop if there is no clearcut UI indicator of "end of manipulation".

通过拖放重新定位使user_specified_order值无效时,必须更新每一行。何时保持该值取决于您 - 要么在用户操作的“结束”,要么定义(例如,单击“保存”按钮),或者在每次拖放后如果没有明确的UI指示符“结束”操纵”。

EDIT: ContenProvider in Android: Android - Can you update a Cursor for SQLite results?

编辑:Android中的ContenProvider:Android - 您可以更新SQLite结果的Cursor吗?

Android SQLite transactions: Android Database Transaction

Android SQLite事务:Android数据库事务

#2


4  

I just meant I wanted a more effective way to update the fields in the db, rather than manually updating each and every single row

我只是想要一种更有效的方法来更新数据库中的字段,而不是手动更新每一行

Make the user-specified-order column a decimal, not an integer. Then you need to update only the moved row(s).

使用户指定的顺序列为小数,而不是整数。然后,您只需要更新已移动的行。

Allow negative numbers.

允许负数。

0.00 cat
1.00 aardvark
2.00 wolf
3.00 dog

If "dog" is dragged above "wolf" then "dog" becomes 1.50 and no need to change other rows. If "aardvark" is dragged above "cat" (special case -- prepending to list rather than inserting between rows) then subtract 1 from the topmost value, and "aardvark" becomes -1.00.

如果“狗”被拖到“狼”之上,那么“狗”变为1.50并且不需要改变其他行。如果“aardvark”被拖到“cat”之上(特殊情况 - 前置于列表而不是插入行之间),则从最顶层的值中减去1,“aardvark”变为-1.00。

This will require you to know the values of the adjacent rows, but you won't have to update them. Only the moved row's value must change.

这将要求您知道相邻行的值,但您不必更新它们。只有移动的行的值必须更改。


推荐阅读
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
author-avatar
失心人2702939300
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有