메모리의 Java 콜렉션에 대한 쿼리 예제

다음 예제에서는 pureQuery에서 메모리의 콜렉션에 대한 쿼리를 구현하는 방법에 대해 설명합니다.

콜렉션에 대한 단순 쿼리 예제

이 예제에서 콜렉션은 java.util.List 오브젝트이며 java.lang.Iterable 인터페이스의 구현입니다. Customer 오브젝트의 구체화된 List를 리턴하는 경우, 연결된 데이터 소스에 다시 액세스하지 않고 해당 데이터에 대해 여러 가지 질문을 할 수 있습니다.

또한, San Francisco Bay Area 영업 지역의 고객 수를 알아보려 한다고 가정하십시오. 코드는 다음과 같을 수 있습니다.

Connection con = DriverManager.getConnection(...);    1 

Data db = DataFactory.getData(con);                   2 

Data qocdata = DataFactory.getData();                 3 

List<Customer> customers = db.queryList(              4 
  "SELECT * from SALES.CUSTOMER", Customer.class);

db.close();                                           5 

int sanFranCode = ...                                 6 

Integer countCity = qocdata.queryFirst(                   7 
"SELECT COUNT(*) FROM ?1.com.company.Customer AS cr WHERE cr.storeRegion = ?2",
Integer.class, customers, sanFranCode );

qocdata.close();                                      8 

위 코드에서 수행하는 단계는 다음과 같습니다.

  1. 데이터베이스에 대한 연결을 작성합니다.
  2. Data 인터페이스의 구현 인스턴스를 작성합니다. Connection 오브젝트가 컨스트럭터에 전달되므로 데이터베이스에 대해 SQL을 실행하기 위해 구현에서 메소드를 사용할 수 있습니다.
  3. Data 인터페이스의 다른 구현을 작성합니다. Connection 오브젝트가 컨스트럭터에 전달되지 않으므로 이 구현에서 콜렉션에 대한 쿼리에 대해서만 메소드를 사용할 수 있습니다.
  4. 모든 고객에 대해 데이터베이스를 쿼리하고 고객 레코드를 고객 List의 Customer 오브젝트로 리턴하십시오.
  5. 데이터베이스에 대한 연결을 닫습니다.
  6. San Francisco Bay Area 영업 지역의 값을 설정합니다.
  7. 목록에서 Customer 오브젝트를 쿼리하고 목표 영업 지역에 있는 고객의 수를 리턴합니다.
  8. qocdata에 사용된 모든 자원을 닫고 해제합니다.

qocdata를 닫는 대신에 고객에 대한 추가 분석을 수행할 수 있습니다(다음 예제에서 설명).

콜렉션에 대한 복합 쿼리 예제

관리 보고서에 San Francisco Bay Area 영업 지역의 독립된 도시 수 및 해당 지역의 가장 큰 5개 도시(서로 다른 주소의 수로 환산)가 필요하다고 가정하십시오. 그런 다음, 제공된 관리의 적극적인 메일링 캠페인이 해당 도시의 고객을 목표로 설정합니다.

연결된 데이터 소스에 대한 하나의 쿼리와 어노테이션이 있는 메소드를 사용하는 얼마간의 애플리케이션 논리를 사용하여 콜렉션에 대한 세 가지 쿼리를 묶을 수 있습니다.

먼저 호출 애플리케이션과 어노테이션이 있는 메소드 둘 모두에 사용되는 스테이징 클래스가 필요합니다.

public class CitySize {
  public String city;
  public Integer size;
}

구현 클래스에서 콜렉션에 대한 쿼리와 데이터베이스에 대한 쿼리 둘 다에 대해 메소드를 사용할 수 없으므로 두 개의 독립된 인터페이스를 작성해야 합니다.

CustomerQuery 인터페이스는 데이터 소스 쿼리를 위한 메소드를 정의합니다. getCustomersInRegion() 메소드는 지정된 영업 지역에 있는 고객을 표시하는 Customer 오브젝트의 목록을 리턴합니다.

import com.company.Customer; 
public interface CustomerQuery
 {
   @Select(sql=
    "SELECT custId, name, ... FROM Customer WHERE region=?1")
   List<Customer> getCustomersInRegion(int r);
 }

RegionReport 인터페이스는 콜렉션 오브젝트 쿼리를 위한 메소드를 정의합니다.

import com.company.Customer;
import com.company.Campaign.CitySize;
public interface RegionReport
{
  @Select(sql="SELECT COUNT(DISTINCT city) FROM ?1")
  public Integer countCities (List<Customer> curRegion);

  @Select(sql=
     "SELECT city, COUNT(DISTINCT addressL1) AS size " +
     " FROM ?1 GROUP BY city ORDER BY size DESC")
  public CitySize[] getCitySize(List<Customer> curRegion);

  @Select(sql="SELECT cr.this FROM ?1 AS cr, ?2 AS t5 " +
            " WHERE cr.city = t5.city ")  
  List<Customer> getMailingList(List<Customer> curRegion,
                       CitySize[] topFive);
}
메소드는 다음과 같은 기능을 수행합니다.
public Integer countCities (List<Customer> curRegion)
현재 지역의 고객 목록에서 고객이 있는 도시의 수를 확인하십시오.
public CitySize[] getCitySize(List<Customer> curRegion)
현재 지역의 고객 목록에서 서로 다른 주소 수를 기반으로 각 도시의 크기를 판별하고 크기의 내림차순으로 정렬된 CitySize 오브젝트의 배열을 리턴하십시오.
List<Customer> getMailingList(List<Customer> curRegion, CitySize[] topFive)
현재 지역의 고객 목록에서 주어진 도시 목록에 해당 도시가 있는 고객을 모두 선택하십시오. "this"의 사용은 List<Customer> curRegion에서 이러한 경우에 쿼리된 실제 오브젝트가 getMailingList에 의해 리턴되는 List<Customer>에 선택되도록 합니다. "cr.*"를 선택하는 유사한 쿼리는 일반적으로 쿼리된 오브젝트의 사본이 리턴되는 결과를 가져옵니다.

인터페이스에 대한 구현 클래스를 생성한 후, 다음과 같은 애플리케이션 논리를 사용하여 관리 보고서 및 목표로 지정된 고객의 목록을 작성할 수 있습니다.

 Connection con = DriverManager.getConnection(...);                    1 
 CustomerQuery cQuery = 
    DataFactory.getData( CustomerQuery.class, con );                   2 

 RegionReport inMem =
    DataFactory.getData( RegionReport.class );                         3 

 int sanFranCode = ...;                                                4 

 List<Customer> customers = cQuery.getCustomersInRegion(sanFranCode);  5 

cQuery.close();                                                        6 

 Integer cityCount = inMem.countCities(customers);                         7 
 System.out.println (                                                  8 
   " There are " + cityCount + " cities in region " + sanFranCode );
 System.out.println (
   " The largest 5, and their number of addresses are: " );

 CitySize[] allCityList = inMem.getCitySize(customers);                9 
 CitySize[] topFive = new CitySize[5];                                 10 
 for (int i=0; i<5; i++)                                               11 
 {  topFive[i] = allCityList[i];
    System.out.println (
      "   " + topFive[i].city + "  " + topFive[i].size);
 }

 List<Customer> mailingCust =                                          12 
         inMem.getMailingList(customers, topFive);

inMem.close();                                                         13 

위 코드에서 수행하는 단계는 다음과 같습니다.

  1. 데이터베이스에 대한 연결을 작성합니다.
  2. CustomerQuery 인터페이스의 구현 인스턴스를 작성합니다. Connection 오브젝트가 컨스트럭터에 전달되므로 데이터베이스에 대해 SQL을 실행하기 위해 구현에서 메소드를 사용할 수 있습니다.
  3. RegionReport 인터페이스의 구현 인스턴스를 작성합니다. Connection 오브젝트가 컨스트럭터에 전달되지 않으므로 이 구현에서 콜렉션에 대한 쿼리에 대해서만 메소드를 사용할 수 있습니다.
  4. San Francisco Bay Area 영업 지역의 값을 설정합니다.
  5. 목표 영업 지역에 있는 고객을 표시하는 Customer 오브젝트로 고객 목록을 채웁니다.
  6. cQuery에 사용된 모든 자원을 닫고 해제합니다.
  7. 고객이 있는 서로 다른 도시의 수를 가져옵니다.
  8. 보고서의 첫 번째 파트를 인쇄합니다.
  9. CitySikze 오브젝트(고객이 있는 각 도시에 대해 하나의 오브젝트)의 배열을 가져옵니다.
  10. 가장 큰 5개 도시에 대한 CitySize 오브젝트를 보유할 CitySize 유형의 배열을 작성합니다.
  11. 가장 큰 5개 도시의 이름 및 크기를 인쇄합니다.
  12. 가장 큰 5개 도시에 있는 고객의 목록을 가져옵니다.
  13. inMem에 사용된 모든 자원을 닫고 해제합니다.

관리가 목표 메일링이 너무 작거나 너무 크다고 판별하는 경우, CitySize 배열에 할당된 크기 및 배열을 채우는 루프를 약간만 변경해도 결과적으로 얻은 mailingCust 목록에서 Customer 오브젝트를 추가하거나 제거하는 데 충분하다는 점을 지적할 만한 가치가 있습니다. getMailingList() 메소드는 입력 배열의 크기와 무관합니다.


피드백