1

在我们的后端系统中,更新对象的情况有很多,比如更新商品、更新商品价格、更新用户、更新状态、更新订单(取消、更新价格)等等。现在有些对象我们有一个专门的日志表,例如 order_update_log ,用于记录更新操作。一些只记录到文件,例如

logger.info("goods update: before: {}, after: {}", oldGoods, newGoods)

感觉处理这些琐碎的事情很烦人,是否存在一些更好的方式/工具来处理这样的记录器?

4

2 回答 2

1

如果您使用 ORM 来持久化您的数据,您可以使用 Hibernate 的 Listners/events 之类的东西来响应数据更新(并将它们记录到数据库或审计日志等)。对于 hibernate,信息在此处进行了详细说明:https ://docs.jboss.org/hibernate/orm/3.3/reference/en/html/events.html但显然您需要调查您的持久性工具提供给您的内容。

于 2015-11-19T12:55:10.307 回答
1

有一个很好的东西叫做 Aspects。您可以为您的项目编写只知道跟踪货物对象变化的方面。假设你有Goods课:

public class Goods {
    private Integer id;
    private String name;
    private BigDecimal cost;

    // Getters, Setters
    ...
}

它映射到具有相应字段的数据库表货物:

CREATE TABLE `goods` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `name` varchar NOT NULL,
    `cost` DECIMAL NOT NULL,
    PRIMARY KEY (`id`)
);

假设你有GoodsService

public class GoodsService {

    public Goods read(Integer id) {
        Goods goods = /* Read goods from database */
        return goods;
    }

    public void write(Goods goods) {
        /* Write goods to database */
    }
}

并且GoodsController使用GoodsService

public class GoodsController {

    private GoodsService goodsService;

    public void updateGoods(Integer id, String name, BigDecimal cost) {
        Goods goods = goodsService.read(id);
        goods.setName(name);
        goods.setCost(cost);
        goodsService.write(goods);
    }

}

因此,让我们为您的项目添加一些方面的魔法来跟踪商品的变化。现在创建另一个表,其中包含用于存储userdatetime更新goods对象的附加字段:

CREATE TABLE `goods_log` (
    `revision` INT NOT NULL AUTO_INCREMENT,
    `id` INT NOT NULL,
    `name` varchar NOT NULL,
    `cost` DECIMAL NOT NULL,
    `user` varchar NOT NULL,
    `timestamp` DATETIME NOT NULL,
    PRIMARY KEY (`revision`,`id`)
);

编写方面类:

@Aspect
public class GoodsLogger {
    @Before(value = "execution(* org.antonu.service.GoodsService.write(..)) && args(goods)")
    public void logWrite(Goods goods) {
        // Get current user and timestamp,
        // Write it to goods_log table, as well as goods data
    }
}

而已!您的业​​务逻辑代码没有改变,读起来很清楚。但是每次调用 GoodsService 的 write 方法时,您都会在商品日志中记录新的商品状态。

为了使这段代码工作,它应该用 AJC 编译器编译,还应该包括 aspectjrt 库。它可以通过maven轻松完成:

<properties>
    <aspectj.version>1.8.7</aspectj.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

现代 IDE Intellij Idea 应该自动使用AJC带有上述 maven 配置的编译器。如果没有,您必须通过File - Settings - 'Build, Execution, Deployment' - Compiler - Java Compiler - Use compiler: Ajc.Path to AJC 编译器配置编译器:<path_to>/aspectjtools-1.8.7.jar

于 2015-11-19T14:45:20.407 回答