对象关系映射中的多值属性(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
方法回答Place
s 的列表,其中每个都包含Image
对象的集合。
update
方法更新 Place
及其图像(更新、插入新图像或在必要时删除现有图像)。
add
方法添加了一个新的 Place
及其图像。
delete
方法删除 Place
及其所有图像。
findAll
、add
和 delete
方法很容易实现。
但是,我还没有看到一种直接的实现update
方法的方法,它考虑了多值属性。我想到的程序算法是:
Place
对象中当前保存的图像以进行更新。
找出Place
对象的images
属性中不再存在哪些Image
对象并将其删除。
更新存在于images
属性中的持久图像。
在images
属性中添加新图像。
我认为这段代码会变得丑陋和低效。 有没有更好的方法来实现 DAO? 在您使用 DAO 的应用程序中,您是否希望每个 DAO 始终映射到一个物理表?
我曾考虑在这种情况下使用两种不同的 DAO,一种用于持久化Place
对象,另一种用于Image
对象。然后Place
DAO 将不负责图像对象的持久性,而是“业务”层应该使它们保持一致。
但是,Image
s 在概念上是 Place
对象的一部分,所以这个解决方案也不能完全说服我。
非常感谢您的反馈!
注意:目前我对使用 Android 的 ORM 框架不感兴趣,只是想从概念的角度找到这个问题的答案。
【问题讨论】:
【参考方案1】:我是ORMLite 的作者,它为您完成所有这些工作,但您可以通过多种方式自己完成这些工作。
您可以编写自己的 List
类(Collection
会更容易)实现您想要的方法:add
、remove
等。这些都会更改列表并通过 DAO 调用方法。对于示例代码,您可以查看 ORMLite 如何做到这一点 BaseForeignCollection
和 EagerForeignCollection
但这可能对您的需求来说有点过头了。
正如您提到的那样,手动维护列表会更容易。也许在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 中的多值属性