2

Take my domain class for example

public class Person
{
  private Integer id;
  private String name;
  private String address;
  private String telephone;

  //Accessors here..
}

This is great for storing 1 instance of a given Person, however, the name for example would most likely change over time, and I would like to retain any previous values, I may wish to see what addresses this person has lived at over the past 10 years.

What are my options for doing this? This is a Java web app so I could potentially have an AUDIT_LOG table on my schema, but that doesn't sound a very reliable way of keeping track of these changes

Another thought is to have a PersonFamily and keep all instances of person, assuming the last item in the List is the most recent, such as..

 public class PersonFamily
 {
   private Integer id;
   private List<Person> persons;

   //Accessors here...
 }

Any suggestions on how I can achieve this? Is there a really clean and simple process I've missed?

Thanks


Is there anywhere in your code where you set your session.IDUsers? You initialize it as a blank ''. Coldfusion does not populate it for you. The session scope is a place that will remember things for that user that you put there for a specified period of time inactivity, usually 20 minutes. So hopefully, somewhere before you run your query you have additional logic that fills that in, otherwise you are asking the database for a user named, ''.

This is just a point of style, but the following may work better for you:

<cfset Session.IDUsers =''>

<!--- Do something here to populate Session.IDUsers --->

<!--- Creates a blank query - not necessary, but can reduce errors later --->
<cfset Recordset1 = queryNew("UserID")>

<!--- Populate the query from the database --->
<cfquery name="Recordset1" datasource="cfGossip">
  SELECT *
  FROM   users
  WHERE  users.IDUsers = <cfqueryparam value="#Session.IDUsers#">
</cfquery>

<!--- If the query has data, use it, otherwise show generic message --->
<cfoutput>
<cfif Recordset1.recordcount>
    <p>Welcome #Recordset1.UserID#.</p>
<cfelse>
    <p>Welcome new user!</p>
</cfif>
</cfoutput>

<!--- OR since we used queryNew("userID"), we can simplify without throwing an error. ---->
<cfoutput>
    <p>Welcome <cfif len(Recordset1.userID)>#Recordset1.userID#.<cfelse>new user!</cfif></p>
</cfoutput>

Putting the cfoutput outside the paragraph block will make it easier if you have additional variables to insert into the text. (but will work either way)

Regardless of all that, unless you forgot to share a bit more of the code, I think the issue is that the session.IDUsers is blank and needs to be populated before the query. I hope this helps!

4

5 回答 5

1

您可能会考虑的一个选项是与类相关的简单版本号:

public class Person 
{
  private Integer id;
  private Integer version;

  private String name;
  private String address;
  private String telephone;

  //additional class stuff...

}

使用这种方法,每当更新名称、地址或其他属性时,版本号都会增加 1。这保留了以前版本下的原始数据,并允许通过 id 轻松检索所有以前的版本,id 不会改变。

于 2009-12-03T19:48:20.577 回答
1
public class Person
{
  private Integer id;
  private String name;
  private Address address;

 }


public class Address {
  Integer id;
  String line1;
  String line2.
}

然后在您的数据库中将其建模为:

  • ID
  • 姓名

地址

  • ID
  • 第1行
  • 线2

带有字段的PersonAddressHistory表:

  • ID
  • 个人身份
  • 地址标识
  • 活动日期

最后一个表维护与一个人相关联的当前地址和以前地址的列表,当前地址是最后一个条目(即,id 的最大值)。

于 2009-12-03T19:31:55.970 回答
0

我认为这取决于您对历史数据的使用要求。

例如,以您的人为例,我将在数据库中有一个“当前/过去”字段。对于大多数用途,我只会得到“当前”的记录,它会像现在一样运行 - 不会更改 DAO 或对象模型(可能添加开始/结束时间戳除外)。

当您确实需要历史记录时,很可能是出于非常特定的原因,您可以在那时获得一个按更改日期排序的单独列表。这将与常用的数据模型分开。

当有人更改姓名时,克隆 Person,将新记录更改为“Previous”,然后更改现有记录的名称,然后在同一事务中提交这两项更改。

请注意,如果历史数据非常常用,则上述内容不相关,您应该有一个列表,其中第一个条目是最新的。地址历史记录可能就是这种情况,它在金融应用程序中非常常用。除了姓名更改之外,最常见的更改是结婚/离婚,因此您的数据模型中应该有一个额外的字段 - 娘家姓。

于 2009-12-03T19:36:32.730 回答
0

谷歌的时间模式或事件源。

http://martinfowler.com/eaaDev/timeNarrative.html

于 2009-12-03T19:29:44.853 回答
0

有很多方法可以做到这一点,最简单的方法是拥有一个“Person”,其中包含“PersonH​​istory”对象列表。每当您调用 setter 时,请创建一个新的 PersonH​​istory 对象,其值与最近的值相同。然后更改更改的字段,并将其保存在您的列表中。

这样做的问题是您将拥有大量冗余数据,每次更改都有一个。如果这将由 A 数据库支持,尽管不是存储一个巨大的列表,但您可以在进行更改时将每个旧实例转储到数据库(因此您只将最新的实例存储在内存中)

否则,您可以为每个变量创建一个列表,并存储一个带有值和“步骤”的元组。因此,每次更改变量时,您都会更新一个计数器,并将该计数器与更改的值一起存储。

于 2009-12-03T19:31:20.853 回答