Java에서 SQL 문자열을 작성하는 가장 깨끗한 방법 방법 대신-거기 더

데이터베이스 조작 (업데이트, 삭제, 삽입, 선택 등)을 수행하기 위해 SQL 문자열을 만들고 싶습니다-기껏해야 읽을 수없는 수백만 개의 “+”와 따옴표를 사용하는 끔찍한 문자열 연결 방법 대신-거기 더 나은 방법이어야합니다.

MessageFormat 사용을 생각했지만 합리적인 작업을 할 것이라고 생각하지만 사용자 메시지에 사용되어야하지만 Java SQL 라이브러리의 SQL 유형 작업에 더 잘 맞는 것이 있어야한다고 생각합니다.

Groovy가 좋을까요?



답변

먼저 준비된 명령문에서 쿼리 매개 변수 사용을 고려하십시오.

PreparedStatement stm = c.prepareStatement("UPDATE user_table SET name=? WHERE id=?");
stm.setString(1, "the name");
stm.setInt(2, 345);
stm.executeUpdate();

수행 할 수있는 다른 작업은 모든 쿼리를 속성 파일에 보관하는 것입니다. 예를 들어 query.properties 파일에서 위의 쿼리를 배치 할 수 있습니다.

update_query=UPDATE user_table SET name=? WHERE id=?

그런 다음 간단한 유틸리티 클래스의 도움으로 :

public class Queries {

    private static final String propFileName = "queries.properties";
    private static Properties props;

    public static Properties getQueries() throws SQLException {
        InputStream is =
            Queries.class.getResourceAsStream("/" + propFileName);
        if (is == null){
            throw new SQLException("Unable to load property file: " + propFileName);
        }
        //singleton
        if(props == null){
            props = new Properties();
            try {
                props.load(is);
            } catch (IOException e) {
                throw new SQLException("Unable to load property file: " + propFileName + "\n" + e.getMessage());
            }
        }
        return props;
    }

    public static String getQuery(String query) throws SQLException{
        return getQueries().getProperty(query);
    }

}

다음과 같이 쿼리를 사용할 수 있습니다.

PreparedStatement stm = c.prepareStatement(Queries.getQuery("update_query"));

이것은 다소 간단한 해결책이지만 잘 작동합니다.


답변

임의의 SQL의 경우 jOOQ를 사용 하십시오 . jOOQ 현재 지원 SELECT, INSERT, UPDATE, DELETE, TRUNCATE,와 MERGE. 다음과 같이 SQL을 생성 할 수 있습니다.

String sql1 = DSL.using(SQLDialect.MYSQL)
                 .select(A, B, C)
                 .from(MY_TABLE)
                 .where(A.equal(5))
                 .and(B.greaterThan(8))
                 .getSQL();

String sql2 = DSL.using(SQLDialect.MYSQL)
                 .insertInto(MY_TABLE)
                 .values(A, 1)
                 .values(B, 2)
                 .getSQL();

String sql3 = DSL.using(SQLDialect.MYSQL)
                 .update(MY_TABLE)
                 .set(A, 1)
                 .set(B, 2)
                 .where(C.greaterThan(5))
                 .getSQL();

SQL 문자열을 얻는 대신 jOOQ를 사용하여 실행할 수도 있습니다. 보다

http://www.jooq.org

(면책 조항 : 나는 jOOQ 뒤에있는 회사에서 일합니다)


답변

고려해야 할 한 가지 기술은 SQLJ 입니다. 즉, Java에 SQL 문을 직접 포함하는 방법입니다. 간단한 예로 TestQueries.sqlj라는 파일에 다음이있을 수 있습니다.

public class TestQueries
{
    public String getUsername(int id)
    {
        String username;
        #sql
        {
            select username into :username
            from users
            where pkey = :id
        };
        return username;
    }
}

.sqlj 파일을 가져와 순수 Java로 변환하는 추가 사전 컴파일 단계가 있습니다. 즉, 다음으로 구분 된 특수 블록을 찾습니다.

#sql
{
    ...
}

JDBC 호출로 변환합니다. SQLJ를 사용하면 몇 가지 주요 이점이 있습니다.

  • JDBC 계층을 완전히 추상화합니다. 프로그래머는 Java와 SQL 만 생각하면됩니다.
  • 번역기는 컴파일 타임에 데이터베이스에 대한 구문 등의 쿼리를 확인하도록 만들 수 있습니다.
  • “:”접두사를 사용하여 쿼리에서 Java 변수를 직접 바인딩하는 기능

대부분의 주요 데이터베이스 공급 업체를위한 변환기 구현이 있으므로 필요한 모든 것을 쉽게 찾을 수 있습니다.


답변

나는 당신이 Squiggle 과 같은 것을 추구 하고 있는지 궁금합니다 . 또한 매우 유용한 것은 jDBI 입니다. 그래도 쿼리에는 도움이되지 않습니다.


답변

나는 Spring JDBC를 살펴볼 것이다 . 프로그래밍 방식으로 SQL을 실행해야 할 때마다 사용합니다. 예:

int countOfActorsNamedJoe
    = jdbcTemplate.queryForInt("select count(0) from t_actors where first_name = ?", new Object[]{"Joe"});

모든 종류의 SQL 실행, 특히 쿼리에 정말 좋습니다. 전체 ORM의 복잡성을 추가하지 않고도 결과 집합을 개체에 매핑하는 데 도움이됩니다.


답변

저는 Spring의 명명 된 JDBC 매개 변수를 사용하는 경향이 있으므로 “select * from blah where colX = ‘: someValue'”와 같은 표준 문자열을 작성할 수 있습니다. 꽤 읽기 쉬운 것 같아요.

대안은 별도의 .sql 파일에 문자열을 제공하고 유틸리티 메서드를 사용하여 내용을 읽는 것입니다.

오, Squill도 살펴볼 가치가 있습니다 : https://squill.dev.java.net/docs/tutorial.html


답변

Hibernate와 같은 ORM 사용에 대한 권장 사항을 두 번째로 설명합니다. 그러나 확실히 작동하지 않는 상황이 있기 때문에이 기회를 통해 내가 작성하는 데 도움이 된 몇 가지 내용을 소개 하겠습니다 . SqlBuilder 는 “빌더”스타일을 사용하여 SQL 문을 동적으로 빌드하기위한 자바 라이브러리입니다. 상당히 강력하고 유연합니다.