微服务 - 在不更改代码的情况下更改服务的真正含义是什么?
Microservice - What does changing service without changing code really mean?
我正在努力理解 "changing database without changing code"。目前使用 springboot、java、thymeleaf 和 cloud foundry 处理微服务。
我有一个 spring 引导应用程序并使用 cloud foundry 将数据库作为服务附加。
我的问题是我发现微服务的目的是允许在不更改代码的情况下轻松更改服务。
这是我卡住的地方
在java我有一个sql脚本,"select * from ORDER where Status = 'ACCEPTED';"
图片source
我的数据库将作为服务附加到使用 CUPS 的 Cloud Foundry 上
"jdbc:oracle:thin:username/password//host:port/servicename"
假设我想将此数据库更改为 CUSTOMER table(将其视为不同的数据库)。这将引发错误,因为 CUSTOMER table 不会有 "select * from ORDER where Status = 'ACCEPTED';"
我已经更改了数据库,但我是否仍然需要返回到我的代码并更改 sql 脚本?
我尝试解决这个问题
所以不要在 java "select * from ORDER where Status = 'ACCEPTED';"
中硬编码我的 sql 脚本
我创建了一个系统环境变量并将其设置为 sql脚本,值为 select * from ORDER where Status = 'ACCEPTED'
然后在java中我调用了环境变量String sqlScript= System.getenv("sqlScript");
所以现在用户可以通过环境变量更改它,而不是返回 java 来更改 sql 脚本。
这是解决我的问题的一种非常肮脏的方法,什么是更好的替代方法?
我知道我的理解逻辑真的是错误的。请引导我走上正确的道路。
在我看来,最好使用 Flyway or Liquibase, which are integrated really well in Spring Boot. You can find more information here。
我更喜欢 Liquibase,因为它使用更高级别的格式来描述您的数据库迁移,让您可以非常轻松地切换数据库。这样,您还可以在每个环境中使用不同的数据库,例如:
- 本地开发期间的HSQLDB
- MySQL 在开发和测试中
- 生产中的 Oracle
也可以从现有数据库中导出当前数据库模式,以在 Flyway 或 Liquibase 中拥有初始版本,这将为您的脚本提供良好的基线。
我认为短语 'changing database without changing code' 并不 意味着如果你 add/remove 数据库中的字段你不必修改你的代码库 - 它只是没有任何意义。
真正的意思是您应该使用良好的数据库抽象,以防万一您需要将数据库供应商从 MYSQL 更改为 OracleDB您的 Java 代码应该保持不变。唯一可能不同的是一些配置。
一个很好的例子就是像 Hibernate 这样的 ORM。您只需编写 java 代码一次,而不管您在下面使用的 SQL 数据库是什么。要切换数据库,您唯一需要更改的是方言配置 属性(实际上这并不容易,但可能比我们耦合到一个特定的数据库更容易)。
Hibernate 为您提供了对 SQL 数据库 的良好抽象。现在我们有一个新趋势——对不同的数据库家族进行抽象,比如 SQL 和 NoSQL。 因此在理想情况下,即使您想将 MySQL 更改为 MongoDB 甚至 Neo4j,您的代码库也应该保持不变。 Spring Data probably is the most popular framework that tries to solve this problem. Another framework that I found recently is Kundera不过我还没用过
所以回答您的问题 - 您不需要将 SQL 查询保留为系统变量。您需要做的就是在您选择的语言中使用适当的抽象。
我正在努力理解 "changing database without changing code"。目前使用 springboot、java、thymeleaf 和 cloud foundry 处理微服务。
我有一个 spring 引导应用程序并使用 cloud foundry 将数据库作为服务附加。
我的问题是我发现微服务的目的是允许在不更改代码的情况下轻松更改服务。
这是我卡住的地方
在java我有一个sql脚本,"select * from ORDER where Status = 'ACCEPTED';"
图片source
我的数据库将作为服务附加到使用 CUPS 的 Cloud Foundry 上 "jdbc:oracle:thin:username/password//host:port/servicename"
假设我想将此数据库更改为 CUSTOMER table(将其视为不同的数据库)。这将引发错误,因为 CUSTOMER table 不会有 "select * from ORDER where Status = 'ACCEPTED';"
我已经更改了数据库,但我是否仍然需要返回到我的代码并更改 sql 脚本?
我尝试解决这个问题
所以不要在 java "select * from ORDER where Status = 'ACCEPTED';"
中硬编码我的 sql 脚本
我创建了一个系统环境变量并将其设置为 sql脚本,值为 select * from ORDER where Status = 'ACCEPTED'
然后在java中我调用了环境变量String sqlScript= System.getenv("sqlScript");
所以现在用户可以通过环境变量更改它,而不是返回 java 来更改 sql 脚本。
这是解决我的问题的一种非常肮脏的方法,什么是更好的替代方法?
我知道我的理解逻辑真的是错误的。请引导我走上正确的道路。
在我看来,最好使用 Flyway or Liquibase, which are integrated really well in Spring Boot. You can find more information here。
我更喜欢 Liquibase,因为它使用更高级别的格式来描述您的数据库迁移,让您可以非常轻松地切换数据库。这样,您还可以在每个环境中使用不同的数据库,例如:
- 本地开发期间的HSQLDB
- MySQL 在开发和测试中
- 生产中的 Oracle
也可以从现有数据库中导出当前数据库模式,以在 Flyway 或 Liquibase 中拥有初始版本,这将为您的脚本提供良好的基线。
我认为短语 'changing database without changing code' 并不 意味着如果你 add/remove 数据库中的字段你不必修改你的代码库 - 它只是没有任何意义。
真正的意思是您应该使用良好的数据库抽象,以防万一您需要将数据库供应商从 MYSQL 更改为 OracleDB您的 Java 代码应该保持不变。唯一可能不同的是一些配置。
一个很好的例子就是像 Hibernate 这样的 ORM。您只需编写 java 代码一次,而不管您在下面使用的 SQL 数据库是什么。要切换数据库,您唯一需要更改的是方言配置 属性(实际上这并不容易,但可能比我们耦合到一个特定的数据库更容易)。
Hibernate 为您提供了对 SQL 数据库 的良好抽象。现在我们有一个新趋势——对不同的数据库家族进行抽象,比如 SQL 和 NoSQL。 因此在理想情况下,即使您想将 MySQL 更改为 MongoDB 甚至 Neo4j,您的代码库也应该保持不变。 Spring Data probably is the most popular framework that tries to solve this problem. Another framework that I found recently is Kundera不过我还没用过
所以回答您的问题 - 您不需要将 SQL 查询保留为系统变量。您需要做的就是在您选择的语言中使用适当的抽象。