使用spring jdbc时,清除外部长(+20行sql)的方法?

Jac*_*ans 20 java sql spring-jdbc

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

我看了一下:Java - 在一个外部文件中存储SQL语句,但为一些查询执行这个属性名.1,.2等,每个查询都要长20行看起来不干净.

Pan*_*kaj 28

您可以将查询放在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>
Run Code Online (Sandbox Code Playgroud)

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

<bean id="queryProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations" value="classpath:/queries.xml" />
</bean>
Run Code Online (Sandbox Code Playgroud)

在您的DAO类中注入此bean

<bean id="myDAO" class="com.xyz.dao.MyDAOImpl">
  <property name="queryProps" ref="queryProps" />
</bean>
Run Code Online (Sandbox Code Playgroud)

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

 private Properties queryProps;
Run Code Online (Sandbox Code Playgroud)

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

 String query = queryProps.getProperty("getPersonById");
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.


sip*_*uel 9

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

selectSomething: >
  SELECT column1, column2 FROM SOMETHING

insertSomething: >
  INSERT INTO SOMETHING(column1, column2)
  VALUES(1, '1')
Run Code Online (Sandbox Code Playgroud)

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

anotherSelect: <
  SELECT column1 FROM SOMETHING
  WHERE column2 IN (
    SELECT * FROM SOMETHING_ELSE
  )
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下代码在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!!!");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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


Aru*_*ran 6

这是Pankaj所回答的补充.这个在属性XML中没有CDATA并使用自动装配.我不得不将其添加为答案,因为如果我必须在评论部分中执行此操作,则无法格式化代码.

确保在spring application context xml文件中有以下命名空间.

xmlns:util="http://www.springframework.org/schema/util
Run Code Online (Sandbox Code Playgroud)

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

<util:properties id="sqls" location="classpath:oracle/sqls.xml" />
Run Code Online (Sandbox Code Playgroud)

该文件的内容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>
Run Code Online (Sandbox Code Playgroud)

自动装配以下属性

@Autowired
@Qualifier("sqls")
private Properties sqls;
Run Code Online (Sandbox Code Playgroud)

用于从Properties获取sql查询的代码

String sql = sqls.getProperty("employee.insert");
Run Code Online (Sandbox Code Playgroud)

  • 是的,那种挫败了这个恕我直言的目的.以这种方式外化的一个好处是我们可以清除查看查询,也可以直接复制sql并粘贴到sql工具中运行.MY 2 CENTS. (3认同)

Ada*_*dam 1

您可以通过在行末尾添加 \ 来在属性文件中执行多行查询。例如

queries.myquery = select \
foo, bar \
from mytable \
where baz > 10
Run Code Online (Sandbox Code Playgroud)