什么时候需要使用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缓存一起正常工作。

重新开始投影

我们还实现了一种手动执行此类重新初始化的方法,在管理控制台中显示为按钮。 当有关投影的某些内容发生更改但不涉及修改架构时,它会派上用场。 例如,如果值的计算/格式不同,但仍然是文本字段,则可以使用此机制来手动重新处理历史记录。 另一个用例是修复错误。

生产用途?

cqrs_hibernate

在开发过程中,我们一直在成功使用这种机制。 它使我们可以通过仅更改Java类而不用担心表定义来自由地修改模式。 由于与CQRS相结合,我们甚至可以维护长期运行的演示或试点客户实例。 数据始终在事件存储区中是安全的。 我们可以逐步开发读取模型架构,并将更改自动部署到正在运行的实例中,而不会丢失数据或手动编写SQL迁移脚本。

显然,这种方法有其局限性。 仅在很小的情况下或事件可以足够快速地处理时,才可以在随机的时间点重新处理整个事件存储。

否则,可以使用SQL迁移脚本解决迁移问题,但是它有其局限性。 这通常是冒险且困难的。 可能会很慢。 最重要的是,如果更改较大并且涉及以前未包含在读取模型中的数据(但事件中可用),则根本不选择使用SQL脚本。

更好的解决方案是将投影(带有新代码)指向新数据库。 让它重新处理事件日志。 当它赶上来时,请测试视图模型,重定向流量并丢弃旧实例。 提出的解决方案也与此方法完美配合。

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

什么时候需要使用cqrs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336844.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 隐藏了什么_JAVA程序中封装与隐藏是什么意思

qq_遁去的一_1隐藏就是封装吧。。。。封装是把过程和数据包围起来&#xff0c;对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念&#xff0c;即现实世界可以被描绘成一系列完全自治、封装的对象&#xff0c;这些对象通过一个受保护的接口访问其他对象。封装是一…

esb 和 开源esb_如果今天完成,ESB会是什么样子?

esb 和 开源esbJavaOne 2015即将结束&#xff0c;这又是一次很棒的社区活动。 我和Rafael进行了两次会议和一次HOL 。 我最喜欢的会议之一实际上是&#xff1a;谈论ESB&#xff0c;如果今天完成的话。 我以为那是过去&#xff1f; 我通常也倾向于这样说。 但是&#xff0c;系统…

五皇后问题 java_Java的5个古怪问题

五皇后问题 java我们有机会接触到一些最奇怪的Java难题 即使是最有经验的Java开发人员&#xff0c;也会在这篇文章中发现令人困惑的问题。 或者至少是有趣的&#xff08;绝对不公平&#xff09;。 在经历了Java Deathmatch冒险之后&#xff0c;我们决定这次发布一系列不同的问…

java加密成固定长度_Java使用MD5加密,生成的密文长度只有31位

在使用MD5加密时&#xff0c;生成的密文长度只有31位&#xff0c;该怎么解决&#xff1f;代码如下&#xff1a;public static String toMd5(String str) {String re null;byte encrypt[];try {byte[] tem str.getBytes();MessageDigest md5 MessageDigest.getInstance("…

可以自定义模板的ide_将IDE检查应用于自定义Java批注

可以自定义模板的ideJ2SE 5中注释的引入改变了我们编写和处理Java的方式。 除了Java SE的预定义注释外 &#xff0c;框架&#xff0c;IDE和工具包还引入了自己的自定义注释 。 Checker框架提供了一些示例&#xff0c;说明如何使用自定义批注在Java中增加类型安全性 。 在本文中…

java设置弹出框为模态_点击按钮弹出模态框的一系列操作代码实例

实现功能提交按钮功能&#xff1a;点击提交按钮的时候都会弹出模态框&#xff0c;但是有不同的状态&#xff1a;审核状态未通过&#xff1a;弹出未通过理由的input输入框&#xff0c;模态框中除了取消和确定按钮&#xff0c;新增确定并保存医院的按钮审核状态已通过&#xff1a…

java中bpmn流程图_Java学习之BPMN知识以及Activiti的流程部署

BPMN的介绍Activiti项目是一项新的基于Apache许可的开源BPM平台&#xff0c;从基础开始构建&#xff0c;旨在提供支持新的BPMN 2.0标准&#xff0c;包括支持对象管理组(OMG)&#xff0c;面对新技术的机遇&#xff0c;诸如互操作性和云架构&#xff0c;提供技术实现。那什么是BP…

javaone_JavaOne 2015 –第二十版十大收获

javaone我们刚刚在旧金山有了JavaOne的第二十版。 这将是我自2004年以来第十二次参加不间断的系列活动。最大的教训是什么&#xff0c;可以揭示Java的未来。 模块化斗争 自从Java 2007首次提到模块以来&#xff0c;已经花费了将近9年的时间&#xff0c;或者说&#xff0c;直到…

java批量处理数据库语句_Java项目中调用bat批处理进行多用户数据库备份

Java项目中调用bat批处理配合使用BCP进行多用户数据的备份一、项目需求最近项目中需要对数据库(Sql Server系列数据库)进行备份。项目中的需求不是简单的整个数据库的备份&#xff0c;而是根据用户来备份&#xff0c;具体的备份策略如下&#xff1a;①系统为某一赛事管理类型的…

mycat和应用程序集成_企业应用程序集成简介

mycat和应用程序集成本文是我们名为“ EAI的Spring集成 ”的学院课程的一部分。 在本课程中&#xff0c;向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来&#xff0c;您将深入研究Spring Integration的基础知识&#xff0c;例如通道&#xff0c;转…

activemq和jms_带有ActiveMQ和Maven的JMS Sender应用程序

activemq和jms我们已经看到了如何使用ActiveMQ和Maven创建JMS Receiver应用程序 。 让我们看看我们如何类似地创建JMS Sender应用程序 。 web.xml与创建接收器应用程序时使用的相同&#xff1a; <web-app xmlns"http://java.sun.com/xml/ns/javaee"xmlns:xsi&qu…

java经纬度曲线简化_JAVA 后台计算 经纬度 最短距离

1、 代码块package com.ilogie.tms.util;import java.io.IOException;import java.math.BigDecimal;import java.text.MessageFormat;public class LocationUtils {// 以下为 获得 两点之间最短距离private static final BigDecimal EARTH_RADIUS MathUtil.toBigDecimal(6378.…

java ee的小程序_在Java EE应用程序中实现自动重试

java ee的小程序最初&#xff0c;我想将此博客称为“ 具有拦截器驱动的重试策略的灵活超时 ”&#xff0c;但后来我认为它太“繁重”。 该声明以及修改后的标题应该&#xff08;希望&#xff09;使您了解此帖子可能谈论的内容;-) 触发 这篇文章主要由我在较早的一篇文章中收到…

jboss eap 7_EAP 7 Alpha和Java EE 7入门

jboss eap 7红帽JBoss企业应用程序平台7&#xff08;JBoss EAP 7&#xff09;是基于开放标准构建并符合Java Enterprise Edition 7规范的中间件平台。 它建立在WildFly等经过验证的创新开源技术之上&#xff0c;这将使Java EE 7的开发更加容易。 这是有关如何开始使用最新ALPHA…

为什么说php单线程,php单线程的缺点是什么?

PHP即“超文本预处理器”&#xff0c;是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言&#xff0c;与C语言类似&#xff0c;是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习&#xff0c;使用广泛&#xff0c;主要适用于Web开发领…

openshift 部署_在OpenShift上部署Java EE微服务

openshift 部署我昨天用WildFly Swarm在博客上发布了有关简单JAX-RS微服务的博客。 您学习了如何使用Maven构建所谓的“胖子”&#xff0c;还使用Maven Docker插件对我们的微服务进行了Docker化并在Docker Machine上本地运行。 这是在本地测试事物的好方法。 到目前为止&#x…

apache.camel_Apache Camel 2.16发布–十大亮点

apache.camelApache Camel 2.16于上周五发布。 这篇博客文章是我尝试在此新版本中进行前10名&#xff08;加1作为奖励&#xff09;的亮点。 1.动态到 来自骆驼用户的最常见的常见问题是&#xff0c;如何将消息发送到端点&#xff0c;uri应该使用消息中的动态值&#xff08;例…

设计模式示例_责任链设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

edmonds算法matlab,匈牙利算法的matlab实现

匈牙利算法算法简介算法原理算法实现(附代码)测试算法简介下面摘用百度百科中的解释。匈牙利算法(Hungarian method)是由匈牙利数学家Edmonds于1965年提出&#xff0c;因而得名。匈牙利算法是基于Hall定理中充分性证明的思想&#xff0c;它是二分图匹配最常见的算法&#xff0c…

java jooq_将Java EE与jOOQ结合使用的初学者指南

java jooqJava EE附带了自己的持久性API&#xff1a;JPA。 当您想要将RDBMS实体&#xff08;表/关系&#xff09;映射到Java实体&#xff08;类&#xff09;时&#xff0c;JPA最强大&#xff0c;主要遵循1&#xff1a;1映射策略。 其背后的思想是&#xff0c;业务逻辑通常不像关…