본문 바로가기
IT 지식/빅데이터 & 분석

JAVA-HIVE/HBASE 간 통신_Hive 통신

by 이민우 2023. 1. 22.
728x90
반응형

Hive는 HDFS에 데이터를 저장하고 이를 RDB처럼 보여주는 Hadoop의 데이터베이스이다.

 

Hive는 Java의 HIVE-JDBC 드라이버와 HIVESERVER2 간의 연동을 통해 쉽게 접근할 수 있다. 구글링 결과 JPA를 적용할 수 도 있을 것으로 보이는데, 이번 프로젝트에서는 DML뿐 아니라 DDL도 사용해야 했기에 JPA를 사용하지 않았다. 그래서 JPA 대신 MyBatis를 적용했고, 현 포스팅에서도 Mybatis를 사용한 Hive 접근을 다룰 예정이다.

 


 

1. 프로젝트 생성

 

우선 프로젝트를 다음과 같이 생성했다.

  • Maven
  • Java : 1.8
  • Spring Boot : 2.7.7
  • Dependency : Lombok, MyBatis Framework

다음으로 Hive에 접근하기 위한 Dependency를 pom.xml 수동으로 추가해준다.

이 때 아래 hive-jdbc는 설치한 hive의 버전과 일치해야 함을 명심한다.

<dependency>
           <groupId>org.apache.commons</groupId>
           <artifactId>commons-dbcp2</artifactId>
           <version>2.9.0</version>
</dependency>
<dependency>
           <groupId>org.apache.hive</groupId>
           <artifactId>hive-jdbc</artifactId>
           <version>3.1.2</version>
</dependency>

 


*왠지 모르겠지만 jdk-tools를 찾을 수 없어 다음 dependency도 추가했다.

<dependency>
        <groupId>jdk.tools</groupId>
        <artifactId>jdk.tools</artifactId>
        <scope>system</scope>
        <version>1.6</version>
        <systemPath>C:\Users\...\lib\tools.jar</systemPath>
</dependency>

* systemPath 경로는 $JAVA_HOME 경로이다.

* 만약 위 방식이 싫으면 hive-jdbc dependency를 삭제하고 Add External Jar로 hive-jdbc jar 등 hadoop 관련 jar 파일들을 물리적으로 넣어주면 되는데... 너무 귀찮다.

 

만약 jdk.tools의 경로 설정이 되지 않으면 hive-jdbc를 삽입하는 데 jdk.tools를 사용하지 않도록 설정할 수 있다. 다만 이 경우 test가 불가능했다.

<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-jdbc</artifactId>    
    <version>3.1.2</version>    
    <exclusions>
        <exclusion>
            <groupId>jdk.tools</groupId>
            <artifactId>jdk.tools</artifactId>
        </exclusion>
    </exclusions>
</dependency>

 

dependency 추가 후 maven update를 진행한다.

 

다음으로 application.yml에 다음 내용을 추가한다.

hive:
  driver:
    classname: org.apache.hive.jdbc.HiveDriver
  connection:
    url: jdbc:hive2://192.168.0.10:10000/default?socketTimeout=1000000&connectTimeout=1000000
    username: hadoop
    password: hadoop

 

이제 프로젝트를 구성한다.

프로젝트는 아래의 사진과 같이 구성했다.

  • HiveConfig : Hive에 연동되는 sqlSession 빈 생성 파일
  • Commons : 공통코드 파일
  • HiveDao : hive dao
  • HiveService : service 파일
  • hive.xml : 쿼리가 입력된 mybatis xml 파일

 

각 클래스 파일은 아래와 같이 작성했으며, 세세한 설명은 코드 안에 기재했다.

 

Commons.java

package com.example.demo;

/*
 * 공통코드
 */
public class Commons {
	// 테이블명
	public static final String TABLE_NAME = "tableName";
	// CREATE 시 컬럼 정보
	public static final String COLUMNS_INFO = "columnsInfo";
	// UPDATE 시 컬럼 정보
	public static final String ADD_COLUMNS_INFO = "addColumnsInfo";
	// MODIFY 시 컬럼 정보
	public static final String MODIFY_COLUMNS_INFO = "modifyColumnsInfo";
	// DROP 할 컬럼명 (리스트)
	public static final String DROP_COLUMNS_INFO = "dropColumnsInfo";
	// INSERT 할 데이터 정보 구성
	public static final String DATA_INFO = "dataInfo";
	// UPDATE 할 데이터 정보 구성 (HIVE 전용)
	public static final String UPDATE_DATA_INFO = "dataInfo";
	// WHERE 정보
	public static final String WHERE = "where";
	// HBASE PK 정보
	public static final String HBASE_PK = "hbasePk";

	// Query 입력용
	public static final String SPACE = " ";
	public static final String LINE = "\n";
}

 

 

HiveConfig.java

package com.example.demo.config;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.AutoMappingBehavior;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/*
 * 코드 변경을 최대한 줄이기 위해 타회사에서 제작한 것과 최대한 똑같이 제작함.
 * Hive에 연동하기 위한 SqlProvider를 만들기 위한 설정 클래스.
 */
@Configuration
@EnableTransactionManagement
public class HiveConfig {
	
	@Value("${hive.driver.classname}")
	private String hiveDriverClassName ;
	@Value("${hive.connection.url}")
	private String hiveJdbcUrl;
	@Value("${hive.connection.username}")
	private String hiveJdbcUsername;
	@Value("${hive.connection.password}")
	private String hiveJdbcPassword;
	

	@Bean
	@Qualifier("hiveDataSource")
	public DataSource hiveDataSource() {
		
		BasicDataSource dataSource = new BasicDataSource();
		
		dataSource.setDriverClassName(hiveDriverClassName);
		dataSource.setUrl(hiveJdbcUrl);
		dataSource.setUsername(hiveJdbcUsername);
		dataSource.setPassword(hiveJdbcPassword);
		dataSource.setMinIdle(10);

		return dataSource;
	}
	
	@Bean
	@Qualifier("hiveDataSourceTransactionManager")
	public DataSourceTransactionManager hiveDataSourceTransactionManager(@Qualifier("hiveDataSource") DataSource hiveDataSource) {
		return new DataSourceTransactionManager(hiveDataSource);
	}

	@Bean
	@Qualifier("hiveSqlSessionFactory")
	public SqlSessionFactory hiveSqlSessionFactory(@Qualifier("hiveDataSource") DataSource hiveDataSource) throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(hiveDataSource);
		bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/hive.xml"));
		// *Configuration annotation과 겹쳐서 이렇게 작성
		org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
		
		configuration.setCacheEnabled(true);
		configuration.setUseGeneratedKeys(false);
		configuration.setDefaultExecutorType(ExecutorType.SIMPLE);
		configuration.setLazyLoadingEnabled(false);
		configuration.setAggressiveLazyLoading(true);
		configuration.setUseColumnLabel(true);
		configuration.setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
		configuration.setMultipleResultSetsEnabled(true);
		configuration.setSafeRowBoundsEnabled(true);
		configuration.setMapUnderscoreToCamelCase(false);
		
		bean.setConfiguration(configuration);
		
		return bean.getObject();
	}

	@Bean
	@Qualifier("hiveSqlSession")
	public SqlSessionTemplate hiveSqlSession(@Qualifier("hiveSqlSessionFactory") SqlSessionFactory hiveSqlSessionFactory) {
		return new SqlSessionTemplate(hiveSqlSessionFactory);
	}

}

 

hive.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="mapper.hive">
	
	<update id="createTable" parameterType="map">
		<!-- CREATE TABLE -->
		<!--  ${}는 문자 그대로 나가고, #{}는 '' 등에 둘러쌓여서 나감 -->
		<!-- update/delete 수행을 위해 TRANSACTIONAL 설정이 필요하고, 이를 위해 ORC 형식으로 저장. -->
		CREATE TABLE IF NOT EXISTS ${tableName}
			<foreach 
				collection="columnsInfo.entrySet()"
				index="column" 
				item="info"  
				separator=" , "
				open="( " 
				close=" )"
			>
				${column} ${info}
			</foreach>
		STORED AS ORC 
		TBLPROPERTIES('transactional'='true')
	</update>
	<update id="saveExternal" parameterType="map">
		ALTER TABLE ${tableName} SET TBLPROPERTIES('EXTERNAL'='TRUE')
	</update>
	
	<select id="selectColumnList" parameterType="String" resultType="map">
		<!-- SELECT COLUMN LIST -->
		DESCRIBE ${tableName}
	</select>
	
	<update id="updateTableAddColumns" parameterType="map">
		<!--  UPDATE TABLE -->
		ALTER TABLE ${tableName} 
		<!-- Column 추가 -->
		ADD COLUMNS
		<foreach
			collection="addColumnsInfo.entrySet()"
			index="column" 
			item="info" 
			separator=" , "
			open="( " 
			close=" )"
		>
			${column} ${info}
		</foreach>
		
	</update>
	
	<update id="updateTableModifyColumns" parameterType="map">
		ALTER TABLE ${tableName}
		<!-- Column 수정 -->
		<foreach
			collection="modifyColumnsInfo.entrySet()"
			index="column" 
			item="info" 
			separator=" , "
		>
			CHANGE ${column} ${column} ${info}
		</foreach>
	</update>
	
	<update id="updateTableReplaceColumns" parameterType="map">
		ALTER TABLE ${tableName} REPLACE COLUMNS
		<!-- Column 삭제 -->		
		<foreach
			collection="dropColumnsInfo"
			index="index" 
			item="column" 
			separator=" , "
				open="( " 
				close=" )"
		> ${column}
		</foreach>
	</update>
	
	<update id="dropTable" parameterType="String">
		<!-- DROP TABLE -->
		DROP TABLE IF EXISTS ${tableName}
	</update>
	
	<insert id="insertData" parameterType="map">
		<!-- INSERT DATA -->
		INSERT INTO ${tableName} 
		VALUES 
		<foreach
			collection="dataInfo"
			index="index" 
			item="list" 
			separator=", "
		>
			<foreach
				collection="list"
				index="index"
				item="data"
				separator=","
				open="( " 
				close=" )"
			>
				#{data}
			</foreach>
		</foreach>
	</insert>

	<update id="updateData" parameterType="map">
		<!-- UPDATE DATA -->
		UPDATE ${tableName} 
		SET 
		<foreach 
			collection="dataInfo"
			index="column" 
			item="data" 
			separator=", "
		>
			${column}=#{data}
		</foreach>
		<if test="where != null">
			WHERE
			<foreach
				collection="where"
				index="column" 
				item="data" 
				separator=" AND "
			>
				${column}${data}
			</foreach>
		</if>
	</update>

	<delete id="deleteData" parameterType="map">
		<!-- DELETE DATA -->
		DELETE FROM ${tableName} 
		<if test="where != null">
			WHERE
			<foreach
				collection="where"
				index="column" 
				item="data" 
				separator=" AND "
			>
				${column}${data}
			</foreach>
		</if>
		
	</delete>

	<select id="selectAll" parameterType="map" resultType="map">
		<!-- SELECT SEVERAL DATA -->
		SELECT * 
		FROM ${tableName}
		<if test="where != null">
			WHERE 
			<foreach
				collection="where"
				index="column" 
				item="data" 
				separator=" AND "
			>
				${column}${data}
			</foreach>
		</if>
	</select>

</mapper>

 

HiveDao.java

package com.example.demo.hive.dao;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.example.demo.Commons;

@Repository
public class HiveDao {
	
	@Autowired
	@Qualifier("hiveSqlSession")
	private SqlSessionTemplate sqlSession;
	
	// DDL
	/**
	 * 테이블 생성
	 * 
	 * @param queryConditions
	 * 	-tableName (String) : 테이블명
	 * 	-columnInfo (Map<String, String>) : 테이블 내 컬럼 정보
	 * 		- key : 컬럼의 이름 (ex: col01)
	 * 		- value : 컬럼의 선언 (ex: VARCHAR(50))
	 * 
	 * 
	 * \@Transactional 사용 시 Request to set autoCommit to false; Hive does not support autoCommit=false. 오류 발생 (클래스 내 모든 함수 공통)
	 * src/main/resources/mapper/hive.xml에 쿼리를 작성해놓았고, 해당 xml 내에서 namespace를 mapper.hive로 설정했기에, mapper.hive.{queryId} 를 소환
	 * 
	 */
	public int createTable(Map<String, Object> queryConditions) {		
		return sqlSession.update("mapper.hive.createTable", queryConditions);
	}
	/**
	 * 테이블 업데이트
	 * 
	 * @param queryConditions
	 * 	-tableName (String) : 테이블명)
	 *  -addColumnsInfo (Map<String, String>) : 추가할 컬럼 정보
	 *  	- key : 추가할 컬럼의 이름 (ex: col02)
	 *  	- value : 컬럼의 선언 (ex: INT)
	 *  -modifyColumnsInfo (Map<String, String>) : 변경할 컬럼 정보 
	 *  	- key : 추가할 컬럼의 이름 (ex: col03)
	 *  	- value : 컬럼의 선언 (ex: BOOLEAN)
	 *  -dropColumnsInfo (List<String>) : 삭제할 컬럼이름 리스트
	 *  
	 */
	public int updateTable(Map<String, Object> queryConditions) {
		
		int result = 0;
		// 한 번에 모든 쿼리가 UPDATE {TABLE_NAME} 안에 들어가지 않아, 컬럼 추가/수정/삭제를 분리해서 제작.
		// 컬럼 추가
		if(queryConditions.containsKey(Commons.ADD_COLUMNS_INFO) && queryConditions.get(Commons.ADD_COLUMNS_INFO) != null) 
			result += sqlSession.update("mapper.hive.updateTableAddColumns", queryConditions);
		// 컬럼 수정
		if(queryConditions.containsKey(Commons.MODIFY_COLUMNS_INFO) && queryConditions.get(Commons.MODIFY_COLUMNS_INFO) != null) 
			result += sqlSession.update("mapper.hive.updateTableModifyColumns", queryConditions);
		// 컬럼 삭제
		// TRANSACTIONAL을 위해 ORC로 생성했으므로, 컬럼 삭제가 불가능함.
		// 그래서 테이블을 외부로 뺸 후 재생성해야 함. 외부에 데이터가 존재하므로 기존 데이터도 쿼리가 가능함.
		if(queryConditions.containsKey(Commons.DROP_COLUMNS_INFO) && queryConditions.get(Commons.DROP_COLUMNS_INFO) != null) {
			// data_yupr, comment, col_name으로 구성된 리스트
			List<Map<String, String>> columnList = sqlSession.selectList("mapper.hive.selectColumnList", queryConditions.get(Commons.TABLE_NAME));
			List<String> deleteColumnList = (List<String>) queryConditions.get(Commons.DROP_COLUMNS_INFO);
			
			// 기존 테이블 데이터를 백업하고 테이블 drop
			sqlSession.update("mapper.hive.saveExternal", queryConditions);
			sqlSession.update("mapper.hive.dropTable", queryConditions.get(Commons.TABLE_NAME));
			
			Map<String, String> newColumnList = new LinkedHashMap<>();
			
			for(Map<String, String> column : columnList) {
				Boolean isExist = false;
				for(String delColumn : deleteColumnList) {
					// 삭제할 컬럼인지 여부 확인
					if(column.get("col_name").toLowerCase().equals(delColumn.toLowerCase())) {
						isExist = true;
						break;
					}
				}
				
				// 삭제할 컬럼이 아니라면
				if(!isExist) {
					StringBuffer columnName = new StringBuffer(column.get("col_name"));
					StringBuffer columnDef = new StringBuffer(column.get("data_type"));
					
					// COMMENT가 존재할 경우 추가
					if(column.get("comment") != null && !"".equals(column.get("comment"))) {
						columnDef.append("COMMENT").append(Commons.SPACE).append(column.get("comment"));
					}
					
					newColumnList.put(columnName.toString(), columnDef.toString());
				}
			}
			
			queryConditions.put(Commons.COLUMNS_INFO, newColumnList);
			result += sqlSession.update("mapper.hive.createTable", queryConditions);
		}
		
		return result;
	}
	/**
	 * 테이블 삭제
	 * 
	 * @param tableName
	 * 		테이블 이름
	 */
	public int dropTable(String tableName) {
		return sqlSession.delete("mapper.hive.dropTable", tableName);
	}
	
	// DML
	/**
	 * 데이터 입력
	 * 
	 * @param queryConditions
	 *  -tableName (String) : 테이블명
	 * 	-dataInfo (List<List<Object>>) : 입력할 데이터, 열의 순서와 갯수에 맞춰야 함.
	 * 
	 */
	public int insertData(Map<String, Object> queryConditions) {
		/*
		 * TODO: 
		 * 	일단은 데이터 입력 시 테이블의 구조를 알고있고, 그에 따라 데이터를 입력한다는 전제 하에 만들어놓음.
		 *	하지만 실제로는 이렇게 하면 안되고, sqlSession.selectList("mapper.hive.selectColumnList", queryConditions.get(Commons.TABLE_NAME))로 칼럼정보 불러와서,
		 *	칼럼 위치에 맞게 조정하고 나머지는 NULL로 만들어서 넣어줘야 함.
		 *	만약 이렇게 되면 queryConditions.dataInfo는 List<List<Object>>가 아니라, List<Map<String, Object>>가 되어야 함.
		 *	단, 쿼리에 들어갈때는 원래대로 List<List<Object>>로 재변경되어서 들어가야 함.
		 *
		 *  이 코드는 그냥 테스트용이므로 그렇게까지 작성하지는 않음.
		 */
		
		return sqlSession.insert("mapper.hive.insertData", queryConditions);
	}
	/**
	 * 데이터 수정
	 * 
	 * @param queryConditions
	 * 	-tableName (String) : 테이블명
	 *  -dataInfo (Map<String, Object>) : 입력할 데이터
	 *  	-key : 컬럼
	 *  	-value : 값
	 *  -where (Map<String, Object>) : where절에 들어갈 값
	 *  	-key : 컬럼 (ex: col01)
	 *  	-value : 조건 (ex: ='123')
	 */
	//@Transactional
	public int updateData(Map<String, Object> queryConditions) {
		return sqlSession.update("mapper.hive.updateData", queryConditions);
	}
	/**
	 * 데이터 삭제
	 * 
	 * @param queryConditions
	 * 	-tableName (String) : 테이블명
	 *  -where (Map<String, Object>) : where절에 들어갈 값
	 *  	-key : 컬럼 (ex: col01)
	 *  	-value : 조건 (ex: ='123')
	 */
	//@Transactional
	public int deleteData(Map<String, Object> queryConditions) {
		return sqlSession.delete("mapper.hive.deleteData", queryConditions);
	}
	/**
	 * 데이터 조회
	 * 
	 * @param queryConditions
	 * 	-tableName (String) : 테이블명
	 *  -where (Map<String, Object>) : where절에 들어갈 값
	 *  	-key : 컬럼 (ex: col01)
	 *  	-value : 조건 (ex: ='123')
	 * 	
	 * where이 null일 경우 전체 조회.
	 */
	public List<Map<String, Object>> selectAll(Map<String, Object> queryConditions) {
		return sqlSession.selectList("mapper.hive.selectAll", queryConditions);
	}
}

 

 

HiveService.java

package com.example.demo.hive.service;

import java.util.List;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.Commons;
import com.example.demo.hive.dao.HiveDao;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class HiveService {
	@Autowired
	private HiveDao hiveDao;
	
	public void createTable(String tableName, Map<String, String> columnsInfo) {
		
		Map<String, Object> queryConditions = new HashMap<>();
		
		queryConditions.put(Commons.TABLE_NAME, tableName);
		queryConditions.put(Commons.COLUMNS_INFO, columnsInfo);
		
		try {
			hiveDao.createTable(queryConditions);
			log.info("@@@ SQL CREATE TABLE DONE");
		}
		catch(Exception e) {
			log.error("@@@ SQL ERROR OCCURED WHILE CREATE TABLE: {}", e.getMessage());
		}
	}
	
	
	public void updateTable(String tableName, Map<String, String> addColumnsInfo, List<String> dropColumnsInfo, Map<String, String> modifyColumnsInfo) {
		Map<String, Object> queryConditions = new HashMap<>();
		
		queryConditions.put(Commons.TABLE_NAME, tableName);
		queryConditions.put(Commons.ADD_COLUMNS_INFO, addColumnsInfo);
		queryConditions.put(Commons.DROP_COLUMNS_INFO, dropColumnsInfo);
		queryConditions.put(Commons.MODIFY_COLUMNS_INFO, modifyColumnsInfo);
		
		try {
			hiveDao.updateTable(queryConditions);
			log.info("@@@ SQL UPDATE TABLE DONE");
		}
		catch(Exception e) {
			log.error("@@@ SQL ERROR OCCURED WHILE UPDATE TABLE: {}", e.getMessage());
		}
	}
	
	public void dropTable(String tableName) {
		try {
			hiveDao.dropTable(tableName);
			log.info("@@@ SQL DROP TABLE DONE");
		}
		catch(Exception e) {
			log.error("@@@ SQL ERROR OCCURED WHILE DROP TABLE : {}", e.getMessage());
		}
	}
	
	
	public void insertData(String tableName, List<List<Object>> values) {
		Map<String, Object> queryConditions = new HashMap<>();
		
		queryConditions.put(Commons.TABLE_NAME, tableName);
		queryConditions.put(Commons.DATA_INFO, values);
		
		try {
			hiveDao.insertData(queryConditions);
			log.info("@@@ SQL INSERT DATA DONE");
		}
		catch(Exception e) {
			log.error("@@@ SQL ERROR OCCURED WHILE INSERT DATA : {}", e.getMessage());
		}
	}
	
	public void updateData(String tableName, Map<String, Object> values, Map<String, Object> conditions) {
		Map<String, Object> queryConditions = new HashMap<>();
		
		queryConditions.put(Commons.TABLE_NAME, tableName);
		queryConditions.put(Commons.UPDATE_DATA_INFO, values);
		queryConditions.put(Commons.WHERE, conditions);
		
		try {
			hiveDao.updateData(queryConditions);
			log.info("@@@ SQL UPDATE DATA DONE");
		}
		catch(Exception e) {
			log.error("@@@ SQL ERROR OCCURED WHILE UPDATE DATA : {}", e.getMessage());
		}
	}
	
	public void deleteData(String tableName, Map<String, Object> conditions) {
		Map<String, Object> queryConditions = new HashMap<>();
		
		queryConditions.put(Commons.TABLE_NAME, tableName);
		queryConditions.put(Commons.WHERE, conditions);
		
		try {
			hiveDao.deleteData(queryConditions);
			log.info("@@@ SQL DELETE DATA DONE");
		}
		catch(Exception e) {
			log.error("@@@ SQL ERROR OCCURED WHILE DELETE DATA : {}", e.getMessage());
		}
	}
	
	public List<Map<String, Object>> selectData(String tableName, Map<String, Object> conditions) {
		Map<String, Object> queryConditions = new HashMap<>();
		
		queryConditions.put(Commons.TABLE_NAME, tableName);
		queryConditions.put(Commons.WHERE, conditions);
		
		return hiveDao.selectAll(queryConditions);
	}
}

 

 

모든 코드 작성이 완료되었다면 이제 Test 메소드를 만들어 실행해본다.

package com.example.demo;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.example.hive.service.HiveService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootTest
class HadoopTestApplicationTests {

	@Test
	void contextLoads() {
	}

	@Autowired HiveService hiveService;
	
	@Test
	void hiveTest() {
		String tableName = "test_table";

		log.info("### DROP TABLE STARTED...");
		hiveService.dropTable(tableName);
		
		log.info("\n");
		
		
		// CREATE TABLE
		log.info("### CREATE TABLE STARTED...");
		Map<String, String> createDDL = new LinkedHashMap<>(); // HashMap 사용 시 Mybatis에서 순서가 꼬임.
		
		createDDL.put("ID", "STRING");
		createDDL.put("VALUE01", "STRING"); // NOT NULL 지원안됨.
		createDDL.put("VALUE02", "STRING");
		
		hiveService.createTable(tableName, createDDL);
		
		log.info("\n");
		
		
		// ALTER TABLE
		log.info("### ALTER TABLE STARTED...");
		Map<String, String> updateAddColumnDDL = new LinkedHashMap<>();
		Map<String, String> updateMdfColumnDDL = new LinkedHashMap<>();
		List<String> updateDelColumnDDL = new LinkedList<>();
		
		updateAddColumnDDL.put("VALUE03", "VARCHAR(100)");
		updateAddColumnDDL.put("VALUE04", "VARCHAR(100)");
		
		updateMdfColumnDDL.put("VALUE01", "VARCHAR(50)");
		
		updateDelColumnDDL.add("VALUE02");
		
		hiveService.updateTable(tableName, updateAddColumnDDL, updateDelColumnDDL, updateMdfColumnDDL);

		log.info("\n");
		
		// INSERT DATA
		log.info("### INSERT DATA STARTED...");
		List<List<Object>> insertData = new LinkedList<>();
		
		List<Object> data1 = new LinkedList<>();
		data1.add("ID01");
		data1.add("1234");
		data1.add("1235");
		data1.add("1236");
		
		List<Object> data2 = new LinkedList<>();
		data2.add("ID02");
		data2.add("2345");
		data2.add("2346");
		data2.add("2347");
		
		List<Object> data3 = new LinkedList<>();
		data3.add("ID03");
		data3.add("3456");
		data3.add("3457");
		data3.add("3458");
		
		insertData.add(data1);
		insertData.add(data2);
		insertData.add(data3);
		
		hiveService.insertData(tableName, insertData);

		log.info("\n");
		
		// SELECT DATA (ALL)
		log.info("### SELECT DATA STARTED...");
		
		log.info("===========================");
		log.info("===========================");
		log.info(hiveService.selectData(tableName, null).toString());
		// [{test_table={value04=1236, value03=1235, id=ID01, value01=1234}}, {test_table={value04=2347, value03=2346, id=ID02, value01=2345}}, {test_table={value04=3458, value03=3457, id=ID03, value01=3456}}]
		log.info("===========================");
		log.info("===========================");

		log.info("\n");
		
		// UPDATE DATA
		log.info("### UPDATE DATA STARTED...");
		Map<String, Object> updateValues = new HashMap<>();
		updateValues.put("VALUE01", "3459");
		updateValues.put("VALUE04", "3450");
		
		Map<String, Object> updateWhere = new HashMap<>();
		updateWhere.put("ID", "='ID03'");
		
		hiveService.updateData(tableName, updateValues, updateWhere);
		
		log.info("\n");
		
		// SELECT DATA (ONE)
		log.info("### SELECT DATA STARTED...");
		Map<String, Object> selectWhere = new HashMap<>();
		selectWhere.put("ID", "='ID03'");
		
		log.info("===========================");
		log.info("===========================");
		log.info(hiveService.selectData(tableName, selectWhere).toString());
		// [{test_table={value04=3450, value03=3457, id=ID03, value01=3459}}]
		log.info("===========================");
		log.info("===========================");

		log.info("\n");
		
		// DELETE DATA
		log.info("### DELETE DATA STARTED...");
		Map<String, Object> deleteWhere = new HashMap<>();
		deleteWhere.put("ID", " LIKE 'ID%'");
		
		hiveService.deleteData(tableName, deleteWhere);
		
		log.info("\n");
		
		// SELECT DATA (ALL)
		log.info("### SELECT DATA STARTED...");
		
		log.info("===========================");
		log.info("===========================");
		log.info(hiveService.selectData(tableName, null).toString());
		// []
		log.info("===========================");
		log.info("===========================");
		
		log.info("\n");
		
		// DROP TABLE
		log.info("### DROP TABLE STARTED...");
		hiveService.dropTable(tableName);
		
		log.info("\n");
		
		// DONE
		log.info("### ALL METHOD DONE SUCCESSFULLY");
	}
}

 

 

다음 결과를 얻을 수 있다.

2023-01-22 22:33:57.609  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : Started HadoopTest1ApplicationTests in 3.28 seconds (JVM running for 5.746)
2023-01-22 22:33:58.150  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### DROP TABLE STARTED...
2023-01-22 22:33:59.388  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL DROP TABLE DONE
2023-01-22 22:33:59.388  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:33:59.388  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### CREATE TABLE STARTED...
2023-01-22 22:33:59.561  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL CREATE TABLE DONE
2023-01-22 22:33:59.561  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:33:59.561  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### ALTER TABLE STARTED...
2023-01-22 22:34:00.231  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL UPDATE TABLE DONE
2023-01-22 22:34:00.231  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:34:00.231  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### INSERT DATA STARTED...
2023-01-22 22:34:20.912  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL INSERT DATA DONE
2023-01-22 22:34:20.912  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:34:20.912  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### SELECT DATA STARTED...
2023-01-22 22:34:20.913  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:20.913  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:21.340  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : [{test_table={value04=1236, value03=1235, id=ID01, value01=1234}}, {test_table={value04=2347, value03=2346, id=ID02, value01=2345}}, {test_table={value04=3458, value03=3457, id=ID03, value01=3456}}]
2023-01-22 22:34:21.341  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:21.341  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:21.341  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:34:21.341  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### UPDATE DATA STARTED...
2023-01-22 22:34:45.567  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL UPDATE DATA DONE
2023-01-22 22:34:45.567  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:34:45.567  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### SELECT DATA STARTED...
2023-01-22 22:34:45.567  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:45.568  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:45.843  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : [{test_table={value04=3450, value03=3457, id=ID03, value01=3459}}]
2023-01-22 22:34:45.843  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:45.843  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:34:45.844  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:34:45.844  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### DELETE DATA STARTED...
2023-01-22 22:35:08.044  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL DELETE DATA DONE
2023-01-22 22:35:08.044  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:35:08.044  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### SELECT DATA STARTED...
2023-01-22 22:35:08.044  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:35:08.044  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:35:08.267  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : []
2023-01-22 22:35:08.267  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:35:08.267  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ===========================
2023-01-22 22:35:08.267  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:35:08.267  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### DROP TABLE STARTED...
2023-01-22 22:35:08.407  INFO 2144 --- [           main] c.example.demo.hive.service.HiveService  : @@@ SQL DROP TABLE DONE
2023-01-22 22:35:08.407  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : 

2023-01-22 22:35:08.407  INFO 2144 --- [           main] c.e.demo.HadoopTestApplicationTests     : ### ALL METHOD DONE SUCCESSFULLY
728x90
반응형