복붙노트

[HADOOP] jooq는 기존의 방언을 확장합니다. Hive 방언을 아파치하기 위해 MySQL 방언 채택

HADOOP

jooq는 기존의 방언을 확장합니다. Hive 방언을 아파치하기 위해 MySQL 방언 채택

Hive를 쿼리하기 위해 JOOQ를 사용하려고합니다. Hive SQL 언어는 MySQL 언어와 매우 비슷합니다. 지금 나는이 문제들을 만났다 :

JOOQ에서 이러한 문제를 해결하는 모범 사례는 무엇입니까?

해결법

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

    1.불행히도 새로운 SQL 언어를 철저히 지원하기 위해 jOOQ를 확장하는 것은 그리 간단하지 않습니다. jOOQ의 API는 시간이 지남에 따라 확장되어 표준 및 공급 업체별 SQL 구문 변형을 지원합니다. Apache Hive 언어는 MySQL과 비슷하게 보일 수 있지만 jOOQ 내부에서 구현해야 할 미묘한 차이점이 많이있을 것입니다. LIMIT .. OFFSET 절의 다른 구현은 단지 하나의 문제입니다. 즉, 일반적으로 "알 수없는"또는 "지원되지 않는"방언으로 jOOQ를 사용하는 것은 좋지 않습니다.

    불행히도 새로운 SQL 언어를 철저히 지원하기 위해 jOOQ를 확장하는 것은 그리 간단하지 않습니다. jOOQ의 API는 시간이 지남에 따라 확장되어 표준 및 공급 업체별 SQL 구문 변형을 지원합니다. Apache Hive 언어는 MySQL과 비슷하게 보일 수 있지만 jOOQ 내부에서 구현해야 할 미묘한 차이점이 많이있을 것입니다. LIMIT .. OFFSET 절의 다른 구현은 단지 하나의 문제입니다. 즉, 일반적으로 "알 수없는"또는 "지원되지 않는"방언으로 jOOQ를 사용하는 것은 좋지 않습니다.

    단기적으로는 jOOQ 렌더 SQL을 패치해야 할 것입니다. 이를위한 가장 좋은 기술은 여기에 설명 된대로 실행 리스너를 사용하는 것입니다.

    "renderEnd ()"이벤트를 받으면 렌더링 된 SQL에 액세스하여 정규식 또는 원하는 기술을 사용하여 수정할 수 있습니다.

    장기적으로 # 2337이 구현되면 더 나은 솔루션이있을 수 있습니다 (그러나 아마도 구현하지 않을 것입니다)

  2. ==============================

    2.가장 더러운 해결책은 다음과 같습니다.) JOOQ 사용자 그룹이 불행히도 대답하지 않았습니다 :(

    가장 더러운 해결책은 다음과 같습니다.) JOOQ 사용자 그룹이 불행히도 대답하지 않았습니다 :(

    public class CountRatingQueryBuilder {
    
        private static final String SCORING_TABLE_NAME = "web_resource_rating";
    
        private final Connection connection;
        private final ScoringMetadata scoringMetadata;
    
        private final SelectSelectStep select;
        private final Factory create;
    
        public CountRatingQueryBuilder(Connection connection, ScoringMetadata scoringMetadata){
            this.connection = connection;
            this.scoringMetadata = scoringMetadata;
    
            create = new Factory(this.connection, SQLDialect.MYSQL);
            select = create.select();
    
            withSelectFieldsClause();
        }
    
        public CountRatingQueryBuilder withLimit(int limit){
            select.limit(limit);
            return this;
        }
    
        public CountRatingQueryBuilder withRegionId(Integer regionId){
            select.where(REGION_ID.field().equal(regionId));
            return this;
        }
    
        public CountRatingQueryBuilder withResourceTypeId(int resourceTypeId){
            select.where(RESOURCE_TYPE_ID.field().equal(resourceTypeId));
            return this;
        }
    
        public CountRatingQueryBuilder withRequestTimeBetween(long beginTimestamp, long endTimestamp){
            select.where(REQUEST_TIME.field().between(beginTimestamp, endTimestamp));
            return this;
        }
    
        public CountRatingQueryBuilder withResourceId(int resourceId){
            select.where(RESOURCE_ID.field().equal(resourceId));
            return this;
        }
    
    
    
        protected void withGroupByClause(){
            select.groupBy(REGION_ID.field());
            select.groupBy(RESOURCE_TYPE_ID.field());
            select.groupBy(RESOURCE_ID.field());
            select.groupBy(CONTENT_ID.field());
        }
    
        protected void withSelectFieldsClause(){
            select.select(REGION_ID.field());
            select.select(RESOURCE_TYPE_ID.field());
            select.select(CONTENT_ID.field());
            select.select(RESOURCE_ID.field());
            select.select(Factory.count(HIT_COUNT.field()).as(SUM_HIT_COUNT.fieldName()));
        }
    
        protected void withFromClause(){
            select.from(SCORING_TABLE_NAME);
        }
    
        protected void withOrderByClause(){
            select.orderBy(SUM_HIT_COUNT.field().desc());
        }
    
        public String build(){
            withGroupByClause();
            withOrderByClause();
            withFromClause();
            return select.getSQL().replace("offset ?","");//dirty hack for MySQL dialect. TODO: we can try to implement our own SQL dialect for Hive :)
    
        }
    
        public List<ResultRow> buildAndFetch(){
            String sqlWithPlaceholders = build();
    
            List<ResultRow> scoringResults = new ArrayList<ResultRow>(100);
            List<Record> recordResults = create.fetch(sqlWithPlaceholders, ArrayUtils.subarray(select.getBindValues().toArray(new Object[select.getBindValues().size()]),0, select.getBindValues().size()-1));//select.fetch();
            for(Record record : recordResults){
                ResultRowBuilder resultRowBuilder = ResultRowBuilder.create();
    
                resultRowBuilder.withContentType(scoringMetadata.getResourceType(record.getValue(RESOURCE_TYPE_ID.fieldName(), Integer.class)));
                resultRowBuilder.withHitCount(record.getValue(SUM_HIT_COUNT.fieldName(), Long.class));
                resultRowBuilder.withUrl(record.getValue(CONTENT_ID.fieldName(), String.class));
                scoringResults.add(resultRowBuilder.build());
            }
            return scoringResults;
        }
    
    }
    
  3. from https://stackoverflow.com/questions/15381401/jooq-extend-existing-dialect-adopt-mysql-dialect-to-apache-hive-dialect by cc-by-sa and MIT license