2015-11-19 109 views
1

在我們的後端系統中,有很多情況需要更新對象,例如更新商品,更新商品價格,更新用戶,更新狀態,更新訂單(取消,更新價格)等。現在我們有一個特殊的日誌表,例如order_update_log,以記錄更新操作。只有一些記錄器要歸檔,例如是否存在一些更好的方式來記錄更新歷史記錄?

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

感覺過程中,這些瑣碎的事情很煩人的,確實存在一些更好的方法/工具來處理記錄器這樣的嗎?

+0

我知道你想記錄的東西,但你想實現什麼?你需要登錄哪種信息? – Matt

+0

如果我理解正確,這些更新日誌在通用應用程序日誌中時會令你感到厭煩。你可以爲它們配置一個特殊的記錄器。在代碼中你必須引用那個(額外的)Logger,比如Logger updLog = LogManager.getLogger(「UPDATELOG」);'。然後使用該記錄器實例進行更新。在配置中,您可以添加appender到該記錄器等。 – Fildor

+0

謝謝!簡而言之,就是我想要記錄對象更新軌道,例如,g誰在做什麼,同時開發人員可以擺脫這個工作,就像春天幫助開發處理事務和依賴注入一樣。 – zhuguowei

回答

1

有非常好的事情稱爲方面。 您可以爲您編寫僅考慮跟蹤商品對象變化的項目。假如你有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 */ 
    } 
} 
使用 GoodsService

GoodsController是:

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的寫入方法時,您都將在goods_log中獲得具有新貨物狀態的記錄。

爲了使這個代碼的工作,應該與AJC編譯器編譯,也aspectjrt庫應包括在內。它可以通過行家很容易做到:

<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

+0

謝謝!很有幫助。但是因爲我使用了spring boot,我會嘗試使用spring aop語法。 – zhuguowei

1

如果您使用ORM來保存您的數據,您可以使用類似Hibernate的Listners/events來響應數據更新(並將它們記錄到數據庫或審覈日誌等) 對於休眠信息在這裏詳細說明:https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/events.html,但顯然你需要調查你的持久性工具提供給你什麼。

+1

謝謝,也是一個好主意,因爲我用spring數據jpa(基於hiberante),我會試試你的方法。 – zhuguowei

相關問題