Hibernate 식별 데이터베이스 특유 필드 실례 상세 설명
선언:
Hibernate 는 대부분의 상용 데이터베이스 데이터 형식 에 내장 지원 을 제 공 했 지만 일부 데이터베이스 의 전속 필드 에 대한 지원 이 부족 합 니 다.이런 특수 데이터 유형 은 흔히 일반적인 데이터 유형 보다 더 좋 은 데이터 표 현 력 을 제공 하고 우리 의 업무 장면 에 더욱 부합된다.예 를 들 어 PostgreSQL 의 Interval 형식 은 한 시간 대의 데 이 터 를 편리 하 게 저장 할 수 있 습 니 다.본 고 는 Interval 형식 지원 을 추가 하 는 것 을 예 로 들 어 Hibernate 에 특유 의 데이터 형식 지원 을 추가 하 는 방법 을 설명 한다.
Hibernate 는 풍부 한 데이터 형식 지원 을 제공 하지만 일부 데이터베이스 전용 데이터 형식 에 대한 지원 은 한계 가 있 습 니 다.예 를 들 어 PostgreSQL 의 Interval 형식 은'시간 대'데 이 터 를 저장 하 는 데 매우 편리 하 다.
개발 과정 에서 우 리 는 Interval 유형 을 자바 8 의 Duration 유형 으로 비 추 기 를 기대한다.그러나 Hibernate 의 기본 Duration 형식 에 대한 맵 은 데이터베이스 에 직접 비 치 는 BigInt 형식 으로 나 초 값 을 직접 저장 합 니 다.분명히 Interval 형식 을 직접 지원 하지 않 는 데이터 베 이 스 는 비교적 적합 하지만 우 리 는 데이터 베 이 스 를 직접 반영 하 는 Interval 유형 을 기대 합 니 다.
이 를 위해 서 는 두 가지 데이터 형식(자바 세계 의 Duration 과 Db 세계 의 Interval)에 대한 Hibernate 의 매 핑 관 계 를 조정 해 야 합 니 다.
다행히도 하 이 버 네 이 트 는 데이터 형식의 매 핑 을 실현 할 수 있 는 매우 편리 한 방법 을 제공 했다.
이 를 위해 서 는 org.hibenate.usertype.User Type 인 터 페 이 스 를 실현 하 는 클래스 가 필요 합 니 다.
Hibernate 의 사용자 정의 형식(UserType)
User Type 은 Hibernate 가 제공 하 는 사용자 정의 데이터 형식의 인터페이스 입 니 다.모든 사용자 정의 데 이 터 는 이 인 터 페 이 스 를 실현 하거나 org.hibenate.usertype 에서 정의 하 는 인터페이스 에서 적당 한 인 터 페 이 스 를 선택해 야 합 니 다.
우리 의 장면 이 비교적 간단 하 다 는 것 을 감안 하여 User Type 을 직접 실현 하면 수 요 를 만족 시 킬 수 있다.이 인 터 페 이 스 는 다음 과 같은 방법 을 제공 합 니 다.
assemble(Serializable cached, Object owner)
직렬 화 에서 대상 을 재 구축 하 다.
deepCopy(Object value)
깊이 던 전 을 되 돌려 줍 니 다.
disassemble(Object value)
대상 의 직렬 화 데 이 터 를 변환 합 니 다.
equals(Object x, Object y)
두 맵 의 데이터 가 같 는 지 되 돌려 줍 니 다.
hashCode(Object x)
대상 의 해시 가 져 오기.
isMutable()
대상 이 가 변 형식 인지 되 돌려 줍 니 다.
nullSafeGet(ResultSet rs, String[] names, Object owner)
데이터베이스 형식의 데이터 에서 대응 하 는 자바 대상 을 되 돌려 줍 니 다.핵심 실현 방법
nullSafeSet(PreparedStatement st, Object value, int index)
자바 대상 에서 대응 하 는 데이터베이스 형식의 데 이 터 를 되 돌려 줍 니 다.핵심 실현 방법
replace(Object original, Object target, Object owner)
합병 기간 에 실체의 목표 값(target)을 원시 값(original)으로 대체 합 니 다.
returnedClass()
null SafeGet 이 되 돌아 오 는 클래스 입 니 다.
sqlTypes()
대응 하 는 데이터베이스 형식 을 되 돌려 줍 니 다.
실례
package framework.postgresql;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import org.postgresql.util.PGInterval;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.time.Duration;
/**
* PostgreSql Inteval java.time.Duration
* 1 (30 )
* <p>
* :
*
* \@TypeDef(name="interval", typeClass = IntervalType.class)
* :
* \@Type(type = "interval")
* <p>
* http://stackoverflow.com/questions/1945615/how-to-map-the-type-interval-in-hibernate/6139581#6139581
*
* @version 1.0
* @since 1.0
*/
public class IntervalType implements UserType {
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public boolean equals(Object arg0, Object arg1) throws HibernateException {
return arg0 != null && arg1 != null && arg0.equals(arg1) || arg0 == null && arg1 == null;
}
public int hashCode(Object object) throws HibernateException {
return object.hashCode();
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, SharedSessionContractImplementor sessionImplementor, Object o) throws HibernateException, SQLException {
String interval = resultSet.getString(names[0]);
if (resultSet.wasNull() || interval == null) {
return null;
}
PGInterval pgInterval = new PGInterval(interval);
return getDuration(pgInterval);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor sessionImplementor) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.OTHER);
} else {
//this http://postgresql.1045698.n5.nabble.com/Inserting-Information-in-PostgreSQL-interval-td2175203.html#a2175205
Duration duration = (Duration) value;
st.setObject(index, getInterval(duration), Types.OTHER);
}
}
public static Duration getDuration(PGInterval pgInterval) {
return Duration.ofSeconds(pgInterval.getDays() * 24 * 3600 +
pgInterval.getHours() * 3600 +
pgInterval.getMinutes() * 60 +
(int) pgInterval.getSeconds());
}
private static PGInterval getInterval(Duration value) {
long seconds = value.getSeconds();
int days = (int) (seconds / (24 * 3600));
seconds -= days * 24 * 3600;
int hours = (int) (seconds / 3600);
seconds -= hours * 3600;
int minutes = (int) (seconds / 60);
seconds -= minutes * 60;
seconds = Math.abs(seconds);
return new PGInterval(0, 0, days, hours, minutes, seconds);
}
public boolean isMutable() {
return false;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public Class returnedClass() {
return Duration.class;
}
public int[] sqlTypes() {
return new int[]{Types.OTHER};
}
}
사용자 정의 형식 사용이로써 우 리 는 자신의 데이터 형식 을 정의 했다.히 버 네 이 트 는 아직 어떻게 사용 해 야 할 지 모 르 겠 어 요.이 를 위해 서 는 Entity 에서 TypeDef 주 해 를 사용 하고 속성 적 으로 Type 주 해 를 사용 해 야 합 니 다.
예 를 들 면:
...
@Entity
@TypeDef(name = "interval", typeClass = IntervalType.class)
public class PaperStatis implements Serializable {
...
@Column(name = "avg_duration")
@Type(type = "interval")
public Duration getAvgDuration() {
return this.avgDuration;
}
...
}
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[JPA] 단방향 연관관계테이블과 컬럼은 결국 엔티티와 필드와 그대로 매핑하기 때문에 매핑방법만 알고 있다면 어렵지 않지만, DB와 JPA는 테이블간의 관계를 표현하는 패러다임에서 큰 차이가 있기 때문에 나 역시 JPA를 처음 접하고 이 부...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.