我们当前的项目不使用 Hibernate(由于各种原因),我们使用 Spring 的 SimpleJdbc 支持来执行我们所有的数据库操作。我们有一个实用程序类,它抽象了所有 CRUD 操作,但复杂的操作是使用自定义 SQL 查询执行的。
目前,我们的查询以字符串常量的形式存储在服务类本身中,并提供给一个实用程序以由 SimpleJdbcTemplate 执行。我们处于一个必须平衡可读性和可维护性的僵局。类本身内的 SQL 代码更易于维护,因为它与使用它的代码一起存在。另一方面,如果我们将这些查询存储在外部文件(平面文件或 XML)中,SQL 本身将比转义的 java 字符串语法更具可读性。
有没有人遇到过类似的问题?什么是好的平衡?您将自定义 SQL 保存在项目中的什么位置?
示例查询如下:
private static final String FIND_ALL_BY_CHEAPEST_AND_PRODUCT_IDS =
" FROM PRODUCT_SKU T \n" +
" JOIN \n" +
" ( \n" +
" SELECT S.PRODUCT_ID, \n" +
" MIN(S.ID) as minimum_id_for_price \n" +
" FROM PRODUCT_SKU S \n" +
" WHERE S.PRODUCT_ID IN (:productIds) \n" +
" GROUP BY S.PRODUCT_ID, S.SALE_PRICE \n" +
" ) FI ON (FI.PRODUCT_ID = T.PRODUCT_ID AND FI.minimum_id_for_price = T.ID) \n" +
" JOIN \n" +
" ( \n" +
" SELECT S.PRODUCT_ID, \n" +
" MIN(S.SALE_PRICE) as minimum_price_for_product \n" +
" FROM PRODUCT_SKU S \n" +
" WHERE S.PRODUCT_ID IN (:productIds) \n" +
" GROUP BY S.PRODUCT_ID \n" +
" ) FP ON (FP.PRODUCT_ID = T.PRODUCT_ID AND FP.minimum_price_for_product = T.sale_price) \n" +
"WHERE T.PRODUCT_ID IN (:productIds)";
这是它在平面 SQL 文件中的样子:
--namedQuery: FIND_ALL_BY_CHEAPEST_AND_PRODUCT_IDS
FROM PRODUCT_SKU T
JOIN
(
SELECT S.PRODUCT_ID,
MIN(S.ID) as minimum_id_for_price
FROM PRODUCT_SKU S
WHERE S.PRODUCT_ID IN (:productIds)
GROUP BY S.PRODUCT_ID, S.SALE_PRICE
) FI ON (FI.PRODUCT_ID = T.PRODUCT_ID AND FI.minimum_id_for_price = T.ID)
JOIN
(
SELECT S.PRODUCT_ID,
MIN(S.SALE_PRICE) as minimum_price_for_product
FROM PRODUCT_SKU S
WHERE S.PRODUCT_ID IN (:productIds)
GROUP BY S.PRODUCT_ID
) FP ON (FP.PRODUCT_ID = T.PRODUCT_ID AND FP.minimum_price_for_product = T.sale_price)
WHERE T.PRODUCT_ID IN (:productIds)