Contact数据模型之EntityDelta

本文介绍了EntityDelta的数据模型,它是ValuesDelta的集合,用于描述联系人数据的变化。文章详细解释了其构造函数、成员变量及主要方法的功能,如如何构建EntityDelta、获取数据条目等。
public class EntityDelta implements Parcelable
EntityDelta的数据模型描述:
EntityDelta ValuesDelta 的集合,它还实现了Parcelable接口。它包含了主数据(存在ValuesDelta mValues中)和子数据.它把子数据以 ValuesDelta的形式按照它们的 mimetype存放在 HashMap<String, ArrayList<ValuesDelta>> mEntries中(拥有相同的mimetype的ValuesDelta放在同一个ArrayList).
注1EntityDelta可用于RawContact。主数据正好对应RawContact的主表,子数据正好对应RawContact的子表。
关于RawContact的更多内容参照《RawContacts
注2ValuesDelta是EntityDelta的一个内部类。更多关于ValuesDelta的,可以参考《Contact数据模型之ValuesDelta
构造函数
publicEntityDelta()
创建一个空的EntityDelta
publicEntityDelta(ValuesDelta values)
创建一个EntityDelta,并用ValuesDelta values来初始化主数据。
主要成员变量
private ValuesDeltamValues;
用于存放 主表(主数据),
private HashMap<String, ArrayList<ValuesDelta>>mEntries= Maps.newHashMap();
用于存放 子表(子数据),子数据以ValuesDelta的形式按照它们的mimetype存放在其中。
静态成员变量
public static final Parcelable.Creator<EntityDelta>CREATOR
:该变量因Parcelable而设计。
主要静态函数
public static EntityDeltafromBefore(Entity before)
用Entity before来实例化一个EntityDelta,把Entity before的 getEntityValues( )得到主数据以ValuesDelta.fromBefore的形式打包成ValuesDelta并赋予 mValues .且设置mValues的mIdColumn为RawContacts._ID。然后用before.getSubValues()得到子数据,然后以ValuesDelta.fromBefore的形式打包成 ValuesDelta 并放入 mEntries
注1:这里的Entity before对应一个RawContacts的数据。
注2:该函数在把Entity转化成EntityDelta的过程中,把Entity的子数据的 Uri uri丢失了。
因为对于update操作可以通过ValuesDelta的id就可以确定它的位置(当然Uri uri也可以确定,然而Data.CONTENT_URI是固定,所以可以丢弃 Uri uri)。
对于删除操作,有主数据的信息就可以了。
public static EntityDeltamergeAfter(EntityDelta local, EntityDelta remote)
EntityDelta remote EntityDelta local 进行mergeAfter操作。它主要是通过对EntityDelta local和EntityDelta remote中的ValuesDelta进行相应的ValuesDelta的mergeAfter操作来实现mergeAfter操作。对于主数据是直接对他们进行mergeAfter操作。对于子数据,是对同id(即ValuesDelta的mIdColumn值相同)的ValuesDelta进行mergeAfter操作。最后返回新的EntityDelta local。
注1:EntityDelta local可以为null,这时会创建一个空的EntityDelta以便处理。
注2:mergeAfter操作是针对EntityDelta local而进行,所以它会被改变。
注3:关于ValuesDelta的mergeAfter操作的更多内容可参考《Contact数据模型之ValuesDelta
主要成员函数
public ValuesDeltagetValues()
返回主数据mValues。
public booleanisContactInsert()
返回是否是Insert操作,通过调用主数据mValues的isInsert()方法来判断。
public ValuesDeltagetPrimaryEntry(String mimeType)
从子表集合变量 mEntries 返回PrimaryEntry
得到MIME类型为mimeType的PrimaryEntry。找到MIME类型为mimeType的ValuesDelta且它的isPrimary()为true,就返回该ValuesDelta。
如果没找到,但 MIME 类型为mimeType的ValuesDelta的ArrayList<ValuesDelta>至少有一个,则返回该列表上的第一个ValuesDelta。否则返回null。
public ValuesDeltagetSuperPrimaryEntry(String mimeType)
从子表集合变量 mEntries返回SuperPrimaryEntry
它直接调用getSuperPrimaryEntry(mimeType, true)。
public ValuesDeltagetSuperPrimaryEntry(String mimeType, boolean forceSelection)
从子表集合变量 mEntries返回SuperPrimaryEntry
原理和getPrimaryEntry(String mimeType)相似。但是只有forceSelection为true的情况下,才在没有找到SuperPrimaryEntry的情况下返回PrimaryEntry,如果PrimaryEntry也没找到,才返回MIME类型为mimeType的ValuesDelta的ArrayList<ValuesDelta>的第一的ValuesDelta,如果ArrayList<ValuesDelta>为空则返回null。
private ArrayList<ValuesDelta>getMimeEntries(String mimeType, boolean lazyCreate)
从子表集合变量 mEntries,得到指定MIME类型mimeType的ArrayList<ValuesDelta>,如果lazyCreate为true,在IME类型mimeType的ArrayList<ValuesDelta>没被创建的情况下,会创建它并放入HashMap<String, ArrayList<ValuesDelta>> mEntrie中。
public ArrayList<ValuesDelta>getMimeEntries(String mimeType)
直接调用getMimeEntries(mimeType, false)。
public intgetMimeEntriesCount(String mimeType, boolean onlyVisible)
从子表集合变量 mEntries,得到指定MIME类型mimeType的ValuesDelta数量。如果onlyVisible是true,则ValuesDelta还必须是isVisible()的。
public booleanhasMimeEntries(String mimeType)
返回HashMap<String, ArrayList<ValuesDelta>>中是否有MIME类型mimeType的ArrayList<ValuesDelta>。
public ValuesDeltaaddEntry(ValuesDelta entry)
向子表集合变量 mEntries加入一个ValuesDelta entry。
public ValuesDeltagetEntry(Long childId)
从子表集合变量 mEntries返回id为Long childId的ValuesDelta
public intgetEntryCount(boolean onlyVisible)
得到子表集合变量 mEntriesValuesDelta的数量,如果onlyVisible是true,则ValuesDelta还必须是isVisible()的。
public booleanequals(Object object)
返回两个EntityDelta是否相当。只有他们所包括的ValuesDelta一样才相等。(这里包括主数据ValuesDelta mValues和子数据HashMap<String, ArrayList<ValuesDelta>>)
:这里的"一样"是指ValuesDelta的equals(Object object)返回true.
private booleancontainsEntry(ValuesDelta entry)
用于检测ValuesDelta entry是否已经在子表集合变量 mEntries 中。
public voidmarkDeleted()
对包含的所有ValuesDelta进行markDeleted()操作。(这里包括主数据ValuesDelta mValues和子数据HashMap<String, ArrayList<ValuesDelta>>)
public StringtoString()
把所有ValuesDelta进行转化为String.
private voidpossibleAdd(ArrayList<ContentProviderOperation> diff,ContentProviderOperation.Builder builder)
在builder不为空的情况下,把builder生成的ContentProviderOperation加入到ArrayList<ContentProviderOperation> diff中。
1:该方法其实应该是static的才对。不知道为什么google没把它写成静态的。也许是google的失误吧。
public voidbuildAssert(ArrayList<ContentProviderOperation> buildInto)
/**
* Build a list of {@link ContentProviderOperation} that will assert any
* "before" state hasn't changed. This is maintained separately so that all
* asserts can take place before any updates occur.
*/
用主数据mValues的 IdRawContacts.VERSION生产一个 RawContacts.CONTENT_URI上的AssertQuery形builder,并加入ArrayList<ContentProviderOperation> buildInto)。
:该函数的真正意义应该是在对数据库操作时(Provide中)进行数据库更新时 确保数据的一致性。即数据在我们读到EntityDelta并没有改变过。
public voidbuildDiff(ArrayList<ContentProviderOperation> buildInto)
该函数负责把该EntityDelta转化为ArrayList<ContentProviderOperation>,以便进行数据库操作。它主要是调用ValuesDelta的buildDiff来进行ContentProviderOperation,然后把他们整合起来。
注1:对于全新的插入操作,需要在操作前把主表mValues的 RawContacts.AGGREGATION_MODE设置为 RawContacts.AGGREGATION_MODE_SUSPENDED,等子数据都插入完了才设置为 RawContacts.AGGREGATION_MODE_DEFAULT
注2:对于更新操作,但是子数据有插入操作的同上。
注3:如果主数据时插入操作,那么子数据也必须是插入操作,否则会抛异常。
注4:对于全EntityDelta的删除操作,只需要主表的信息就可以了,因为它的每个子表都存有主表的Id(即Data.RAW_CONTACT_ID).
注5:创建AssertQuery形的builder,可用这样的形式: final ContentProviderOperation.Builder builder = ContentProviderOperation.newAssertQuery(RawContacts.CONTENT_URI)
protected BuilderbuildSetAggregationMode(Long beforeId, int mode)
用Long beforeId, int mode生成update的Builder。
public intdescribeContents()
返回0.// Nothing special about this parcel
:该方法来自Parcelable。
public voidwriteToParcel(Parcel dest, int flags)
把主表和子表数据都写到Parcel。
:该方法来自Parcelable。
public voidreadFromParcel(Parcel source)
从Parcel source中读取主表和子表数据。
在设计房地产领域的概念数据模型时,需要从整体业务需求出发,明确关键实体及其关系。房地产信息管理系统的核心目标包括提高效率、降低成本、提升服务质量以及增强决策支持能力[^1]。因此,概念模型的设计应围绕这些目标展开,确保数据结构能够有效支持业务流程和决策分析。 ### 概念模型设计 房地产信息系统的概念模型通常包括以下核心实体: - **房产**(Property):表示可供出售或出租的物业,属性包括房产编号、类型、面积、位置、价格等。 - **业主**(Owner):持有房产的个人或公司,属性包括姓名、联系方式、身份证号或营业执照号等。 - **客户**(Client):购房或租房的个人或公司,属性包括姓名、联系方式、购房偏好等。 - **交易**(Transaction):记录房产的买卖或租赁信息,属性包括交易时间、金额、交易类型等。 - **经纪人**(Agent):促成房产交易的专业人员,属性包括姓名、联系方式、所属公司等。 这些实体之间的关系包括: - 一个业主可以拥有多个房产。 - 一个客户可以进行多次交易。 - 一个经纪人可以促成多个交易。 - 一个交易涉及一个房产、一个客户和一个经纪人。 ### 数据库设计 在数据库设计阶段,需要将概念模型转化为具体的数据库结构。通常采用E-R(Entity-Relationship)模型来表示实体及其关系,这有助于与项目团队和客户沟通设计意图[^2]。 #### E-R模型 E-R模型包括实体、属性和关系三个基本要素: - **实体**:用矩形表示,如“房产”、“业主”等。 - **属性**:用椭圆形表示,连接到相应的实体。 - **关系**:用菱形表示,连接相关实体。 例如,房产与业主之间的“拥有”关系可以用菱形连接两个矩形表示。 #### 数据库表结构示例 基于上述概念模型,可以设计如下数据库表结构(以MySQL为例): ```sql CREATE TABLE Owner ( owner_id INT PRIMARY KEY, name VARCHAR(100), contact VARCHAR(50) ); CREATE TABLE Property ( property_id INT PRIMARY KEY, type VARCHAR(50), area DECIMAL(10,2), location VARCHAR(255), price DECIMAL(10,2), owner_id INT, FOREIGN KEY (owner_id) REFERENCES Owner(owner_id) ); CREATE TABLE Client ( client_id INT PRIMARY KEY, name VARCHAR(100), contact VARCHAR(50), preference TEXT ); CREATE TABLE Agent ( agent_id INT PRIMARY KEY, name VARCHAR(100), contact VARCHAR(50), company VARCHAR(100) ); CREATE TABLE Transaction ( transaction_id INT PRIMARY KEY, property_id INT, client_id INT, agent_id INT, transaction_date DATE, amount DECIMAL(10,2), transaction_type VARCHAR(20), FOREIGN KEY (property_id) REFERENCES Property(property_id), FOREIGN KEY (client_id) REFERENCES Client(client_id), FOREIGN KEY (agent_id) REFERENCES Agent(agent_id) ); ``` ### 数据模型优化 在实际应用中,还需要考虑数据模型的优化问题,例如维度模型的使用和分区策略。对于大规模数据存储,应避免因时间推移导致的分区数量膨胀问题[^4]。可以通过合理的分区策略(如按年或按季度分区)来控制分区数量,同时确保查询性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值