ํด๋์ค์ ๋ง์ฐฌ๊ฐ์ง๋ก, ๋ฉ์๋๋ ์ ๋ค๋ฆญ์ผ๋ก ๋ง๋ค ์ ์๋ค.
๋งค๊ฐ๋ณ์ํ ํ์ ์ ๋ฐ๋ ์ ์ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ ๋ณดํต ์ ๋ค๋ฆญ์ด๋ค. ์์ปจ๋ Collections์ ์๊ณ ๋ฆฌ์ฆ ๋ฉ์๋(binarysearch, sort ๋ฑ)๋ ๋ชจ๋ ์ ๋ค๋ฆญ์ด๋ค.
๋จผ์ , ๋ก ํ์
(raw type)์ ์ฌ์ฉํ union
๋ฉ์๋๋ ์ปดํ์ผ ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํ๋ค:
public static Set union(Set s1, Set s2) {
Set result = new HashSet(s1);
result.addAll(s2);
return result;
}
์ด ๋ฉ์๋๋ ๊ฒฝ๊ณ ์์ด ์ปดํ์ผ๋์ง๋ง, ํ์
์์ ์ฑ์ ๋ณด์ฅํ์ง ์๋๋ค. Set
ํ์
์ ์์๊ฐ ์ด๋ค ํ์
์ธ์ง ์ ์ ์์ด, ClassCastException
์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
๋ก ํ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๋ฉ์๋๋ฅผ ์ ๋ค๋ฆญ ๋ฉ์๋๋ก ์์ฑํด์ผ ํ๋ค.
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
Set<E> result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
<E>
: ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์ธSet<E>
: ๋ฉ์๋์ ๋ฐํ ํ์ ๊ณผ ๋งค๊ฐ๋ณ์ ํ์ ์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ์์ ์ฑ์ ๋ณด์ฅํ๋ค.
์ด ๋ฉ์๋๋ ์ ๋ ฅ ์งํฉ๊ณผ ๋ฐํ ์งํฉ์ ํ์ ์ด ์ผ์นํด์ผ ํ๋ฉฐ, ํ์ ์์ ํ ์ฝ๋๋ก ์ปดํ์ผํ ์ ์๋ค.
public static <E/*ํ์
๋งค๊ฐ๋ณ์ ๋ชฉ๋ก*/> Set<E/*๋ฐํ ํ์
*/> union(Set<E/*ํ๋ผ๋ฏธํฐ ํ์
*/> s1, Set<E> s2) {
Set<E> result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
- ์์๋๋ก ํ์ ๋งค๊ฐ๋ณ์ ๋ชฉ๋ก, ๋ฐํ ํ์ , ํ๋ผ๋ฏธํฐ ํ์ 3๊ฐ์ง๋ฅผ ๋ฉ์๋ ์๊ทธ๋์ฒ์ ์ ๋ ฅํ ์ ์๋ค.
- ์ด ๋ฉ์๋๋ ๊ฒฝ๊ณ ์์ด ์ปดํ์ผ ๋๋ฉฐ, ํ์ ์์ ํ๊ณ , ์ฐ๊ธฐ๋ ์ฝ๋ค.
- union ๋ฉ์๋๋ ์งํฉ 3๊ฐ๏ผ์ ๋ ฅ 2๊ฐ, ๋ฐํ 1๊ฐ๏ผ์ ํ์ ์ด ๋ชจ๋ ๊ฐ์์ผ ํ๋ค.
public static void main๏ผString[] args๏ผ {
Set<String> guys = Set.of("ํฐ", "๋", "ํค๋ฆฌ");
Set<String> stooges = Set.of("๋๋ฆฌ", "๋ชจ์", "์ปฌ๋ฆฌ");
Set<String> aflCio = union(guys, stooges);
System.out.println("aflCio = " + aflCio);
}
๋ชจ์, ํฐ, ํด๋ฆฌ, ๋๋ฆฌ, ์ปฌ๋ฆฌ, ๋ ์ถ๋ ฅ๋จ
- ์ ์์ ์์๋ ๋ ๊ฐ์
Set<String>
์ ํฉ์ณ ์๋ก์ด ์งํฉ์ ์์ฑํ๋ค. - ์ด ๋ฉ์๋๋ ์ ๋ค๋ฆญ ๋ฉ์๋์ด๊ธฐ ๋๋ฌธ์, ์ปดํ์ผ ์ ํ์ ๊ฒ์ฌ๋ฅผ ํตํด ์์ ํ ์ฝ๋์์ ๋ณด์ฅํ๋ค.
ํ์ ์ ์์ผ๋์นด๋ ํ์
์ ์ฌ์ฉํ์ฌ union
๋ฉ์๋๋ฅผ ๋ ์ ์ฐํ๊ฒ ๊ฐ์ ํ ์ ์๋ค.
์์ผ๋์นด๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ์ ๋ ฅ ์งํฉ์ ํ์ ์ด ์ ํํ ์ผ์นํ์ง ์์๋, ๊ณตํต์ ์์ ํ์ ์ด ์๋ ๊ฒฝ์ฐ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๊ฒ ๋๋ค. ์ด๋ฅผ ํตํด ๋ค์ํ ํ์ ์ ์งํฉ์ ์์ ํ๊ฒ ํฉ์น ์ ์๋ค.
import java.util.HashSet;
import java.util.Set;
public class UnionExample {
// ํ์ ์ ์์ผ๋์นด๋ ํ์
์ ์ฌ์ฉํ union ๋ฉ์๋
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2) {
Set<E> result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
public static void main(String[] args) {
Set<String> guys = Set.of("ํฐ", "๋", "ํค๋ฆฌ");
Set<String> stooges = Set.of("๋๋ฆฌ", "๋ชจ์", "์ปฌ๋ฆฌ");
// ํ์ ์ ์์ผ๋์นด๋ ํ์
์ ์ฌ์ฉํ union ๋ฉ์๋๋ฅผ ํธ์ถ
Set<String> aflCio = union(guys, stooges);
// ๊ฒฐ๊ณผ ์ถ๋ ฅ
System.out.println("aflCio = " + aflCio);
}
}
Set<E> result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
Set<? extends E>
๋ E
์ ํ์ ํ์
์ ํ์ฉํ์ฌ ๋ค์ํ ํ์
์ ์งํฉ์ ํฉ์น ์ ์๋ค.
- ๋ฉ์๋ ์๊ทธ๋์ฒ:
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)
:<E>
๋ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ์ํ๋ค.Set<? extends E>
๋E
์ ํ์ ํ์ ์ ๋ํ๋ด๋ ํ์ ์ ์์ผ๋์นด๋ ํ์ ์ด๋ค. ์ฆ,s1
๊ณผs2
๋E
์ ํ์ ํ์ ์ธ ์งํฉ์ ๋ฐ์ ์ ์๋ค.- ๋ฐํ ํ์
์
Set<E>
๋ก, ๋ ์งํฉ์ ํฉ์งํฉ์ ๋ฐํํ๋ค.
- ์ ์ฐํ ํ์
์ฒ๋ฆฌ:
Set<? extends E>
๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ, ์ ๋ ฅ ์งํฉ์ ํ์ ์ดE
์ ํ์ ํ์ ์ผ ๋์๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ค.
- ์ถ๋ ฅ ๊ฒฐ๊ณผ:
guys
์stooges
๋ ์งํฉ์ ํฉ์งํฉ์ ๊ตฌํ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋ค.
๋๋ก๋ ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ ํ์ ์ผ๋ก ํ์ฉํ ์ ์๊ฒ ๋ง๋ค์ด์ผ ํ ๋๊ฐ ์๋ค.
์ ๋ค๋ฆญ ์ฑ๊ธํด ํฉํฐ๋ฆฌ ํจํด์ ์ฌ์ฉํ๋ฉด, ๋ฐํ์์ ํ๋์ ๊ฐ์ฒด๋ฅผ ์ด๋ค ํ์ ์ผ๋ก๋ ๋งค๊ฐ๋ณ์ํํ ์ ์๋ค.
๋ค์์ ์ ๋ค๋ฆญ ์ฑ๊ธํด ํจํด์ ์ฌ์ฉํ์ฌ ํญ๋ฑ ํจ์(identity function)๋ฅผ ๊ตฌํํ ์์ ๋ก, ์ด ํจํด์ ํตํด ํ๋์ ๊ฐ์ฒด๋ฅผ ์ด๋ค ํ์ ์ผ๋ก๋ ๋งค๊ฐ๋ณ์ํํ ์ ์๋ค.
1) ์ฌ๊ธฐ์ ์ ๊น ๋ฐํ์์ ํ๋์ ๊ฐ์ฒด๋ฅผ ์ด๋ค ํ์ ์ผ๋ก๋ ๋งค๊ฐ๋ณ์ํํ ์ ์๋ค๋ ๋ฌด์จ๋ป์ผ๊น?
๋งค๊ฐ๋ณ์ํ(Parameterized)
๋ ์ด๋ค ์์๋ฅผ ํน์ ๊ฐ์ด๋ ํ์
์ ๋ง๊ฒ ์ผ๋ฐํํ์ฌ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
๋ฐํ์์ ํ๋์ ๊ฐ์ฒด๋ฅผ ์ด๋ค ํ์
์ผ๋ก๋ ๋งค๊ฐ๋ณ์ํํ ์ ์๋ค
๋ ๊ฒ์ ์ ๋ค๋ฆญ ํ์
์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์ฌ์ฉํ๋ ํ์
๋งค๊ฐ๋ณ์๊ฐ ๋ฐํ์์ ๊ฒฐ์ ๋ ์ ์๋ค๋ ์๋ฏธ์ด๋ค.
์ฆ, ์ปดํ์ผ ์์ ์๋ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ์๊ฑฐ๋์ง๋ง, ๋ฐํ์์ ์ ๋ค๋ฆญ ๊ฐ์ฒด๋ฅผ ํน์ ํ์ ์ผ๋ก ํ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ ์ ์๋ค๋ ๋ป์ด๋ค.
์๋ฐ์์ ์ ๋ค๋ฆญ์ ์ปดํ์ผ ์์ ์ ํ์ ๊ฒ์ฌ๋ฅผ ์ํํ๊ณ , ๋ฐํ์์๋ ํ์ ์ ๋ณด๋ฅผ ์ ๊ฑฐํ๋ "ํ์ ์๊ฑฐ(type erasure)" ๋ฐฉ์์ ์ฌ์ฉํ๋ค. ๊ทธ๋ฌ๋, ์ ๋ค๋ฆญ ์ฑ๊ธํด ํจํด์ ํตํด ๋ฐํ์์ ํ์ ์ ๋ณ๊ฒฝํ์ฌ ์ฌ๋ฌ ํ์ ์ ๋ํด ๋์ผํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
// ํญ๋ฑ ํจ์(identity function)๋ฅผ ๊ตฌํํ ์ ๋ค๋ฆญ ์ฑ๊ธํด ๊ฐ์ฒด
// ์
๋ ฅ ๊ฐ์ ๊ทธ๋๋ก ๋ฐํํ๋ ํจ์ ๊ฐ์ฒด๋ก, ์ํ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ํ์
์ ๋ํด ์ฌ์ฌ์ฉ ๊ฐ๋ฅ
private static final UnaryOperator<Object> IDENTITY_FN = t -> t;
@SuppressWarnings("unchecked")
public static <T> UnaryOperator<T> identityFunction() {
// ์ ๋ค๋ฆญ ํ์
T๋ก ํ๋ณํํ์ฌ ๋ฐํ (ํ์
์์ ์ฑ์ด ๋ณด์ฅ๋๋ฏ๋ก ๋น๊ฒ์ฌ ๊ฒฝ๊ณ ๋ฅผ ์ต์ )
return (UnaryOperator<T>) IDENTITY_FN;
}
IDENTITY_FN
์ ์ ๋ ฅ๊ฐ์ ์์ ์์ด ๊ทธ๋๋ก ๋ฐํํ๋UnaryOperator<Object>
ํ์ ์ ํจ์ ๊ฐ์ฒด์ด๋ค.identityFunction()
๋ฉ์๋๋ ์ ๋ค๋ฆญ ๋ฉ์๋๋ก, ํธ์ถ ์ ํ์ ๋งค๊ฐ๋ณ์T
์ ๋ง๊ฒ ํญ๋ฑ ํจ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.@SuppressWarnings("unchecked")
์ ๋ํ ์ด์ ์ ์ปดํ์ผ๋ฌ์ ๋น๊ฒ์ฌ ํ๋ณํ ๊ฒฝ๊ณ ๋ฅผ ์ต์ ํ๋ค. ์ฌ๊ธฐ์๋ ํ์ ์์ ์ฑ์ด ๋ณด์ฅ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํด๋ ๋ฌธ์ ๊ฐ ์๋ค.
UnaryOperator๋ฅผ ์ด๋ค ํ์ ์ด๋ ๊ณ์ํด์ ์ด์ฉํ ์ ์๋ค.
public static void main(String[] args) {
// ๋ฌธ์์ด ๋ฐฐ์ด
String[] strings = { "์ผ๋ฒ ", "๋๋ง", "๋์ผ๋ก " };
// ์ ๋ค๋ฆญ ์ฑ๊ธํด์ ์ฌ์ฉํ์ฌ UnaryOperator<String> ํ์
์ ํญ๋ฑ ํจ์ ์์ฑ
UnaryOperator<String> sameString = identityFunction();
// ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด ํญ๋ฑ ํจ์๋ฅผ ์ ์ฉ (๊ฐ์ด ๊ทธ๋๋ก ์ถ๋ ฅ๋จ)
for (String s : strings) {
System.out.println(sameString.apply(s));
}
// ์ซ์ ๋ฐฐ์ด
Number[] numbers = { 1, 2.0, 3L };
// ์ ๋ค๋ฆญ ์ฑ๊ธํด์ ์ฌ์ฉํ์ฌ UnaryOperator<Number> ํ์
์ ํญ๋ฑ ํจ์ ์์ฑ
UnaryOperator<Number> sameNumber = identityFunction();
// ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด ํญ๋ฑ ํจ์๋ฅผ ์ ์ฉ (๊ฐ์ด ๊ทธ๋๋ก ์ถ๋ ฅ๋จ)
for (Number n : numbers) {
System.out.println(sameNumber.apply(n));
}
}
identityFunction()
๋ฉ์๋๋ฅผ ํตํดUnaryOperator<String>
๊ณผUnaryOperator<Number>
๋ก ๊ฐ๊ฐ์ ํ์ ์ ๋ํด ํญ๋ฑ ํจ์๋ฅผ ์ฌ์ฉํ๋ค.- ๋ฌธ์์ด ๋ฐฐ์ด๊ณผ ์ซ์ ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด ํญ๋ฑ ํจ์๋ฅผ ์ ์ฉํ์ฌ ๊ฐ์ ๊ทธ๋๋ก ์ถ๋ ฅํ๋ค. ์ปดํ์ผ ๊ฒฝ๊ณ ๋ ์ค๋ฅ ์์ด ์ฌ์ฉํ ์ ์๋ค.
์ด ๋ฐฉ์์ ์ ๋ค๋ฆญ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์ฌ์ฉํ๋ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐํ์์ ๊ฒฐ์ ํ์ฌ ๋์ผํ ๊ฐ์ฒด๋ฅผ ๋ค์ํ ํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค. ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ค์ด๊ณ , ์ฝ๋ ์ค๋ณต์ ๋ฐฉ์งํ๋ ๋ฐ ์ ์ฉํ ํจํด์ด๋ค.
์ฌ๊ท์ ํ์
ํ์
์ ์ ๋ค๋ฆญ ํ์
๋งค๊ฐ๋ณ์๊ฐ ์๊ธฐ ์์ ์ ์ฌ์ฉํ์ฌ ํ์
์ ํ์ฉ ๋ฒ์๋ฅผ ํ์ ํ๋ ๊ฒ์ ๋งํ๋ค. ์ฃผ๋ก Comparable
์ธํฐํ์ด์ค์ ํจ๊ป ์ฌ์ฉ๋์ด, ํน์ ํ์
์ด ์๊ธฐ ์์ ๊ณผ ๋น๊ตํ ์ ์๋๋ก ์ ํํ๋ค.
์ฌ๊ท์ ํ์ ํ์ ์ ์ ๋ ฌ, ๊ฒ์, ์ต๋๊ฐ ๋๋ ์ต์๊ฐ ๊ณ์ฐ๊ณผ ๊ฐ์ ๋น๊ต ์ฐ์ฐ์ด ํ์ํ ๋ฉ์๋์์ ์์ฃผ ์ฌ์ฉ๋๋ค.
// ์ปฌ๋ ์
๋ด์ ์์ ์ค์์ ๊ฐ์ฅ ํฐ ๊ฐ์ ๋ฐํํ๋ ๋ฉ์๋
// <E extends Comparable<E>>๋ E ํ์
์ด ์๊ธฐ ์์ ๊ณผ ๋น๊ต ๊ฐ๋ฅํ๋ค๋ ์๋ฏธ
public static <E extends Comparable<E>> E max(Collection<E> c) {
// ์ปฌ๋ ์
์ด ๋น์ด ์๋ ๊ฒฝ์ฐ ์์ธ ๋ฐ์
if (c.isEmpty()) {
throw new IllegalArgumentException("์ปฌ๋ ์
์ด ๋น์ด ์์ต๋๋ค.");
}
E result = null;
// ์ปฌ๋ ์
์ ๊ฐ ์์๋ฅผ ์ํํ๋ฉฐ ์ต๋๊ฐ ์ฐพ๊ธฐ
for (E e : c) {
// ์ฒ์ ์์์ด๊ฑฐ๋ ํ์ฌ ์ต๋๊ฐ๋ณด๋ค ํฐ ๊ฒฝ์ฐ ์ต๋๊ฐ ๊ฐฑ์
if (result == null || e.compareTo(result) > 0) {
result = e;
}
}
// ์ต๋๊ฐ ๋ฐํ
return result;
}
์ ๋ฉ์๋๋ ์ปฌ๋ ์ ์ ์ต๋๊ฐ์ ๊ตฌํ๋ฉฐ,
Comparable<E>
๋ฅผ ๊ตฌํํ ํ์ ์ด์ด์ผ๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
<E extends Comparable<E>> :
ํ์ ๋งค๊ฐ๋ณ์E
๋Comparable<E>
๋ฅผ ๊ตฌํํด์ผ ํ๋ค๋ ๋ป์ ๋๋ค. ์ฆ,E
ํ์ ์ ๊ฐ์ฒด๋ผ๋ฆฌ ๋น๊ตํ ์ ์์ด์ผ ํ๋ค.- ์ด ๋ฉ์๋๋ ์ปฌ๋ ์ ์ ์๋ ์์์ ์์ฐ์ ์์๋ฅผ ๊ธฐ์ค์ผ๋ก ์ต๋๊ฐ์ ์ฐพ๋๋ค.
- ์ปฌ๋ ์
์ด ๋น์ด ์์ ๊ฒฝ์ฐ
IllegalArgumentException
์ ์ฐพ๋๋ค. - ์ฌ๊ท์ ํ์
ํ์ ์ ํตํด
E
ํ์ ์ ๊ฐ์ฒด๊ฐ ์๋ก ๋น๊ต ๊ฐ๋ฅํจ์ ์ปดํ์ผ๋ฌ๊ฐ ๋ณด์ฅํด์ค๋ค.
public interface CodeValue {
String getCode();
String getValue();
}
public class EnumConverter<E extends Enum<E> & CodeValue> implements AttributeConverter<E, String> {
private Class<E> clz;
protected EnumConverter(Class<E> enumClass) {
this.clz = enumClass;
}
@Override
public String convertToDatabaseColumn(E attribute) {
return attribute != null ? attribute.getCode() : null;
}
@Override
public E convertToEntityAttribute(String dbData) {
if (dbData == null)
return null;
return EnumSet.allOf(clz).stream()
.filter(e -> e.getCode().equals(dbData))
.findAny()
.orElseThrow(() -> new BusinessException(ErrorCode.ENUM_NOT_FOUND));
}
}
@Converter(autoApply = true)
public class ChargerTypeConverter extends EnumConverter<ChargerType> {
public ChargerTypeConverter() {
super(ChargerType.class);
}
}
@Convert(converter = ChargerTypeConverter.class)
@Column(name = "charger_type", nullable = false)
private ChargerType chargerType;
public enum ChargerType implements CodeValue {
SLOW("SLOW", "์์"),
AC3("AC3", "AC3์"),
DESTINATION("DESTINATION", "๊ธ์"),
ETC("ETC", "๊ธฐํ"),
;
private final String code;
private final String value;
ChargerType(String code, String value) {
this.code = code;
this.value = value;
}
@Override
public String getCode() {
return code;
}
@Override
public String getValue() {
return value;
}
}
์ด ์ฝ๋๋ JPA
(Java Persistence API)์์ ์ฌ์ฉ๋๋ ์ปค์คํ
AttributeConverter
๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํฐํฐ ๊ฐ์ ๋ณํ์ ์ฒ๋ฆฌํ๋ ์์ ์
๋๋ค. ์ฌ๊ธฐ์๋ Enum
ํ์
์ธ ChargerType
์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปฌ๋ผ์ ์ ์ฅํ๊ณ , ๋ค์ ์ํฐํฐ ์์ฑ์ผ๋ก ๋ณํํ๋ ๊ณผ์ ์ ๋ค๋ฃน๋๋ค.
-
CodeValue
์ธํฐํ์ด์ค- ์ด ์ธํฐํ์ด์ค๋ ๊ฐ ์ด๊ฑฐํ(Enum)์ด
getCode()
์getValue()
๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํ๋ค๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค. - ์ด ์ฝ๋์์๋
getCode()
๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ ๊ฐ์ ๋ฐํํ๊ณ ,getValue()
๊ฐ ํํํ ๊ฐ์ ๋ฐํํฉ๋๋ค.
public interface CodeValue { String getCode(); String getValue(); }
- ์ด ์ธํฐํ์ด์ค๋ ๊ฐ ์ด๊ฑฐํ(Enum)์ด
-
EnumConverter
ํด๋์ค- ์ด ํด๋์ค๋
AttributeConverter<E, String>
์ ๊ตฌํํ์ฌ ์ ๋ค๋ฆญ ํ์ ์ ์ด๊ฑฐํ(E extends Enum<E> & CodeValue
)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์String
ํ์ ์ผ๋ก ๋ณํํ๋ ์ญํ ์ ํฉ๋๋ค. E
๋Enum
ํ์ ์ด๋ฉด์CodeValue
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ด๊ฑฐํ์ ์๋ฏธํฉ๋๋ค.AttributeConverter<E, String>
:E
ํ์ ์ ์์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์String
ํ์ ์ผ๋ก ๋ณํํ๊ณ , ๋ฐ๋๋ก ๋ณํํ๋ ์ญํ ์ ํฉ๋๋ค.
public class EnumConverter<E extends Enum<E> & CodeValue> implements AttributeConverter<E, String> { private Class<E> clz; protected EnumConverter(Class<E> enumClass) { this.clz = enumClass; } @Override public String convertToDatabaseColumn(E attribute) { // ์ํฐํฐ ์์ฑ(E)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปฌ๋ผ(String)์ผ๋ก ๋ณํ return attribute != null ? attribute.getCode() : null; } @Override public E convertToEntityAttribute(String dbData) { // ๋ฐ์ดํฐ๋ฒ ์ด์ค์ String์ ์ํฐํฐ ์์ฑ์ผ๋ก ๋ณํ if (dbData == null) return null; return EnumSet.allOf(clz).stream() .filter(e -> e.getCode().equals(dbData)) // Enum์ ์ฝ๋์ ์ผ์นํ๋ ํญ๋ชฉ์ ์ฐพ์ .findAny() .orElseThrow(() -> new BusinessException(ErrorCode.ENUM_NOT_FOUND)); // ์ฐพ์ง ๋ชปํ๋ฉด ์์ธ ๋ฐ์ } }
convertToDatabaseColumn
๋ฉ์๋:- ์ํฐํฐ์ ์ด๊ฑฐํ ์์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ
String
ํ์ ์ ๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค. - ์ด๊ฑฐํ ๊ฐ์ด
null
์ธ ๊ฒฝ์ฐnull
์ ๋ฐํํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉดgetCode()
๋ฉ์๋๋ฅผ ํตํด ๋ณํ๋ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.
- ์ํฐํฐ์ ์ด๊ฑฐํ ์์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ
convertToEntityAttribute
๋ฉ์๋:- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์จ
String
๊ฐ์ ์ํฐํฐ์ ์ด๊ฑฐํ ํ์ ์ผ๋ก ๋ณํํฉ๋๋ค. EnumSet.allOf(clz)
๋ฅผ ํตํด ํด๋น ์ด๊ฑฐํ ํด๋์ค์ ๋ชจ๋ ๊ฐ์ ์ํํ๋ฉฐ,getCode()
๋ฉ์๋๋ก ํํฐ๋งํ์ฌ ๋งค์นญ๋๋ ์ด๊ฑฐํ ๊ฐ์ ์ฐพ์ต๋๋ค.- ๋งค์นญ๋๋ ๊ฐ์ด ์์ผ๋ฉด
BusinessException
์ ๋ฐ์์ํต๋๋ค(ENUM_NOT_FOUND
).
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์จ
- ์ด ํด๋์ค๋
-
ChargerTypeConverter
ํด๋์คEnumConverter
์ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ฒด๋ก,ChargerType
์ด๊ฑฐํ ํ์ ์ ๋ํ ๋ณํ๊ธฐ๋ฅผ ์ ์ํฉ๋๋ค.@Converter(autoApply = true)
์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ JPA๊ฐ ์๋์ผ๋ก ์ด ๋ณํ๊ธฐ๋ฅผ ์ ์ฉํ๋๋ก ์ค์ ํฉ๋๋ค.
@Converter(autoApply = true) public class ChargerTypeConverter extends EnumConverter<ChargerType> { public ChargerTypeConverter() { super(ChargerType.class); } }
-
ChargerType
์ด๊ฑฐํChargerType
์CodeValue
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ด๊ฑฐํ์ ๋๋ค.- ๊ฐ ์์์๋
code
์value
๋ผ๋ ๋ ๊ฐ์ ํ๋๋ฅผ ๊ฐ์ง๋ฉฐ, ์ด๋ ์์ฑ์์์ ์ค์ ๋ฉ๋๋ค. - ์๋ฅผ ๋ค์ด,
SLOW("SLOW", "์์")
๋code
๊ฐ"SLOW"
์ด๊ณ ,value
๊ฐ"์์"
์ธ ์ด๊ฑฐํ ์์๋ฅผ ๋ํ๋ ๋๋ค.
์ค์ง jpa๋ง ์๋ ์ปจํฐ๋ฒ ๊ธฐ๋ฅ์ผ๋ก SLOW => ์์์ผ๋ก DB์ ๋ค์ด๊ฐ๊ณ ๋ ์๋ฐ๋ก ๋์ฌ๋ SLOW๋ก ๋์ค๋ ๊ทธ๋ฐ ๋๋?
public enum ChargerType implements CodeValue { SLOW("SLOW", "์์"), AC3("AC3", "AC3์"), DESTINATION("DESTINATION", "๊ธ์"), ETC("ETC", "๊ธฐํ"); private final String code; private final String value; ChargerType(String code, String value) { this.code = code; this.value = value; } @Override public String getCode() { return code; } @Override public String getValue() { return value; } }
-
์ํฐํฐ์์์ ์ฌ์ฉ ์์
@Convert(converter = ChargerTypeConverter.class) @Column(name = "charger_type", nullable = false) private ChargerType chargerType;
- ์ด ์ฝ๋์์๋
chargerType
ํ๋๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์charger_type
์ปฌ๋ผ๊ณผ ๋งคํ๋ฉ๋๋ค. @Convert
์ด๋ ธํ ์ด์ ์ ํตํดChargerTypeConverter
๋ฅผ ์ฌ์ฉํ์ฌChargerType
๊ฐ์ ๋ณํํฉ๋๋ค.
- ์ด ์ฝ๋์์๋
- ์ํฐํฐ -> ๋ฐ์ดํฐ๋ฒ ์ด์ค:
ChargerType
์ด๊ฑฐํ ๊ฐ์ดconvertToDatabaseColumn
๋ฉ์๋๋ฅผ ํตํดString
๊ฐ์ผ๋ก ๋ณํ๋์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด,ChargerType.SLOW
์ ๊ฒฝ์ฐ"SLOW"
๋ก ์ ์ฅ๋ฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค -> ์ํฐํฐ:
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์จ
String
๊ฐ์ดconvertToEntityAttribute
๋ฉ์๋๋ฅผ ํตํดChargerType
์ด๊ฑฐํ ๊ฐ์ผ๋ก ๋ณํ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด,"SLOW"
๊ฐChargerType.SLOW
๋ก ๋ณํ๋ฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์จ
- ์์ธ ์ฒ๋ฆฌ:
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ์ด ๋งค์นญ๋๋
ChargerType
์์๋ฅผ ์ฐพ์ง ๋ชปํ๋ฉดBusinessException
์ด ๋ฐ์ํ์ฌ ์ฒ๋ฆฌ๋ฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ์ด ๋งค์นญ๋๋
- ์ผ๊ด์ฑ ์ ์ง: ์ด๊ฑฐํ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฝ๋๋ก ์ ์ฅํ๊ณ , ์ฝ๋ ๊ฐ์ผ๋ก๋ถํฐ ์ด๊ฑฐํ ๊ฐ์ ๋งคํํ ์ ์๋ ์ผ๊ด๋ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ:
EnumConverter
๋ ๋ชจ๋CodeValue
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ์ด๊ฑฐํ์ ๋ํด ๋ฒ์ฉ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๋ณํ๊ธฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. - ์ ์ฐํ ์์ธ ์ฒ๋ฆฌ: ๋ณํ ์คํจ ์ ์์ธ๋ฅผ ๋ช ํํ๊ฒ ์ ์ํ์ฌ ์ค๋ฅ ์ํฉ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ด ์ฝ๋๋ JPA์์ ์ด๊ฑฐํ ํ์ ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ์ฉํ๋ฉฐ, ์ปค์คํ ๋ณํ๊ธฐ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํฐํฐ ๊ฐ์ ๋ณํ์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
์ฅ์ ์?
์ด ์ฝ๋๋ JPA์์ ์ด๊ฑฐํ(Enum) ํ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๋ํ ๋ ๋ช ๊ฐ์ง ์ค์ํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
EnumConverter
๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๊ฑฐํ ๊ฐ(์:ChargerType.SLOW
)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ ๋ ๋ฌธ์์ด(SLOW
)๋ก ๋ณํํ๊ณ , ๋ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ด๊ฑฐํ ํ์ ์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค.- ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฝ๋ ๊ฐ์ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์ผ๋ฉฐ, ์ด๊ฑฐํ ๊ฐ์ด ๋ณ๊ฒฝ๋๋๋ผ๋ ์ฝ๋์ ๋ณ๊ฒฝ๋ง์ผ๋ก ์ฝ๊ฒ ๋ฐ์ํ ์ ์์ต๋๋ค.
EnumConverter
๋ฅผ ํตํด ๋ณํ ๋ก์ง์ ์ปค์คํฐ๋ง์ด์ฆํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ ๊ฐ์ ํ์์ด๋ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ฅธ ๋ณํ ๋ฐฉ์์ ์ฝ๊ฒ ์กฐ์ ํ ์ ์์ต๋๋ค.- JPA์ ๊ธฐ๋ณธ ๋ณํ๊ธฐ ๋์ ์ปค์คํ ๋ณํ๊ธฐ๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ, ์ํฐํฐ ํ๋์ ๋ํ ์ธ๋ถ์ ์ธ ๋ณํ ๋ก์ง์ ์ ์ฉํ ์ ์์ต๋๋ค.
EnumConverter
๋ ์ ๋ค๋ฆญ ํ์ ์ผ๋ก ๊ตฌํ๋์ด ์์ด,CodeValue
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๋ชจ๋ ์ด๊ฑฐํ์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฝ๋ ์ค๋ณต์ ์ค์ด๊ณ ๋ณํ ๋ก์ง์ ์ผ๊ด๋๊ฒ ์ ์ฉํ ์ ์์ต๋๋ค.- ์๋ฅผ ๋ค์ด, ๋ค๋ฅธ ์ด๊ฑฐํ ํ์
์ ์ถ๊ฐํ ๋๋ ์๋ก์ด ๋ณํ๊ธฐ๋ฅผ ๋ง๋ค์ง ์๊ณ ๊ธฐ์กด
EnumConverter
๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์ด ์ฝ๋ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํฉ๋๋ค.
- ๋ณํ ์ ๋งค์นญ๋๋ ์ด๊ฑฐํ์ด ์์ผ๋ฉด
BusinessException
์ ํตํด ์์ธ๋ฅผ ๋ช ํํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์๋ชป๋ ๋ฐ์ดํฐ๋ ์์์น ๋ชปํ ๊ฐ์ด ๋ค์ด์ค๋ ์ํฉ์ ๋๋นํ ์ ์์ต๋๋ค. CodeValue
์ธํฐํ์ด์ค๋ฅผ ํตํด ๊ฐ ์ด๊ฑฐํ์ดgetCode()
์getValue()
๋ฅผ ๋ฐ๋์ ๊ตฌํํ๋๋ก ๊ฐ์ ํจ์ผ๋ก์จ, ํ์ ์์ ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
@Converter(autoApply = true)
๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋น ๋ณํ๊ธฐ๋ฅผ ์๋์ผ๋ก ์ ์ฉํ์ฌ, ์ํฐํฐ์์ ๋งค๋ฒ@Convert
๋ฅผ ๋ช ์ํ์ง ์์๋ ๋ฉ๋๋ค. ์ด๋ ์ฝ๋์ ๊ฐ๊ฒฐํจ๊ณผ ๊ฐ๋ ์ฑ์ ๋์ฌ์ค๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋๋ ๋ฌธ์์ด ๊ฐ์ด
"SLOW"
์์"S"
๋ก ๋ณ๊ฒฝ๋๋ ์ํฉ์ด ๋ฐ์ํ ๋,EnumConverter
์ ๋ณํ ๋ก์ง๋ง ์์ ํ๋ฉด ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ๋ณ๊ฒฝ์ ์ ์ฐํ๊ฒ ๋์ฒํ ์ ์์ต๋๋ค.
์ด ์ฝ๋์ ์ฃผ์ ์ฅ์ ์ ์ผ๊ด๋ ๋ณํ ๋ก์ง๊ณผ ์ฌ์ฌ์ฉ์ฑ, ์ ์ฐํ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ํ๋ฆฌ์ผ์ด์
๊ฐ์ ๋งคํ์ ์์ ํ๊ณ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค๋ ์ ์
๋๋ค. EnumConverter
๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฐ๊ณผ ์ฝ๋์ ์ด๊ฑฐํ ๊ฐ์ ๋งคํ์ ๋ช
ํํ ์ ์ํจ์ผ๋ก์จ, ์ ์ง๋ณด์์ฑ์ด ๋๊ณ ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ๋ฎ์์ง๋๋ค.
MYBATIS
ํ์ ํธ๋ค๋ฌ๋ผ๋ ํด๋์ค ์ ์, XML์ ๋ฃ์ด๋๋ฉด ์ด๊ฑฐํ ๋ณํํด์ค๋ค๋ ๊ฒ
์ฌ๊ท์ ํ์ ํ์ ์ ์๋ฏธ
<E extends Comparable<E>>
๋ "E
ํ์
์ ๊ฐ์ฒด๊ฐ ์๊ธฐ ์์ (E
)๊ณผ ๋น๊ต ๊ฐ๋ฅํ๋ค"๋ ์๋ฏธ์ด๋ค. ์๋ฅผ ๋ค์ด, String
์ Comparable<String>
์ ๊ตฌํํ๊ณ , Integer
๋ Comparable<Integer>
๋ฅผ ๊ตฌํํ๋ ์์ด๋ค. ์ด๋ฅผ ํตํด ์ปฌ๋ ์
๋ด์ ์์๊ฐ ์๋ก ๋น๊ต ๊ฐ๋ฅํจ์ ๋ณด์ฅํ ์ ์๋ค.
- ์์ ์ฑ๊ณผ ํธ๋ฆฌ์ฑ:
- ์ ๋ค๋ฆญ ๋ฉ์๋๋
ํ์ ์์ ์ฑ
์ ์ ๊ณตํ์ฌ, ๋ฉ์๋ ํธ์ถ ์ ์ปดํ์ผ๋ฌ๊ฐ ํ์ ๊ฒ์ฌ๋ฅผ ํด์ค๋ค. - ํ๋ณํ์ ๋ช ์์ ์ผ๋ก ํ ํ์๊ฐ ์์ด์ ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ๋ ํฅ์๋๋ค.
- ํ๋ณํ ์๋ ์ฌ์ฉ:
- ์ ๋ค๋ฆญ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด, ์ ๋ ฅ ๋งค๊ฐ๋ณ์์ ๋ฐํ๊ฐ์ ํ์ ์ ๋ช ์์ ์ผ๋ก ํ๋ณํํ ํ์๊ฐ ์๋ค.
- ๋ฉ์๋์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ํ์ ์ ๊ฒฐ์ ํ๋ฏ๋ก, ํด๋ผ์ด์ธํธ๊ฐ ๋ถํ์ํ ํ๋ณํ ์์ด ์์ ํ๊ฒ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- ๊ธฐ์กด ๋ฉ์๋์ ๊ฐ์ :
- ๊ธฐ์กด์ ํ๋ณํ์ ํ์๋ก ํ๋ ๋ฉ์๋๋ ์ ๋ค๋ฆญ ๋ฉ์๋๋ก ๋ณ๊ฒฝํ์ฌ ๋ ์์ ํ๊ฒ ๋ง๋ค ์ ์๋ค.
- ๊ธฐ์กด ํด๋ผ์ด์ธํธ ์ฝ๋์ ์ํฅ์ ์ฃผ์ง ์์ผ๋ฉด์๋, ์๋ก์ด ์ฌ์ฉ์์๊ฒ๋ ๋ ํธ๋ฆฌํ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๋ค.
- ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ:
- ์ ๋ค๋ฆญ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ํ ํ์ ์ ๋ํด ํ๋์ ๋ฉ์๋๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์ด ์ฝ๋ ์ค๋ณต์ด ์ค์ด๋ ๋ค.
- ์ ๋ค๋ฆญ ๋ฉ์๋๋ ํ์ ์์ ์ฑ๊ณผ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ๋์ธ๋ค.
์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ฉด ์ปดํ์ผ ์์ ์ ํ์ ์์ ์ฑ์ ๋ณด์ฅ๋ฐ์ ์ ์์ผ๋ฉฐ, ๊ธฐ์กด ์ฝ๋์์ ํธํ์ฑ์ ์ ์งํ๋ฉด์ ๋ ์ ์ฐํ๊ณ ์์ ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
์ถ์ฒ