빅쿼리(Big Query) 연동하는 방법을 소개하겠습니다.
Spring-boot의 Maven을 사용하였고,
인증방법은 Credentials로 사용자 인증 정보가 담긴 json파일로 하였습니다.
pom.xml에 다음과 같이 추가합니다.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>26.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-bigquery</artifactId>
</dependency>
</dependencies>
프로젝트 resources 내에 사용자 인증 정보의 json파일을 업로드합니다.
resources/keys/credentials.json
BigQuery를 생성합니다.
package com.study.common.api.google.biquery;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.bigquery.*;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.ArrayList;
import java.util.HashMap;
/**
* 구글 빅쿼리
*/
public class ApiBigQueryAuthentication {
/**
* 구글 credentials.json을 통한 Biquery 생성
* @return {BigQuery}
*/
public static BigQuery getBigQuery() {
try {
// credentials.json 파일을 읽는다.
File credentialsFile = ResourceUtils.getFile("classpath:keys/credentials.json");
GoogleCredentials credentials;
try (FileInputStream fileInputStream = new FileInputStream(credentialsFile)) {
credentials = ServiceAccountCredentials.fromStream(fileInputStream);
}
// BigQuery 생성
BigQuery bigQuery = BigQueryOptions.newBuilder()
.setCredentials(credentials)
// credentials.json에 있는 project_id
.setProjectId("project_id")
.build()
.getService()
;
return bigQuery;
} catch (Exception e) {
return null;
}
}
}
TableResult를 반환하는 메서드를 생성합니다.
/**
* BigQuery 수행 및 결과
* @param {String} query
* @throws {Exception}
* @return {TableResult}
*/
public static TableResult bigQueryExecute(String query) throws Exception {
BigQuery bigQuery = getBigQuery();
QueryJobConfiguration queryJobConfiguration =
// Query
QueryJobConfiguration.newBuilder(query)
// 표준 SQL 사용
// See: https://cloud.google.com/bigquery/sql-reference/
setUseLegacySql(false)
.build();
// 보안문제로 JobId 생성
JobId jobId = JobId.of(UUID.randomUUID().toString());
Job job = bigQuery.create(JobInfo.newBuilder(queryJobConfiguration).setJobId(jobId).build());
// 쿼리가 완성될 동안 대기
job = job.waitFor();
// 예외처리
if (job == null) {
throw new RuntimeException("쿼리가 존재하지 않습니다.");
} else {
if (job.getStatus().getError() != null) {
String errorMessage =
job.getStatus().getError().getMessage() + "\n"
+ job.getStatus().getError().getReason() + "\n"
+ job.getStatus().getError().toString()
;
throw new RuntimeException(errorMessage);
} else {
TableResult tableResult = job.getQueryResults();
return tableResult;
}
}
}
bigQueryExecute를 이용하여 TableResult를 받은 후 List<Map<String, Object>>에 넣어보겠습니다.
/**
* 빅쿼리 조회
* @return {List<Map<String, Object>>}
* @throws {Exception}
*/
public List<Map<String, Object>> selectBigQuery() throws Exception {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("SELECT 'green' AS color ");
stringBuffer.append(" , '초록' AS colorNm ");
stringBuffer.append(" FROM DUAL ");
stringBuffer.append(" UNION ALL ");
stringBuffer.append("SELECT 'pink' AS color ");
stringBuffer.append(" , '분홍' AS colorNm ");
stringBuffer.append(" FROM DUAL ");
TableResult tableResult = bigQueryExecute(stringBuffer.toString());
// TableResult를 담을 List 생성
List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
// List에 add할 map 선언
Map<String, Object> map;
int idx = 1;
// tableResult for start
for (FieldValueList fieldValueList:tableResult.iterateAll()) {
// map 초기화
map = new HashMap<String, Object>();
// idx 초기화
idx = 1;
// FieldValueList for start
for (FieldValue fieldValue:FieldValueList) {
// Column의 Alias명은 알 수 없음.
// 내가 선언한 쿼리의 순서를 인지하고 Map의 key를 알맞게 넣어줘야 함.
if (idx == 1) map.put("color", fieldValue.getStringValue());
if (idx == 2) map.put("colorNm", fieldValue.getStringValue());
idx++;
} // FieldValueList for end
// list add
dataList.add(map);
} // tableResult for end
return dataList;
}