Spring 프로젝트에 SQL 문구를 입력합니다.sql 파일의 방법

6916 단어 springsql 문장
앞말
우리가 JDBC를 사용할 때 모든 SQL 문장을 Java 파일에 다 쓰면 Java가 Here Document를 지원하지 않기 때문에 여러 줄 문자열은 더하기 기호를 사용하거나 Java 8의 String.join() 방법으로 연결하고 SQL 문장을 문법으로 밝힐 수 없기 때문에 이런 SQL 문자열은 읽기가 매우 나쁘다.왜 Hibernate 같은 것을 사용하지 않고 원시적인 SQL 문장을 쓰지 않는지 말하지 말고, 복잡한 시스템을 조작할 때 JdbcTemplate를 사용하세요.
그래서 우리는 SQL 문장을 단독*에 쓸 수 있기를 바랍니다.ql 파일에서 이렇게 하면 많은 편집기가 문법이 밝게 표시되거나 입력할 때 스마트 알림을 받을 수 있다.
방법이 있어요.sql은 속성 파일로 사용됩니다. 그러면 여러 줄의 SQL 문장을 정의할 때 이렇게 해야 합니다.

select.user=select id, firstname, lastname, address \
 from users \
 where id=?
불러오면 getProperty("select.user") 로 상응하는 문장을 인용할 수 있다.속성 파일의 줄 바꿈은 Bash와 마찬가지로\를 사용하지만 *.sql은 순수한 SQL 파일이 아니기 때문에 문법을 정확하게 밝힐 수 없습니다. 일단 SQL의 주석을 쓰면 더욱 혼란스럽습니다.
그래서 우리의 두 번째 방안은: 우선 *.sql은 위장된 속성 파일이 아니라 진정한 SQL 파일이어야 합니다. 프로그램에서 모든 SQL 문장을 인용할 수 있도록 각자의 키를 어떻게 표시해야 합니까?여기의 영감은 여전히 Linux Shell에서 나온 것입니다. Linux Shell에서 실행 환경을 지정하는 데 특수한 주석 방식을 사용했습니다#!,... 와 같다

#!/bin/bash
#!/usr/bin/env python
모방하여 바가지를 씌우고, SQL의 표준 주석은--, 그래서 우리도 특별한 주석을 만듭니다--!,그 다음 문자열은 다음 SQL 문장의 키입니다.
예를 들면 다음과 같다.

--!select.user
select id, firstname, lastname, address
 from users
 where id=?

--!update.user
update ........
--! 그 다음key select.user, 파일이 끝나지 않았거나 다음 --!이전에는 이 키에 대응하는 전체 SQL 문장의 내용이었다.
본고는 Spring 프로젝트를 예로 삼아 이 SQL 파일에 어떻게 대응하는지 보여 주지만, 사실은 다른 유형의 자바 프로젝트에서도 참고할 수 있다.
이것은 진정한 SQL 파일이기 때문에 Spring에서는 속성 파일로 직접 불러올 수 없습니다.이 파일을 src/resources/sql/queries로 저장한다고 가정하십시오.ql, 그래서 우리는 직접 사용할 수 없습니다

@PropertySource(value = "classpath:sql/queries.sql")
public class AppConfig { ...... }
파일을 로드합니다.
다행히도 Property Source 주해에는 속성 factory가 하나 더 있습니다. 유형은 Property Source Factory입니다. 이것이 바로 우리가 글을 쓰는 곳입니다. 바로 Sql Property Source Factory를 사용자 정의하는 데 착수합니다. 그 중에서 하나를 *할 방법이 있습니다.sql의 내용을 Properties로 변환합니다.그래서 앞으로 우리는 sql/queries를 불러와야 한다.ql 파일에 사용되는 주석 형식은

@PropertySource(value = "classpath:sql/queries.sql", factory = SqlPropertySourceFactory.class)
public class AppConfig { ......}
다음은 본고의 관건입니다. SqlPropertySourceFactory의 실현을 보십시오.
SqlPropertySourceFactory.java

package cc.unmi;
 
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
 
public class SqlPropertySourceFactory implements PropertySourceFactory {
 
 private static final String KEY_LEADING = "--!";
 
 @Override
 public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
 
  Deque<Pair> queries = new LinkedList<>();
 
  new BufferedReader(resource.getReader()).lines().forEach(line -> {
   if (line.startsWith(KEY_LEADING)) {
    queries.addLast(new Pair(line.replaceFirst(KEY_LEADING, "")));
   } else if (line.startsWith("--")) {
    //skip comment line
   } else if (!line.trim().isEmpty()) {
    Optional.ofNullable(queries.getLast()).ifPresent(pair -> pair.lines.add(line));
   }
  });
 
  Map<String, Object> sqlMap = queries.stream()
    .filter(pair -> !pair.lines.isEmpty())
    .collect(Collectors.toMap(pair -> pair.key,
      pair -> String.join(System.lineSeparator(), pair.lines),
      (r, pair) -> r, LinkedHashMap::new));
 
  System.out.println("Configured SQL statements:");
  sqlMap.forEach((s, o) -> System.out.println(s + "=" + o));
 
  return new MapPropertySource(resource.toString(), sqlMap);
 }
 
 private static class Pair {
  private String key;
  private List<String> lines = new LinkedList<>();
 
  Pair(String key) {
   this.key = key;
  }
 }
}
우리가 정의한 src/resources/sql/queries.sql 파일의 내용은 다음과 같습니다.

--external queries in this file
 
--!select_users_by_id
select id, firstname, lastname, address
 from users where id=?
 
--!add_user
insert users(id, firstname, lastname, address)
 values(DEFAULT, ?, ?, ?)
--
 
--!no_statement
---
 
--!update
update users set firstname=? where id=?
마지막으로, SpringBoot 방식으로 Spring 프로젝트를 시작합니다.
DemoApplication.java

package cc.unmi;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
 
@SpringBootApplication
@PropertySource(value = "classpath:sql/queries.sql", factory = SqlPropertySourceFactory.class)
public class DemoApplication implements EnvironmentAware {
 
 private Environment env;
 
 @Value("${add_user}")
 private String sqlAddUser;
 
 @Bean
 public String testBean() {
  System.out.println("SQL_1:" + env.getProperty("select_users_by_id"));
  System.out.println("SQL_2:" + sqlAddUser);
  return "testBean";
 }
 
 public static void main(String[] args) {
  SpringApplication.run(DemoApplication.class, args);
 }
 
 @Override
 public void setEnvironment(Environment environment) {
  env = environment;
 }
}
일반적인 속성으로 변환되었으므로 표현식${key} 또는 env.getProperty("key") 을 통해 인용할 수 있습니다.
위의 코드를 실행하면 다음과 같이 출력됩니다.

Configured SQL statements:
select_users_by_id=select id, firstname, lastname, address
 from users where id=?
add_user=insert users(id, firstname, lastname, address)
 values(DEFAULT, ?, ?, ?)
update=update users set firstname=? where id=?
SQL_1:select id, firstname, lastname, address
 from users where id=?
SQL_2:insert users(id, firstname, lastname, address)
 values(DEFAULT, ?, ?, ?)
이렇게 간단해.그럼요.sql 파일은 엄격하게 쓰는 것이 가장 좋다. 우리는 앞으로 Sql PropertySource Factory를 점차적으로 보완하여 더 많은 가능성에 대응할 수 있다.어쨌든 이것은 진정한 SQL 파일이며, 코드에서도 그 어떠한 다른 속성처럼 그 안에 정의된 SQL 문장을 쉽게 인용할 수 있다.
총결산
이상은 바로 이 글의 전체 내용입니다. 본고의 내용이 여러분의 학습이나 업무에 어느 정도 도움이 되고 의문이 있으면 댓글로 교류하시기 바랍니다.

좋은 웹페이지 즐겨찾기