리팩토링을 하다보면 테스트를 위해 h2를 통한 테스트가 진행되어야 하는데. 그중 특정 query들은 해당 db의 function을 사용하는 경우가 있다. h2는 해당 function을 직접 지원하지 않고 사용자가 직접 정의해서 사용할 수 있도록 진행하고 있는데 해당 방법을 정리해두려고 한다.
H2를 사용하여 테스트를 작성하다보면 이런 상황을 마주친다.
H2에 정의되어 있지 않은 Function을 사용해서 에러가 발생한 것이다. 이는 각 DBMS에 따라 사용되는 Function이 다르기 때문에 H2에는 그러한 Function들을 정의해두지 않았기 때문이다.
H2는 이러한 문제를 사용자가 직접 설정할 수 있도록 제공해준다.
package com.kakaovx.ballmate.common.h2;
public class H2Function {
public static String HEX(String s){
return "hash value";
}
public static String AES_ENCRYPT(String s, String key){
return "encrypt value";
}
}
현재 내 문제를 해결하기 위해 필요한 함수는 HEX
와 AES_ENCRYPT
이다. 현재는 쉽게 사용하기 위해 특정 문자열을 반환하도록 설정해두었지만 필요시 Function에 맞게 반환되도록 직접 구현해주어도 된다.
CREATE ALIAS IF NOT EXISTS HEX FOR "com.example.test.common.h2.H2Function.HEX";
CREATE ALIAS IF NOT EXISTS AES_ENCRYPT FOR "com.example.test.common.h2.H2Function.AES_ENCRYPT";
다음과 같이 Function을 alias로 생성해주면
이전에는 함수로 인해 실패하던 테스트가 정상적으로 작동하는 것을 확인할 수 있다.
개인적으로 해당 Function을 이해하고 생성해낼 수 있을 이해가 있다면 Sql을 통해 풀어내기보다 코드를 통해 풀어내는 편이 더 좋지 않을까 싶다!
해당 방법은 리팩토링 과정중 어쩔 수 없이 h2에서 테스트하기 위함이므로 꼭 테스트 코드를 작성한 후 실제 db와 연결한 뒤 잘 작동하는지 확인이 필요하다!
안녕하세요 예제에서 h2에 AES_ENCRYPT,HEX 함수 등록할 때 주의해야할 점이 있을까요?
http://www.h2database.com/html/features.html#user_defined_functions DOCS에서는 클래스는 public으로, 함수는 public, static으로 선언하라고 나와있긴한데 패키지 경로를 찾지 못하는 오류가 발생하고 있어서요.