0

我在一个spring,hibernate项目中工作,数据库是oracle。我有用于持久性相关操作的 DAO 层。

在我的所有表中,我有create_dateupdate_date列代表分别在表中插入和更新行时的时间戳。

有一个要求是,每当发生任何插入/更新操作时,我都必须更新该特定表的上述两个时间戳列。例如,如果我的 DAO 层有两种方法,比如说 m1 和 m2 负责分别影响 t1 和 t2 表。现在,如果调用 m1 方法,则 t1 表的时间戳列将被更新,即 对于插入,create_date列将被更新,并且对于任何更新update_date列都将被更新。

我有 Spring AOP 的想法,所以我想使用 AOP 来实现上述要求,不过,我不太确定是否可以使用 AOP 来实现。

请让我知道我是否可以使用 AOP 来满足这个要求。如果可能的话,请向我提供如何实现它的输入。

4

4 回答 4

3

我已经使用 Spring AOP 为我的应用程序中的一个模块实现了更新日期功能。PFB代码供您参考

希望这会有所帮助。我想知道是否也可以为变量设置切入点。我知道使用 spring 的方面 j 实现它可能是不可能的。但是任何解决方法的人:P

    **
    * @author Vikas.Chowdhury
    * @version $Revision$ Last changed by $Author$ on $Date$ as $Revision$
    */
   @Aspect
   @Component
public class UpdateDateAspect
{
    @Autowired
    private ISurveyService surveyService;

    Integer surveyId = null;

    Logger gtLogger = Logger.getLogger(this.getClass().getName());

    @Pointcut("execution(* com.xyz.service.impl.*.saveSurvey*(..)))")
    public void updateDate()
    {

    }

    @Around("updateDate()")
    public Object myAspect(final ProceedingJoinPoint pjp)
    {

        // retrieve the runtime method arguments (dynamic)
        Object returnVal = null;
        for (final Object argument : pjp.getArgs())
        {

            if (argument instanceof SurveyHelper)
            {
                SurveyHelper surveyHelper = (SurveyHelper) argument;
                surveyId = surveyHelper.getSurveyId();

            }

        }
        try
        {
            returnVal = pjp.proceed();
        }
        catch (Throwable e)
        {
            gtLogger.debug("Unable to use JointPoint :(");
        }
        return returnVal;
    }

    @After("updateDate()")
    public void updateSurveyDateBySurveyId() throws Exception
    {
        if (surveyId != null)
        {
            surveyService.updateSurveyDateBySurveyId(surveyId);
        }
    }
}
于 2012-11-03T13:53:17.970 回答
1

我会改用 Hibernate 拦截器,这就是它们的用途。例如,需要此类字段的实体可以实现以下接口:

public interface Auditable {
    Date getCreated();
    void setCreated(Date created);
    Date getModified();
    void setModified(Date modified);
}

然后拦截器总是在保存时设置修改的字段,并且仅在尚未设置时设置创建的字段。

于 2012-09-08T11:12:46.160 回答
1

尽管您一直在为您的问题寻求 Spring AOP 解决方案,但我想指出,使用数据库触发器可以实现相同的结果,例如createdINSERT操作期间自动设置时间戳,modifiedUPDATE语句期间自动设置时间戳。

这可能是一个很好的解决方案,特别是如果不是所有的 DB 调用都通过 AOP 捕获的逻辑(例如,当因为方法不符合模式而绕过切入点定义时,甚至使用独立 SQL 客户端完全绕过代码时),这样即使有人从不同的应用程序更新条目,您也可以强制执行修改后的时间戳。

但是,它的缺点是您需要在所有受影响的表上定义触发器。

于 2012-09-08T13:18:00.560 回答
0

Spring AOP 应该可以使用@Before建议。如果您将实体传递给 create 方法,请设置通知,create_date并为更新方法设置update_date. 您可能需要考虑以下事项以使您的工作更轻松:

  • 让所有实体实现一个通用接口来设置create_dateupdate_date。这使您无需进行反思即可获得共同的建议。
  • 有一个命名约定来标识我们 DAO 上的创建和更新方法。这将使您的切入点更简单。
于 2012-09-08T10:55:09.073 回答