对象关系映射中的多值属性(Android 应用程序)

Posted

技术标签:

【中文标题】对象关系映射中的多值属性(Android 应用程序)【英文标题】:Multivalue properties in an object relational mapping (Android application) 【发布时间】:2012-01-24 16:14:14 【问题描述】:

在我正在构建的 android 应用程序中,我将关系查询封装在模型层中。

我的一个对象,我们称之为Place,有一个多值属性(我们称之为Image)。简化一下,我可以说 Java 中的模型如下所示:

class Place
    List<Image> images;
    ...



class Image 
    String description;
    String imageName;
    ...

在数据库中,这些类被映射到表 PLACE 和 IMAGE。

在 Java 端,我使用 DAO 来查询、插入、更新和删除 Place 对象。

作为一个简化的示例,我希望有一个名为 PlaceDataSource 的类,如下所示:

class PlaceDataSource 
    public List<Place> findAll();
    public void update(Place place);
    public void add(Place place);
    public void delete(Place place);
    ...

这些方法的描述如下:

findAll 方法回答Places 的列表,其中每个都包含Image 对象的集合。

update 方法更新 Place 及其图像(更新、插入新图像或在必要时删除现有图像)。

add 方法添加了一个新的 Place 及其图像。

delete 方法删除 Place 及其所有图像。

findAlladddelete 方法很容易实现。 但是,我还没有看到一种直接的实现update 方法的方法,它考虑了多值属性。我想到的程序算法是:

从数据库中查询Place 对象中当前保存的图像以进行更新。 找出Place 对象的images 属性中不再存在哪些Image 对象并将其删除。 更新存在于images 属性中的持久图像。 在images 属性中添加新图像。

我认为这段代码会变得丑陋和低效。 有没有更好的方法来实现 DAO? 在您使用 DAO 的应用程序中,您是否希望每个 DAO 始终映射到一个物理表?

我曾考虑在这种情况下使用两种不同的 DAO,一种用于持久化Place 对象,另一种用于Image 对象。然后Place DAO 将不负责图像对象的持久性,而是“业务”层应该使它们保持一致。 但是,Images 在概念上是 Place 对象的一部分,所以这个解决方案也不能完全说服我。

非常感谢您的反馈!

注意:目前我对使用 Android 的 ORM 框架不感兴趣,只是想从概念的角度找到这个问题的答案。

【问题讨论】:

【参考方案1】:

我是ORMLite 的作者,它为您完成所有这些工作,但您可以通过多种方式自己完成这些工作。

您可以编写自己的 List 类(Collection 会更容易)实现您想要的方法:addremove 等。这些都会更改列表并通过 DAO 调用方法。对于示例代码,您可以查看 ORMLite 如何做到这一点 BaseForeignCollectionEagerForeignCollection 但这可能对您的需求来说有点过头了。

正如您提到的那样,手动维护列表会更容易。也许在PlaceDataSource 上添加方法(这看起来更像是一个DAO,而不是DataSource),这将从列表数据库中删除。比如:

class PlaceDataSource 
    /** deletes image at location index from list and removes from database */
    public void deleteImage(Place place, int index);
    /** add image to the list and to the database */
    public void addImage(Place place, Image image);
    ...

您必须确保不直接使用该列表,否则它将与数据库不同步。

您也可以在Place 本身上使用这些方法,然后将每个Place 对象注入其DAO。有些人喜欢这种模式,但我一直认为将 DAO 方法放在另一个类中会更干净。

希望这会有所帮助。

【讨论】:

感谢您的回答和指向 ORMLite @Gray 的指针。您是否认为在同一个 Android 活动中使用两个 DAO(一个用于地方,一个用于图像)的解决方案也是一个有效的解决方案? (无论如何,它似乎不存在对此的“完美”解决方案)还是您根本不建议我这样做? (如果是,为什么?)。出于好奇:ORMLite 是在运行时使用字节码检测还是在编译时生成代码? 如果您以不同的方式处理图像和位置,那么 2 个 DAO 可能会更好。如果您只处理 Place 对象,那么 1 就可以了。 ORMLite 会为您节省大量代码,但它很重。它适用于运行时注释或配置——它不进行代码生成。祝你好运。

以上是关于对象关系映射中的多值属性(Android 应用程序)的主要内容,如果未能解决你的问题,请参考以下文章

检索并分配 jcr:mixinTypes magnolia 中的多值属性

核心数据:获取特定对象的多对多关系中的所有实体?

Fluent NHibernate:如何在关系表上映射具有附加属性的多对多关系?

使用 JPA 映射与属性的多对多关系

Hibernate双向一对多映射关系

核心数据 - 在对象中的多对关系更改属性后更新 UI