2014-01-06 2 views
3

을 PostgreSQL에 전달하고 올바른 순서로 데이터가 다시 들어오는 지 확인하는 통합 테스트를 작성하고 있습니다. 나는이 통합 테스트를 Java로 작성하고 있으며 String.compareTo 메소드는 PostgreSQL과 다르게 정렬하는 것으로 보입니다.PostgreSQL과 같은 방법으로 String을 정렬하는 Comparator를 어떻게 만들 수 있습니까?

import com.google.common.collect.Lists; 
import com.google.common.collect.Ordering; 
import org.junit.Test; 

import java.util.List; 

import static junit.framework.Assert.assertEquals; 

public class PostgresqlSortOrderTest { 

    @Test 
    public void whenJavaSortsStringsThenItIsTheSameAsWhenPostgresqlSortsStrings() { 
     List<String> postgresqlOrder = Lists.newArrayList("a", "A", "b", "c", "d", "D"); 
     Ordering<String> ordering = new Ordering<String>() { 
      @Override 
      public int compare(String left, String right) { 

       return left.compareTo(right); 
      } 
     }; 
     List<String> javaOrdering = ordering.sortedCopy(postgresqlOrder); 
     assertEquals(postgresqlOrder, javaOrdering); 
    } 

} 

:

a 
A 
b 
c 
d 
D 

은 그때 자바 물건을 정렬하는 방식이 비교하기 위해 단위 테스트를 작성 :

SELECT regexp_split_to_table('D d a A c b', ' ') ORDER BY 1; 

그것은이로 응답 : 내 PostgreSQL 데이터베이스에서이 작업을 실행 이 출력으로 실패했습니다 :

Expected :[a, A, b, c, d, D] //postgresql 
Actual :[A, D, a, b, c, d] //java 

나는이 용어에 대해 아주 무지하다. 나는 서로 다른 String 종류의 이름을 알고 싶습니다. 그래서 나는 더 잘 의사 소통을 할 수 있습니다. 하지만 더 중요한 것은 PostgreSQL처럼 Java 정렬을 어떻게 만들 수 있습니까?

+2

Java는 ASCII 순서로 수행합니다. PG는 알파벳순으로 같은 문자를 대문자와 소문자로 순서대로 정렬 한 것 같습니다 (낮은

+0

@DaveNewton 사실, 이미 비교기를 가지고있는 라이브러리가 있다면, 직접 쓰는 것보다는 사용하는 것이 좋습니다. 너는 그걸 알고 있니? –

+1

표준 API의 String.CASE_INSENSITIVE_ORDER입니다. –

답변

5

늦은는 답을 보여,하지만 난 간단한 대소 문자 구분 검색은 반드시 당신이 원하는 일을하지 않을 두려워.

귀하가 검색하고자하는 키워드가 collation (더 넓은 의미에서 locales)이고 PostgreSQL은이를 지원하기 위해 기본 운영 체제를 사용합니다. 순서는 문자별로 간단한 비교가 거의 없습니다. 예를 들어 많은 로케일에서 공백은 무시됩니다 (en_GB의 경우는 확실합니다).

또한 다른 플랫폼에서 다른 정렬 순서로 종료 될 수 있음을 의미합니다 (Apple 또는 Microsoft가 해당 국가의 기본 주문에 대해 Linus와 동의하는지 여부에 따라 다름).

플랫폼간에 일관된 정렬 순서를 제공하기 위해 BSD 라이센스 라이브러리를 포함하는 것이 타당한 지에 대한 논의가있었습니다. 그러나 이것은 많은 작업이며 나머지 운영 체제에서 데이터베이스 내부의 다른 정렬로 끝날 수 있음을 의미합니다. 다른 공급자가이를 처리하는 방법에 대해서는 동의하지 않지만 두려운 것이 하나도 없습니다.

"전통적"정렬의 "C"데이터 정렬을 조사 할 수 있습니다. Java가 적절한 로케일 정렬을 처리하는 것에 대해서는 언급 할 수 없습니다.

+1

+1'을 쓰면, [A, D, a, b, c, d] FYI Java가 정확히 같은 방식으로 처리하기 때문에. 로켈 기반이며 사용할 수있는 [Collator] (http://docs.oracle.com/javase/7/docs/api/java/text/Collator.html) 클래스가 있습니다. –

+0

@BrianRoach 나는 그것을 필요로한다고 생각한다. 내 통합 테스트는'String.CASE_INSENSITIVE_ORDER'로 로컬로 전달되었지만 일단 다른 OS와 로케일의 CI에서 실행되면 실패했습니다. 하지만 기본 로케일에 대소 문자를 구분하지 않는 콜 레이터를 얻는 방법을 알 수는 없습니다. 어떻게하는지 아십니까? –

+1

@tieTYT - 여기에 문제가 있습니다. 플랫폼 전반에 걸쳐 로케일 기반의 두 가지 시스템 동작에 의존하려고합니다. 일치하는 부분을 명시 적으로 관리하거나 한쪽 끝을 선택하여 작업을 수행 할 필요가 있습니다. 그것은 나 였고 쿼리 (난 그게 문제라고 생각 해요) 후에 데이터베이스 외부에 삽입 정렬을 할 필요가 있다면 나는 자바 쪽 정렬 만 할 것입니다. Java 데이터 정렬을 사용하는 방법에 대한 자습서가 있습니다. http://docs.oracle.com/javase/tutorial/i18n/text/collationintro.html 다른 옵션을 사용하면 문제에 대한 접근 방식을 다시 생각할 수 있습니다. –

3

을 사용하여 CollectionStrings으로 정렬하십시오. 그것은 이미 String 클래스에 암시되어 있습니다. 에서 필드의 개요에서

봐 : http://docs.oracle.com/javase/6/docs/api/java/lang/String.html

+2

주목할만한 점은 postgres의'ORDER BY'는 Java와 마찬가지로 로케일에 의존한다는 것입니다. Postgres 9.예를 들어, 만약 당신이''regexp_split_to_table ('D da A c b', '') ORDER BY 1; ' –

관련 문제