Android - 存储对象列表的最佳方式(存储聊天记录)
Android - Best way to store a list of objects (Storing Chat History)
所以我正在编写一个聊天应用程序,我需要在本地存储每个用户的聊天记录。我正在使用 Room 执行此操作。
用户class:
@PrimaryKey
@NonNull
private String userid;
private String name;;
@TypeConverters(Object_Converter.class)
private ArrayList<Message> messages = new ArrayList<>();
我遇到的问题是更新消息列表。
我目前正在使用默认的@Update 方法:
@Update
void updateUser(User user);
所以基本上每次我的监听器收到一条消息,它都会通过Id请求用户,然后获取消息列表然后添加到其中,最后调用updateUser。
我的问题是这种方法对性能有多大影响,因为我假设 updateUser 只是用新消息覆盖整个消息列表?每隔几分钟就会收到消息,那么它们是存储和更新用户聊天记录的更好方法吗?
你是对的。所有消息都将被更新覆盖。最好将消息存储在自己的 table 中,并带有发送和接收用户的外键。基本上您的消息将如下所示:
@Entity(tableName = "message", foreignKeys = {
@ForeignKey(
entity = User.class,
parentColumns = "userid",
childColumns = "senderId",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
@ForeignKey(
entity = User.class,
parentColumns = "userid",
childColumns = "receiverId",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
}, indices = {
@Index("senderId"),
@Index("receiverId")
})
public class Message {
@PrimaryKey(autoGenerate = true)
public long id;
public String senderId;
public String receiverId;
public String content;
// ... other stuff
}
然后您只需在需要时插入和删除消息。当您想要检索消息时,您可以使用 userid
检索它,或者您可以加入 tables 并创建另一个模型 class,其中将包含用户以及已发送和已接收消息的列表。
将列表存储为列从来都不是一个好主意,因为它表明需要一个新的 table。有关更多信息,请阅读 database normal form。
这更多是关于数据库的设计,而不是实现。
我会这样处理这个问题:
您可以为消息创建一个新的数据库实体,并使用外键连接两个实体。那将是 one-to-many 关系,每个用户可以有更多消息。然后,您只需将每条新消息插入第二个 table 并通过查询获取消息列表,即:
"SELECT message FROM messages WHERE userid = :id"
或类似的东西。重点是,你需要改变你的数据库结构。
所以我正在编写一个聊天应用程序,我需要在本地存储每个用户的聊天记录。我正在使用 Room 执行此操作。
用户class:
@PrimaryKey
@NonNull
private String userid;
private String name;;
@TypeConverters(Object_Converter.class)
private ArrayList<Message> messages = new ArrayList<>();
我遇到的问题是更新消息列表。
我目前正在使用默认的@Update 方法:
@Update
void updateUser(User user);
所以基本上每次我的监听器收到一条消息,它都会通过Id请求用户,然后获取消息列表然后添加到其中,最后调用updateUser。
我的问题是这种方法对性能有多大影响,因为我假设 updateUser 只是用新消息覆盖整个消息列表?每隔几分钟就会收到消息,那么它们是存储和更新用户聊天记录的更好方法吗?
你是对的。所有消息都将被更新覆盖。最好将消息存储在自己的 table 中,并带有发送和接收用户的外键。基本上您的消息将如下所示:
@Entity(tableName = "message", foreignKeys = {
@ForeignKey(
entity = User.class,
parentColumns = "userid",
childColumns = "senderId",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
),
@ForeignKey(
entity = User.class,
parentColumns = "userid",
childColumns = "receiverId",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
}, indices = {
@Index("senderId"),
@Index("receiverId")
})
public class Message {
@PrimaryKey(autoGenerate = true)
public long id;
public String senderId;
public String receiverId;
public String content;
// ... other stuff
}
然后您只需在需要时插入和删除消息。当您想要检索消息时,您可以使用 userid
检索它,或者您可以加入 tables 并创建另一个模型 class,其中将包含用户以及已发送和已接收消息的列表。
将列表存储为列从来都不是一个好主意,因为它表明需要一个新的 table。有关更多信息,请阅读 database normal form。
这更多是关于数据库的设计,而不是实现。 我会这样处理这个问题: 您可以为消息创建一个新的数据库实体,并使用外键连接两个实体。那将是 one-to-many 关系,每个用户可以有更多消息。然后,您只需将每条新消息插入第二个 table 并通过查询获取消息列表,即:
"SELECT message FROM messages WHERE userid = :id"
或类似的东西。重点是,你需要改变你的数据库结构。