有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当使用SpringJDBC时,用java干净的方式外部化长(+20行sql)?

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

我看了一下:Java - Storing SQL statements in an external file但是对一些查询执行propertyname.1、.2等操作,每个查询的长度都超过了20行,看起来并不是很干净


共 (5) 个答案

  1. # 1 楼答案

    您可以在属性文件中执行多行查询,方法是将\放在行的末尾。比如说

    queries.myquery = select \
    foo, bar \
    from mytable \
    where baz > 10
    
  2. # 2 楼答案

    这是对Pankaj has answered的补充。这一个在属性XML中没有CDATA,并且使用自动连接。我必须添加这个作为答案,因为如果我必须在注释部分这样做,我无法格式化代码

    确保在spring应用程序上下文xml文件中有以下名称空间

    xmlns:util="http://www.springframework.org/schema/util
    

    将以下bean添加到spring应用程序上下文xml中

    <util:properties id="sqls" location="classpath:oracle/sqls.xml" />
    

    文件sqls.xml的内容为

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
        <comment>Employee Queries</comment>
        <entry key="employee.insert">
            INSERT
            INTO EMPLOYEE
              (
                ID,
                NAME,
                AGE,
                DEPARTMENT
              )
            VALUES
              (
                EMPLOYEE_SEQ.NEXTVAL,
                ?,
                ?,
                ?
              )
        </entry>
    </properties>
    

    自动连接属性,如下所示

    @Autowired
    @Qualifier("sqls")
    private Properties sqls;
    

    从属性获取sql查询的代码

    String sql = sqls.getProperty("employee.insert");
    
  3. # 3 楼答案

    您可以将查询放入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

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

    在DAO类中定义queryProps,不要忘记为此使用setter方法

     private Properties queryProps;
    

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

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

    希望这有帮助

  4. # 4 楼答案

    JdbcTestUtils拿走一点战利品 方法“executeSqlScript”和“readScript”

  5. # 5 楼答案

    不久前,我遇到了同样的问题,并提出了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文件映射到包含查询名称/字符串的映射