u010888939
2013-01-09 16:45 阅读 1.1k
已采纳

java Web 怎么记录修改的历史(包括字段的原始值和新值)

用Spring来开发一个WEb系统。比如:现在实体 Problem,Problem有一下属性:Cateory,Title,description。需求是可以更新Problem的数据库记录,但是,用户可以在页面上看到这个Problem的历史记录,需要看到具体被修改属性的原始值跟新的值。没有好的设计思路。求解。。。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

6条回答 默认 最新

  • 已采纳
    zuoshang zuoshang 2013-01-09 23:21

    看到这个需求,我第一反应是设计在java层做更新记录好像更方便。不需要任何其他知识点了。
    数据库加[b]一张[/b]表就行,比如名叫record

    表里面 entry property old new date 类似这么几个字段,java层再加一个这个表对应的实体类Record,并且有一个insert方法

    在Problem的update方法里,很容易能获取到这几个值,update成功以后创建一个Record对象insert到表里。 这样做的好处是可以收集任意一个实体类的修改记录,可能有User,Person等等。查询的时候根据entry name这个字段来区分。这样无论多少次修改,都能保存直观的历史记录。

    至于这样污染了update的代码,你可以思考下依靠spring的aop编程,比如后置通知之类的,将比较新老值,组装成Record对象等逻辑,分离到一个通用、独立的方法里。其实这一点还是需要思考一下,如果才能更优雅地实现。

    点赞 评论 复制链接分享
  • zhouhua0104 想成为工程师的码农 2013-01-09 16:51

    可以考虑分表,一个历史表一个原始表,每次更新的时候将原始数据存到历史表中,然后在更新原始表

    点赞 1 评论 复制链接分享
  • jinnianshilongnian jinnianshilongnian 2013-01-09 17:11

    1、版本号
    每修改一下 复制一条记录 并版本号+1

    2、历史表

    可以通过如下完成复制:
    1、触发器
    2、应用程序内

    点赞 评论 复制链接分享
  • tonglei85 澜冰-Tonly 2013-01-10 09:53

    可以创建一个与原表结构相同的历史表,可以比原表多一些数据操作的标记字段,然后对原表添加Trigger,在原表进行Update,Insert,Delete操作的时候向历史表添加数据(可以考虑同时添加Before Image和After Image).
    Trigger可以做得更简单一些。假设原表的表名是TBL_AAA,有若干列A1,A2...,那么Audit表就可以为AUD_AAA,设有A1,A2...,AUDIT_DT,AUDIT_MODE,AUD_IMG_TYPE;
    [code="java"]
    CREATE OR REPLACE TRIGGER TRI_AAA

    AFTER INSERT OR UPDATE

    ON TBL_AAA

    REFERENCING NEW AS NEW OLD AS OLD

    FOR EACH ROW

    DECLARE

    auditMode VARCHAR2 (6);

    curr_date date;

    BEGIN

    IF UPDATING THEN

    auditMode := 'update';

    ELSIF INSERTING THEN

    auditMode := 'insert';

    END IF;

    curr_date:=sysdate;

    IF UPDATING THEN

    insert into AUD_AAA

    (

    A1,

    A2,

    .,

    .,

    .,

    AUDIT_MODE,

    AUD_IMG_TYPE,

    AUDIT_DT

    ) values

    (

    :OLD.A1,

    :OLD.A2,

    :OLD..,

    :OLD..,

    :OLD..,

    auditMode,

    'before',

    curr_date

    );

    END IF;

    IF INSERTING or UPDATING THEN

    insert into AUD_AAA

    (

    A1,

    A2,

    .,

    .,

    .,

    AUDIT_MODE,

    AUDIT_IMG_TYPE,

    AUDIT_DT

    ) values

    (

    :NEW.A1,

    :NEW.A2,

    :NEW..,

    :NEW..,

    :NEW..,

    .auditMode,

    'after',

    curr_date

    );

    END IF;

    EXCEPTION

    WHEN OTHERS THEN

    RAISE;

    END;
    [/code]

    点赞 评论 复制链接分享
  • lyjilu2008 lyjilu2008 2013-01-10 22:36

    如果是新建一个历史表,每次复制,这样能查询出历史版本,但是如果要知道修改的字段,还需要 取出数据对比才知道,
    如果新建的表是记录 old值与new值的这种表,那么就很方便查看修改前的值与修改后的值,但这种方式不能查看历史某一版本的全部数据,根据需求把握,我以前是用的第二种方案,记录 用户修改属性,然后让管理员审核,可以只通过部分字段或者驳回部分字段。

    点赞 评论 复制链接分享
  • h248980496 h248980496 2013-01-11 10:50

    两种方式,
    一种是简历一张和原表一样的表,对每个可能修改的字段列增加一个修改值的列,再增加一个字段是版本号,这样可以随意调取任何一个版本的记录,速度快,缺点是不可复用,只能针对某一个表,如果你的原表是主子表,那你新增的表就要和原表的结构一样,比较比如原表是合同表,有合同项子表,有订单子表,你都要一一复制。
    第二种是使用修改表,建一张修改记录主表,记录修改时间,修改人,审核人等主信息,配一张修改项子表,记录修改的表名或者对象名,对象主键id,修改的对象的属性名,原值,修改值,如果是子对象,可以在对象名和对象id上拼接。这种方式适用比较多的情况,具有通用性,但是调取任何一个版本,你需要一个复原引擎,读取你指定版本之后每一个版本,进过处理才能还原到指定版本。
    两种方式的选择需要自己判断一下需求,选择适合自己的方式,至于到底是触发器控制,还是对修改逻辑进行监控就没那么重要了。

    点赞 评论 复制链接分享

相关推荐