我所在的位置是,我们公司拥有高度可配置的数据库搜索服务,因此以编程方式配置查询非常有用。Criteria API 很强大,但是当我们的一位开发人员重构其中一个数据对象时,在我们运行单元测试或更糟糕的是,在我们的生产环境中运行并运行之前,标准限制不会表明它们已被破坏。最近,由于这个问题,我们有一个重构项目的工作时间出乎意料地增加了一倍,这是项目计划中的一个差距,如果我们知道它真正需要多长时间,我们可能会采取另一种方法。
我想使用 Example API 来解决这个问题。如果我们在真正的 POJO 属性上指定“where”条件,Java 编译器会大声指出我们的查询是错误的。但是,Example API 中的功能只有这么多,并且在很多方面都受到限制。举个例子
Product product = new Product();
product.setName("P%");
Example prdExample = Example.create(product);
prdExample.excludeProperty("price");
prdExample.enableLike();
prdExample.ignoreCase();
在这里,正在查询属性“name”(其中 name 像 'P%'),如果我要删除或重命名字段“name”,我们会立即知道。但是房产的“价格”呢?它被排除是因为 Product 对象有一些默认值,所以我们将“价格”属性名称传递给排除过滤器。现在,如果“价格”被删除,这个查询在语法上将是无效的,直到运行时你才会知道。瘸。
另一个问题 - 如果我们添加第二个 where 子句会怎样:
product.setPromo("Discounts up to 10%");
由于调用了 enableLike(),此示例将匹配促销文本“折扣高达 10%”,以及“折扣高达 10,000,000 美元”或任何其他匹配的内容。一般来说,Example 对象的查询范围修改,例如 enableLike() 或 ignoreCase() 并不总是适用于检查的每个属性。
这是第三个也是主要的问题——其他特殊标准呢?使用标准示例框架无法让每件产品的价格都超过 10 美元。无法按促销、降序对结果进行排序。如果 Product 对象加入了某个制造商,则也无法在相关的制造商对象上添加标准。也没有办法在制造商的标准上安全地指定 FetchMode(尽管这通常是 Criteria API 的一个问题 - 无效的获取关系会默默地失败,甚至更像是一个定时炸弹)
对于上述所有示例,您将需要返回到 Criteria API 并使用属性的字符串表示来进行查询 - 同样,消除了示例查询的最大好处。
Example API 有哪些替代方案可以获得我们需要的编译时建议?