我试图理解"更改数据库而不更改代码"。目前正在使用springboot,java,thymeleaf和云代工厂处理微服务。
我有一个spring boot应用程序,并使用云代工厂将数据库作为服务附加。
我的问题是我看到微服务的目的是允许在不改变代码的情况下轻松更改服务。
这是我被困的地方
在java中我有一个sql脚本,"从ORDER中选择*,其中Status =' ACCEPTED';"
图片source
我的数据库将使用CUPS作为服务附加到云代工厂 " JDBC:预言:瘦:用户名/密码//主机:端口/服务名"
因此,我想将此数据库更改为CUSTOMER表(将其作为不同的数据库)。这将引发错误,因为CUSTOMER表不会从ORDER中选择*,其中Status =' ACCEPTED';"
我已经更改了数据库,但是我还是不得不回到我的代码并更改sql脚本吗?
我尝试解决此问题
因此,不要在java中对我的sql脚本进行硬编码,而是从ORDER中选择*,其中Status =' ACCEPTED';"
我创建了一个系统环境变量,并将其设置为sqlScript,其值为select * from ORDER,其中Status =' ACCEPTED'
然后在java中我调用了env变量String sqlScript = System.getenv(" sqlScript");
所以现在用户可以通过环境变量改变它,而不是回到java来改变sql脚本。
这是解决我的问题的一种非常肮脏的方法,什么是更好的替代方案?
我知道我的理解逻辑确实是错误的。请引导我走正确的道路。
答案 0 :(得分:0)
在我看来,最好使用像Flyway或Liquibase这样的东西,这些东西在Spring Boot中很好地集成了。您可以找到更多信息here。
我更喜欢Liquibase,因为它使用更高级别的格式来描述您的数据库迁移,允许您非常轻松地切换数据库。这样,您还可以为每个环境使用不同的数据库,例如:
也可以从现有数据库导出当前数据库模式,使其具有Flyway或Liquibase的初始版本,这将为您的脚本提供良好的基线。
答案 1 :(得分:0)
我认为在不更改代码的情况下更改数据库这一短语' 不意味着如果您在数据库中添加/删除字段,则无需修改代码库 - 它只是没有任何意义。
它的真正意义在于您应该使用良好的数据库抽象,因此如果您需要更改数据库供应商,请说,MYSQL到OracleDB您的Java代码应该保留相同。唯一可能不同的是一些配置。
一个很好的例子是ORM,如 Hibernate 。无论你在下面使用什么SQL数据库,你都可以编写一次java代码。要切换数据库,您需要更改的唯一内容是方言配置属性(实际上它并不容易,但可能比我们耦合到一个特定的数据库更容易)。
Hibernate为您提供了对SQL数据库的良好抽象。现在我们有了一个新的趋势 - 对SQL和NoSQL等不同的数据库系列进行抽象。 因此,在理想的世界中,即使您想将MySQL更改为MongoDB甚至Neo4j ,您的代码库也应保持不变。 Spring Data可能是试图解决此问题的最流行的框架。我最近发现的另一个框架是Kundera,但到目前为止我还没有使用它。
回答您的问题 - 您不需要将SQL查询保留为系统变量。您需要做的就是以您选择的语言使用适当的抽象。