在我们的后端系统中,有很多情况需要更新对象,例如更新商品、更新商品价格、更新用户、更新状态、更新订单(取消、更新价格)等。现在有些对象我们有一个特殊的日志表,例如order_update_log ,记录更新操作。有些仅记录到文件,例如
logger.info("goods update: before: {}, after: {}", oldGoods, newGoods)
感觉处理这些琐碎的事情很烦人,是否存在一些更好的方式/工具来处理这样的记录器?
最佳答案
有一个非常好的东西叫做方面。
您可以为您的项目编写仅了解跟踪商品对象更改的方面。假设你有Goods
类:
public class Goods {
private Integer id;
private String name;
private BigDecimal cost;
// Getters, Setters
...
}
映射到数据库表goods并具有相应字段:
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);
}
}
因此,让我们为您的项目添加一些神奇的方面,以跟踪 cargo 的变化。现在创建另一个表,其中包含用于存储 user
的附加字段。和datetime
更新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 方法时,您都会在 Goods_log 中获得包含新商品状态的记录。
要使此代码正常工作,应使用 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.
配置编译器AJC编译器路径:<path_to>/aspectjtools-1.8.7.jar
关于java - 是否存在更好的方式来记录更新历史记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33803359/