반응형
MySQL이나 MariaDB에서 inet_aton/inet_ntoa 함수를 사용하면 문자열로 된 IP 주소를 정수로 저장할 수 있어 저장 용량을 줄이는데 도움이 된다. JPA를 사용하면 AttributeConverter를 사용해서 유사한 변환을 처리할 수 있다.
inet_aton과 inet_ntoa 구현
먼저 다음은 문자열과 정수 간 변환을 처리하는 코드이다.
object Inets {
const val p3_256 = 256L * 256L * 256L
const val p2_256 = 256L * 256L
fun aton(ip: String?): Long? {
if (ip == null) return null
val vals: List<Int> = ip.split(".").filter { it.isNotEmpty() }.map { Integer.parseInt(it) }
if (vals.isEmpty()) return null
if (vals.size == 1) return vals[0].toLong()
if (vals.size == 2) return vals[0] * p3_256 + vals[1]
if (vals.size == 3) return vals[0] * p3_256 + vals[1] * p2_256 + vals[2]
else return vals[0] * p3_256 + vals[1] * p2_256 + vals[2] * 256L + vals[3]
}
fun ntoa(num: Long?): String? {
if (num == null) return null
val d = num % 256
val c = num / 256 % 256
val b = num / (p2_256) % 256
val a = num / (p3_256) % 256
return "$a.$b.$c.$d"
}
}
MySQL의 inet_aton()에 맞춰 구현했다. 예를 들어 inet_aton()은 "1.1"을 "1.0.0.1"과 동일한 값으로 변환한다. 또 "1.1.1"은 "1.1.0.1"과 같게 변환하고 "1"은 "0.0.0.1"과 같게 변환한다. 이 규칙에 맞게 Inets.aton()을 구현했다.
JPA 컨버터
다음은 Inets를 이용해서 구현한 JPA 컨버터이다.
import javax.persistence.AttributeConverter
import javax.persistence.Converter
@Converter
class InetConverter : AttributeConverter<String, Long> {
override fun convertToDatabaseColumn(ip: String?): Long? {
return Inets.aton(ip)
}
override fun convertToEntityAttribute(num: Long?): String? {
return Inets.ntoa(num)
}
}
사용
다음은 InetConverter를 사용한 코드 예이다.
@Convert(converter = InetConverter::class)
@Column(name = "reg_ip")
val ip: String?