使用弹簧jdbc时外化长(+20行sql)的干净方法?[已关闭]

2022-09-02 02:37:47

我想将应用程序中的一些大型查询外部化到属性\sql\xml 文件中。然而,我想知道是否有人对如何以干净的方式实现这一目标有一些建议。大多数结果建议使用ORM框架,但由于某些数据限制,这不适用。

我看了一下:Java - 将SQL语句存储在外部文件中,但对一些查询执行此属性名称.1,.2等,每个查询都比20行更长,似乎并不那么干净。


答案 1

您可以将查询放在 xml 文件中

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<properties>
<entry key="getPersonById">
    <![CDATA[
        Select Name From Person 
        Where Id =?     
    ]]>

</entry>    
<entry key="getPersonBySSN">
    <![CDATA[

    ]]>
</entry>

</properties>

在Spring应用程序上下文中,加载此xml文件

<bean id="queryProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations" value="classpath:/queries.xml" />
</bean>

将此豆注入您的 DAO 类

<bean id="myDAO" class="com.xyz.dao.MyDAOImpl">
  <property name="queryProps" ref="queryProps" />
</bean>

在 DAO 类中定义查询程序,不要忘记为此设置 setter 方法

 private Properties queryProps;

现在,您可以像这样访问DAO中的查询 -

 String query = queryProps.getProperty("getPersonById");

希望这有帮助。


答案 2

前段时间我遇到了同样的问题,并提出了YAML。它支持多行字符串属性值,因此您可以在查询文件中编写如下内容:

selectSomething: >
  SELECT column1, column2 FROM SOMETHING

insertSomething: >
  INSERT INTO SOMETHING(column1, column2)
  VALUES(1, '1')

这里,和是查询名称。所以它非常方便,并且包含很少的特殊字符。查询由空行分隔,并且每个查询文本必须缩进。请注意,查询绝对可以包含自己的缩进,因此以下内容是完全有效的:selectSomethinginsertSomething

anotherSelect: <
  SELECT column1 FROM SOMETHING
  WHERE column2 IN (
    SELECT * FROM SOMETHING_ELSE
  )

然后,您可以在SnakeYAML库的帮助下,使用以下代码将文件的内容读取到哈希映射中:

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.FileUtils;
import java.io.FileReader;

import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileNotFoundException;

public class SQLReader {
  private Map<String, Map> sqlQueries = new HashMap<String, Map>();

  private SQLReader() {
    try {
      final File sqlYmlDir = new File("dir_with_yml_files");
      Collection<File> ymlFiles = FileUtils.listFiles(sqlYmlDir, new String[]{"yml"}, false);
      for (File f : ymlFiles) {
        final String fileName = FilenameUtils.getBaseName(f.getName());
        Map ymlQueries = (Map)new Yaml().load(new FileReader(f));
        sqlQueries.put(fileName, ymlQueries);
      }
    }
    catch (FileNotFoundException ex) {
      System.out.println("File not found!!!");
    }
  }
}

在上面的示例中,创建了一个映射映射,将每个 YAML 文件映射到包含查询名称/字符串的映射。


推荐