帐户电子邮件激活的设计(考虑到Hibernate)

时间:2009-05-04 17:22:22

标签: hibernate

我有一个设计问题,我想要一些输入。以下是约束条件:

  1. 每个用户在注册帐户时都必须有一个可用的电子邮件地址。注册其用户帐户时,应发送激活电子邮件,其中包含一个激活码的链接,必须遵循该激活码才能激活该帐户。
  2. 每个用户帐户只存在于一个公司中的一个办公室。
  3. 公司的第一个注册用户创建公司和一个办公室。然后,第一个用户邀请其他公司用户。
  4. 公司可以互相互动,但前提是公司的第一批用户被激活(即他们在注册后点击了各自的激活链接)。
  5. 这是一个如何解决它的小UML图:

    alt text

    在上图中,省略了一些细节。该图仅显示类和字段。当谈到字段时,它们只是在概念上用于显示应存储哪些信息,请忽略它们的范围。

    一些想法和问题:

    • User和NotActivatedUser大致相同。他们应该是一个单独的课程还是分开?如果它们是分开的,你会使用哪种形式的Hibernate继承持久性?
    • 如果帐户在一段时间后未激活,则应将其删除。如果它是第一个用户,也创建了用户公司和Office,这两个用户也应该被删除。我们还需要NotActivatedOffice和NotActivatedCompany吗? (用于数据库中的清洁分离。)

    您将如何设计此类解决方案?您是否认为在数据库中保持非活动和活动实体是重要的?为什么或为什么不呢?

4 个答案:

答案 0 :(得分:1)

我不会使用继承来表示User对象的状态(已激活/已停用)。在这里,组合(聚合)是一个更好的选择。

通过使用聚合,AbstractUser简单地成为User。您可能希望使用类对激活建模,而不是使用激活相关属性污染User类。这样你就可以获得一个漂亮而干净的对象模型。

在数据库级别,您仍然可以决定将两个对象存储在同一个表/记录中,称为Component mapping。或者您可以决定将用户和激活存储在单独的表中(也称为Entity mapping)。

Hibernate支持两种类型的映射,这主要是配置问题。

User类将包含以下属性:

  • 给定名称
  • 电子邮件
  • 激活(引用激活对象)

Activation类将包含以下属性:

  • activationCode(string)
  • sentOn(发送电子邮件的时间)
  • activatedOn(默认为null,设置为当用户点击激活链接时的当前日期/时间,告诉系统用户是否在非空时激活了他的帐户)

您可以使用HQL查询来了解哪家公司至少有一位激活用户:

from Office o 
   left join fetch o.company 
where 
   o.administrator.activatedOn != null

此查询假定您已在Office类中定义了“管理员”属性。 “管理员”将是对创建Office的用户的引用。在数据库中,'offices'表具有用户记录的外键。

通过这种方式对关系建模,您可以更改Office的管理员(例如,他离开或被Office / Company解雇)。这一切都取决于你的用例......

我还在Activation类中添加了一个sentOn属性,用于在一段时间后清理未激活的帐户(在UML图中缺失)。

答案 1 :(得分:0)

我不会将NotActivatedUser与ActivatedUser分开;只有一个User表,并有一个“Activated”列,默认为0(未激活)。

一件事;我将激活代码拆分为一个单独的表,可能是“ActivationMethod”。如果您想让用户激活除电子邮件以外的帐户,并且还可以从User表中删除“activationCode”列,那么将来可以实现可扩展性。

我不担心未经激活的办事处和公司;根据您上面描述的使用计划,在用户激活自己(以及办公室和公司)之前,他们不应该被其他人使用。一个问题;为什么允许未激活的用户创建Office和公司?为什么不将该活动限制为仅激活用户?

答案 2 :(得分:0)

就个人而言,我不会为激活和未激活的用户编写两个类,因为它只是一个状态。如果激活之前的状态变得复杂,您可以引用激活状态等。

如果您在用户上有“OfficeOwner”标志,则您知道何时删除办公室而没有任何复杂的逻辑。

答案 3 :(得分:0)

对于已激活和未激活的用户使用相同的表,您需要检查用户的状态,以及应用程序中各处的办公室和公司的状态。

出于这个原因,我可能会使用一个activationrequest表,其中包含创建用户所需的所有信息,以及执行激活时公司的办公室。