복붙노트

[SQL] 자바 - 외부 파일에 보관 SQL 문이 [마감]

SQL

자바 - 외부 파일에 보관 SQL 문이 [마감]

나는 외부 파일에 SQL 문을 저장하는 자바 라이브러리 / 프레임 워크 / 기술 찾고 있어요. (DBA를 포함) 지원 팀은 경우 데이터베이스 스키마 변경 또는 조정을 위해 동기화를 유지하기 위해 (약간) 문을 변경 할 수 있어야한다.

여기 요구 사항은 다음과 같습니다

노트:

지금까지, 나는 SQL 문을 저장하기 위해 외부 파일을 사용하여 다음과 같은 자바 라이브러리를 찾을 수 있었다. 그러나, 나는 주로 저장보다는 도서관이 가죽 모든 JDBC "복잡성"에 관심이 있어요.

사람이 노력하고 테스트 솔루션을 추천 할 수 있습니까?

해결법

  1. ==============================

    1.다만이 같은 키와 값의 페어로 간단한 자바 속성 파일을 만듭니다 :

    다만이 같은 키와 값의 페어로 간단한 자바 속성 파일을 만듭니다 :

    users.select.all = select * from user
    

    파일의 값을 읽어 봄 구성을 사용하여 DAO 클래스에과 주입의 호텔 중 한 private 필드를 선언합니다.

    UPDATE : 여러 줄이 표기법을 사용에 SQL 문을 지원하려는 경우 :

    users.select.all.0 = select *
    users.select.all.1 = from   user
    
  2. ==============================

    2.이 작업을 수행해야하는 경우, 당신은 MyBatis로 프로젝트를 봐야한다. 나는 그것을 사용하지 않은,하지만 여러 번 추천 들었습니다.

    이 작업을 수행해야하는 경우, 당신은 MyBatis로 프로젝트를 봐야한다. 나는 그것을 사용하지 않은,하지만 여러 번 추천 들었습니다.

    SQL 실제로 코드, 그리고 꽉를 호출하는 자바 코드에 연결되어 있기 때문에 분리 SQL 및 Java는, 내가 좋아하는 접근 방식이 아니다. 유지 보수 및 분리 된 코드가 어려울 수 디버깅.

    물론이 저장 발동을 사용하지 않습니다. 그들은 단지 DB와 응용 프로그램 사이의 트래픽을 줄여 성능을 향상시키기 위해 사용되어야한다.

  3. ==============================

    3.스프링 JDBC를 사용하는 경우 청소 방법 여기에 내 대답을 붙여 넣으면 (+20 라인 SQL) 긴 구체화하기 위해?

    스프링 JDBC를 사용하는 경우 청소 방법 여기에 내 대답을 붙여 넣으면 (+20 라인 SQL) 긴 구체화하기 위해?

    나는 얼마 전에 같은 문제에 직면하고, YAML 함께했다. 당신이 당신의 쿼리 파일에 다음처럼 작성할 수 있습니다 그것은 여러 줄 문자열 속성 값을 지원합니다 :

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

    여기에, selectSomething 및 insertSomething 쿼리 이름입니다. 그래서 정말 편리하고 매우 적은 특수 문자가 포함되어 있습니다. 쿼리는 빈 라인으로 구분되며, 각 쿼리 텍스트는 들여 쓰기를해야합니다. 쿼리가 절대적으로 다음 완벽하게 유효 그래서, 자신의 들여 쓰기를 포함 할 수 있습니다 :

    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 파일을 매핑 생성됩니다.

  4. ==============================

    4.이 때 직면 구현 한 간단한 해결책은 다음 SQL로 동적 특성을 주입 MessageFormat.format (문자열 [] 인수)를 사용하여 파일 (mySql.properties)에 SQL / DML을 구체화 하였다.

    이 때 직면 구현 한 간단한 해결책은 다음 SQL로 동적 특성을 주입 MessageFormat.format (문자열 [] 인수)를 사용하여 파일 (mySql.properties)에 SQL / DML을 구체화 하였다.

    예를 들면 : mySql.properties :

    select    *
        from      scott.emp
                  join scott.dept on (emp.deptno = dept.deptno)
        where     emp.ename = {0}
    

    유틸리티 방법 :

    public static String format(String template, Object[] args) {
        String cleanedTemplate = replaceSingleQuotes(template);
        MessageFormat mf = new MessageFormat(cleanedTemplate);
        String output = mf.format(args);
        return output;
    }
    private static String replaceSingleQuotes(String template) {
        String cleaned = template.replace("'", "''");
        return cleaned;
    }
    

    다음과 같이 사용 :

    String sqlString = youStringReaderImpl("/path/to/file");
    String parsedSql = format(sqlString, new String[] {"bob"});
    
  5. ==============================

    5.또한 속성 파일에서 SQL을 읽을 아파치 코 몬즈 DbUtils의 QueryLoader 클래스를 사용할 수 있습니다. 그러나, 당신은 종류의가 JdbcTemplate와 같은 목적을 제공 DbUtils를 사용해야합니다.

    또한 속성 파일에서 SQL을 읽을 아파치 코 몬즈 DbUtils의 QueryLoader 클래스를 사용할 수 있습니다. 그러나, 당신은 종류의가 JdbcTemplate와 같은 목적을 제공 DbUtils를 사용해야합니다.

  6. ==============================

    6.ElSql 라이브러리는이 기능을 제공합니다.

    ElSql 라이브러리는이 기능을 제공합니다.

    ElSql는 외부 SQL 파일 (elsql)로드 할 수있는 작은 jar 파일 (여섯 개 public 클래스)로 구성되어 있습니다. 이 파일은 선택적으로 간단하게 파일을로드하는 것보다 약간 더 동작을 제공하는 간단한 형식을 사용합니다 :

    -- an example comment
    @NAME(SelectBlogs)
      @PAGING(:paging_offset,:paging_fetch)
        SELECT @INCLUDE(CommonFields)
        FROM blogs
        WHERE id = :id
          @AND(:date)
            date > :date
          @AND(:active)
            active = :active
        ORDER BY title, author
    @NAME(CommonFields)
      title, author, content
    
    // Java code:
    bundle.getSql("SelectBlogs", searchArgs);
    

    이 파일은 코드에서 참조 할 수 @NAME 블록으로 분할된다. 각 블록은 상당한 공백 들여 쓰기에 의해 정의된다. 같은 FETCH 페이징에 필요한 코드를 삽입합니다 @PAGING / OFFSET. 지정된 변수 (빌드 동적 검색을 돕기) @AND있는 경우에만 출력된다. DSL은 검색에서 와일드 카드에 대한 = 대 LIKE를 처리합니다. 옵션 DSL 태그의 목표는 데이터베이스에 의존하지 않는 방법 빌드 동적 SQL을하려고 할 때 종종 충돌 공통의 기초를 제공하는 것입니다.

    블로그 나 사용자 가이드에 대한 자세한 정보를 원하시면.

  7. ==============================

    7.당신은 스프링을 사용하고 당신이 당신의 빈 공장에서 수업을받을 때 주입하여 콩 파일에 저장된 SQL 문을 가질 수 있습니다. 그 클래스는 코드 단순화에 빈 파일을 통해 구성 할 수 있습니다 인 SimpleJdbcTemplate의 인스턴스를 사용할 수 있습니다.

    당신은 스프링을 사용하고 당신이 당신의 빈 공장에서 수업을받을 때 주입하여 콩 파일에 저장된 SQL 문을 가질 수 있습니다. 그 클래스는 코드 단순화에 빈 파일을 통해 구성 할 수 있습니다 인 SimpleJdbcTemplate의 인스턴스를 사용할 수 있습니다.

  8. ==============================

    8.그것은 봄에서 클래스를 사용하여 수행하는 간단하고 신뢰할 수 있습니다. 당신의 SQL 파일을 클래스 패스에 어떤 위치에 저장합니다. 이것은 당신이 원하는 경우에만 SQL을 포함하는 JAR 파일에있을 수 있습니다. 그런 다음 스트림으로 파일을로드하고 문자열로 변환 아파치 IOUtils를 사용하는 Spring의 ClassPathResource가를 사용합니다. 당신은 당신의 선택의 인 SimpleJdbcTemplate, 또는 DB 코드를 사용하여 SQL을 실행할 수 있습니다.

    그것은 봄에서 클래스를 사용하여 수행하는 간단하고 신뢰할 수 있습니다. 당신의 SQL 파일을 클래스 패스에 어떤 위치에 저장합니다. 이것은 당신이 원하는 경우에만 SQL을 포함하는 JAR 파일에있을 수 있습니다. 그런 다음 스트림으로 파일을로드하고 문자열로 변환 아파치 IOUtils를 사용하는 Spring의 ClassPathResource가를 사용합니다. 당신은 당신의 선택의 인 SimpleJdbcTemplate, 또는 DB 코드를 사용하여 SQL을 실행할 수 있습니다.

    난 당신이 SQL 파일 이름에 해당이 사용자가 선택한 규칙을 다음과 같은 것을 공공 문자열 필드에 간단한 자바 클래스를 취하는 유틸리티 클래스를 만드는 것이 좋습니다. 그런 다음 이름 지정 규칙을 준수하는 SQL 파일을 찾아 이동 및 문자열 필드에 할당하는 ClassPathResource가 클래스와 함께 반사를 사용합니다. 당신은 SQL을 필요로 할 때 그 후에 바로 클래스 필드를 참조하십시오. 그것은 간단 위대한 작동하고 원하는 목표를 달성 할 수있다. 또한 잘 착용 클래스와 기술을 사용합니다. 아무것도 공상. 나는 몇 년 전에했다. 훌륭한 작품. 코드를 가서 너무 게으른. 당신은 시간 자신을 알아내는이없는 것입니다.

  9. ==============================

    9.난 강력하게 저장 프로 시저를 사용하는 것이 좋습니다 것입니다. 이런 종류의 일을 정확히 그들이있어 것입니다.

    난 강력하게 저장 프로 시저를 사용하는 것이 좋습니다 것입니다. 이런 종류의 일을 정확히 그들이있어 것입니다.

  10. ==============================

    10.이 작업을 수행하기 위해 현지화 시설을 사용할 수 있습니다. 그런 다음 "삽입 된 바 foo는 -"대신 영어 또는 프랑스어 버전의 "oraclish"버전을 얻을 로케일로 데이터베이스의 이름을 사용합니다.

    이 작업을 수행하기 위해 현지화 시설을 사용할 수 있습니다. 그런 다음 "삽입 된 바 foo는 -"대신 영어 또는 프랑스어 버전의 "oraclish"버전을 얻을 로케일로 데이터베이스의 이름을 사용합니다.

    번역은 일반적으로 속성 파일에 저장되며, 이러한 특성 파일을 편집 할 수 있도록하여 응용 프로그램 지역화를위한 좋은 도구가 있습니다.

  11. ==============================

    11.동적 쿼리는 JDBC와 ORM 사이에 그 찾는 뭔가 좋은 오픈 소스 프레임 워크입니다. (1) 일반 SQL. - 그것은 외부 파일에 일반 SQL을 저장합니다. 중복되는 태그, 지원 코멘트.

    동적 쿼리는 JDBC와 ORM 사이에 그 찾는 뭔가 좋은 오픈 소스 프레임 워크입니다. (1) 일반 SQL. - 그것은 외부 파일에 일반 SQL을 저장합니다. 중복되는 태그, 지원 코멘트.

    /* It also supports comment.
    This code is in an external file 'sample.sql', Not inisde java code.*/
    listUsers : select * from user_table
    where user_id= $$;  /* $$ will automatically catch a parameter userId */
    

    2 확장 SQL. - 그것은 다른 파일 및 하위 쿼리를 포함하는 매개 변수를 지원합니다.

    listUsers:
    select
        id, amount, created
        @checkEmail{ ,email } 
    from user_table
    where amount > $amt and balance < $amt
        @checkDate { and created = $$ }
        @checkEmail{ and email in (
            select email from vip_list ) } ;        
    /* Above query can be four queries like below.
    1. listUsers
    2. listUsers.checkDate 
    3. listUsers.checkEmail
    4. listUsers.checkDate.checkEmail 
    */
    
    
    
    -- It can include other files like below
    & ../hr/additional hr.sql ; 
    & ../fi/additional fi.sql ;
    

    위에서 사용하는 Java 예제 코드. 값을 설정하면 dB로.

    QueryUtil qu = qm.createQueryUtil("selectAll");
    try {
        qu.setConnection(conn);
    
        // with native jdbc
        qu.setString("alpha");
        qu.setDouble(10.1);
        qu.executeQuery();
    
        // or with bean
        qu.executeQuery(new User("alpha", 10.1));
    
        // or with map
        Map<String, Object> map=new HashMap<String, Object>();
        map.put("userName", "alpha");
        map.put("amt", 10.1);
        qu.executeQuery(map);
    
        // or with array
        qu.executeQueryParameters("alpha", 10.1);
    

    위에서 사용하는 Java 예제 코드. DB에서 값을 받고.

        while (qu.next()) // == qu.rs.next()
        {
            // native jdbc
            String usreName = qu.getString("user_name"); 
            double amt = qu.getDouble("amt");
    
            // or bean
            User user = new User();
            qu.updateBean(user);
    
            // or array
            Object[] values = qu.populateArray();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        qu.closeJust();
    }
    
  12. ==============================

    12.당신은 당신이 유연한 방식으로 파일을 작업에 사용할 수있는 "스크립트"SQL 템플릿을 가지고 속도를 사용할 수 있습니다. 당신은 당신의 SQL 명령을 구축 조건문과 루프 같은 원시적 문이있다.

    당신은 당신이 유연한 방식으로 파일을 작업에 사용할 수있는 "스크립트"SQL 템플릿을 가지고 속도를 사용할 수 있습니다. 당신은 당신의 SQL 명령을 구축 조건문과 루프 같은 원시적 문이있다.

    그러나 나는 강력하게 준비된 명령문 및 / 또는 저장 프로 시저를 사용하는 것이 좋습니다. 당신의 SQL이있는 거 계획 SQL 주입에 당신이 취약 할 것입니다 방법을 구축, DB 서버는 (나쁜 성능으로 이어질 것)는 SQL 쿼리를 캐시 할 수 없습니다.

    BTW : 당신은 너무 파일의 준비된 문의 정의를 저장할 수 있습니다. 이것은 아주 가까이 그것에 최선의 해결책이 아닌 그리고 당신은 SQL 주입 보호 및 성능의 혜택을받을.

    당신의 SQL 스키마는 스키마를 재고 할 수 있습니다 준비된 문 또는 저장 프로 시저 작업에 빌드하지 않은 경우. 어쩌면 리팩토링 할 필요가있다.

  13. from https://stackoverflow.com/questions/1544335/java-storing-sql-statements-in-an-external-file by cc-by-sa and MIT license