日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 默认站点!

默认站点

當前位置: 首頁 >

什么时候需要使用cqrs_在CQRS读取模型中使用Hibernate进行快速开发

發布時間:2023/12/3 36 豆豆
默认站点 收集整理的這篇文章主要介紹了 什么时候需要使用cqrs_在CQRS读取模型中使用Hibernate进行快速开发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么時候需要使用cqrs

在本文中,我將分享一些在CQRS讀取模型中使用Hibernate工具進行快速開發的技巧。

為什么要Hibernate?

Hibernate非常流行。 從外觀上看,它也很容易,而從內部看,它卻相當復雜。 它可以很容易地上手,而無需深入了解,濫用和發現問題,因為已經為時已晚。 由于所有這些原因,這幾天真是臭名昭著。

但是,它仍然是一項堅實而成熟的技術。 經過戰斗測試,功能強大,文檔齊全,并且可以解決許多常見問題。 它可以使您*非常*高效。 如果包括工具和庫,則更多。 最后,只要您知道自己在做什么,它就是安全的。

自動模式生成

使SQL模式與Java類定義保持同步相當麻煩。 在最佳情況下,這是非常繁瑣且耗時的活動。 錯誤的機會很多。

Hibernate帶有模式生成器(hbm2ddl),但其“本機”形式在生產中使用有限。 創建SessionFactory時,它只能驗證架構,嘗試更新或導出架構。 幸運的是,該實用程序可用于自定義編程用途。

我們進一步走了一步,并將其與CQRS預測集成在一起。 運作方式如下:

  • 當投影過程線程啟動時,請驗證數據庫模式是否與Java類定義匹配。
  • 如果不是,請刪除該架構并重新導出(使用hbm2ddl)。 重新啟動投影,從一開始就重新處理事件存儲。 從一開始就進行投影。
  • 如果匹配,則繼續從當前狀態更新模型。

由于這個原因,在很多時候,您幾乎不必手動輸入帶有表定義SQL。 它使開發速度大大加快。 這類似于使用hbm2ddl.auto = create-drop 。 但是, 在視圖模型中使用它意味著它實際上不會丟失數據 (在事件存儲中是安全的)。 而且,它非常聰明,僅在實際更改架構時才重新創建架構-與創建-放置策略不同。

保留數據并避免不必要的重啟不僅會縮短開發周期。 它還可能使其在生產中可用。 至少在某些條件下,請參見下文。

需要注意的是:并非架構中的所有更改都會使Hibernate驗證失敗。 一個示例是更改字段長度–只要是varchar或文本,驗證就可以通過,而不受限制。 另一個未發現的變化是可空性。

這些問題可以通過手動重新啟動投影來解決(請參見下文)。 另一種可能性是擁有一個不存儲數據的偽實體,但對其進行了修改以觸發自動重啟。 它可能只有一個名為schemaVersion字段,每次架構更改時, @Column(name = "v_4") schemaVersion @Column(name = "v_4")批注(由開發人員)都會更新。

實作

實施方法如下:

public class HibernateSchemaExporter {private final EntityManager entityManager;public HibernateSchemaExporter(EntityManager entityManager) {this.entityManager = entityManager;}public void validateAndExportIfNeeded(List<Class> entityClasses) {Configuration config = getConfiguration(entityClasses);if (!isSchemaValid(config)) {export(config);}}private Configuration getConfiguration(List<Class> entityClasses) {SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) getSessionFactory();Configuration cfg = new Configuration();cfg.setProperty("hibernate.dialect", sessionFactory.getDialect().toString());// Do this when using a custom naming strategy, e.g. with Spring Boot:Object namingStrategy = sessionFactory.getProperties().get("hibernate.ejb.naming_strategy");if (namingStrategy instanceof NamingStrategy) {cfg.setNamingStrategy((NamingStrategy) namingStrategy);} else if (namingStrategy instanceof String) {try {log.debug("Instantiating naming strategy: " + namingStrategy);cfg.setNamingStrategy((NamingStrategy) Class.forName((String) namingStrategy).newInstance());} catch (ReflectiveOperationException ex) {log.warn("Problem setting naming strategy", ex);}} else {log.warn("Using default naming strategy");}entityClasses.forEach(cfg::addAnnotatedClass);return cfg;}private boolean isSchemaValid(Configuration cfg) {try {new SchemaValidator(getServiceRegistry(), cfg).validate();return true;} catch (HibernateException e) {// Yay, exception-driven flow!return false;}}private void export(Configuration cfg) {new SchemaExport(getServiceRegistry(), cfg).create(false, true);clearCaches(cfg);}private ServiceRegistry getServiceRegistry() {return getSessionFactory().getSessionFactoryOptions().getServiceRegistry();}private void clearCaches(Configuration cfg) {SessionFactory sf = entityManager.unwrap(Session.class).getSessionFactory();Cache cache = sf.getCache();stream(cfg.getClassMappings()).forEach(pc -> {if (pc instanceof RootClass) {cache.evictEntityRegion(((RootClass) pc).getCacheRegionName());}});stream(cfg.getCollectionMappings()).forEach(coll -> {cache.evictCollectionRegion(((Collection) coll).getCacheRegionName());});}private SessionFactory getSessionFactory() {return entityManager.unwrap(Session.class).getSessionFactory();} }

該API看起來過時且繁瑣。 似乎沒有從現有SessionFactory提取Configuration的方法。 這只是用來創建工廠并扔掉的東西。 我們必須從頭開始重新創建它。 以上是我們需要的所有內容,以使其與Spring Boot和L2緩存一起正常工作。

重新開始投影

我們還實現了一種手動執行此類重新初始化的方法,在管理控制臺中顯示為按鈕。 當有關投影的某些內容發生更改但不涉及修改架構時,它會派上用場。 例如,如果值的計算/格式不同,但仍然是文本字段,則可以使用此機制來手動重新處理歷史記錄。 另一個用例是修復錯誤。

生產用途?

在開發過程中,我們一直在成功使用這種機制。 它使我們可以通過僅更改Java類而不用擔心表定義來自由地修改模式。 由于與CQRS相結合,我們甚至可以維護長期運行的演示或試點客戶實例。 數據始終在事件存儲區中是安全的。 我們可以逐步開發讀取模型架構,并將更改自動部署到正在運行的實例中,而不會丟失數據或手動編寫SQL遷移腳本。

顯然,這種方法有其局限性。 僅在很小的情況下或事件可以足夠快速地處理時,才可以在隨機的時間點重新處理整個事件存儲。

否則,可以使用SQL遷移腳本解決遷移問題,但是它有其局限性。 這通常是冒險且困難的。 可能會很慢。 最重要的是,如果更改較大并且涉及以前未包含在讀取模型中的數據(但事件中可用),則根本不選擇使用SQL腳本。

更好的解決方案是將投影(帶有新代碼)指向新數據庫。 讓它重新處理事件日志。 當它趕上來時,請測試視圖模型,重定向流量并丟棄舊實例。 提出的解決方案也與此方法完美配合。

翻譯自: https://www.javacodegeeks.com/2015/10/rapid-development-with-hibernate-in-cqrs-read-models.html

什么時候需要使用cqrs

總結

以上是默认站点為你收集整理的什么时候需要使用cqrs_在CQRS读取模型中使用Hibernate进行快速开发的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得默认站点網站內容還不錯,歡迎將默认站点推薦給好友。