使用Hibernate JPA的自定义布尔用户类型
ANSI SQL 1999標(biāo)準(zhǔn)引入了BOOLEAN數(shù)據(jù)類型(盡管遺憾的是僅作為可選功能)。 但是到目前為止,大多數(shù)主要的數(shù)據(jù)庫(kù)系統(tǒng)仍未實(shí)現(xiàn)它。 結(jié)果,布爾列以各種方式實(shí)現(xiàn)。 例如,包含“ Y”或“ N”的CHAR列,或使用BIT列。 隨后,JPA無(wú)法提供將實(shí)體的布爾字段映射到數(shù)據(jù)庫(kù)列的標(biāo)準(zhǔn)化方法。
Hibernate為使用包含“ Y”或“ N”字符的CHAR(1)列的布爾實(shí)現(xiàn)提供了一個(gè)自定義YesNoType。 但是對(duì)于其他實(shí)踐,您基本上必須提供自己的解決方案。 幸運(yùn)的是,Hibernate提供了創(chuàng)建自己的自定義UserType的可能性。 在此博客條目中,我將提供一個(gè)這樣的自定義布爾UserType的示例。
最近,我遇到了一個(gè)荷蘭傳統(tǒng)數(shù)據(jù)庫(kù)架構(gòu),其中“ Y”(表示“是”)和“ N”(表示“否”)分別由“ J”(“ ja”)和“ N”(“ nee”)表示, 分別。 排除使用Hibernate的YesNoType。 更復(fù)雜的是,其中一些列使用CHAR(1),另一些使用帶有填充空間的CHAR(2)–不要問(wèn)為什么!
因此,我最終編寫了一個(gè)自定義UserType,使我基本上可以轉(zhuǎn)換以下內(nèi)容…
起點(diǎn)
@Entity @Table(name = "FOO_BAR") public class FooBar implements Serializable {@Column(name = "FOO_ INDICATOR")private String fooIndicator;@Column(name = "BAR_ INDICATOR", length = 2)private String barIndicator;// … }進(jìn)入...
理想情況
@Entity @Table(name = "FOO_BAR") @TypeDefs({@TypeDef(name = JaNeeType.NAME, typeClass = JaNeeType.class) }) public class FooBar implements Serializable {@Column(name = "FOO_INDICATOR)@Type(type = JaNeeType.NAME)private Boolean fooIndicator;@Column(name = "BAR_INDICATOR", length = 2)@Type(type = JaNeeType.NAME, parameters = { @Parameter(name = "length", value = "2") })@Type(type = JaNeeType.NAME)private Boolean barIndicator;// … }編碼自定義類型被證明是相當(dāng)簡(jiǎn)單的。 我只需要實(shí)現(xiàn)org.hibernate.usertype.UserType接口。 要處理變化的列長(zhǎng)度,需要添加“ length”參數(shù),這需要實(shí)現(xiàn)第二個(gè)接口org.hibernate.usertype.ParameterizedType。
下面給出的是我所做的最終結(jié)果。
JaNeeType
package it.jdev.examples.persistence.hibernate;import java.io.Serializable; import java.lang.invoke.MethodHandles; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.Properties;import org.apache.commons.lang3.StringUtils; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.usertype.ParameterizedType; import org.hibernate.usertype.UserType; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** A type that maps between {@link java.sql.Types#VARCHAR CHAR(1) or CHAR(2)} and {@link Boolean} (using "J " and "N ").* <p>* Optionally, a parameter "length" can be set that will result in right-padding with spaces up to the* specified length.*/ public class JaNeeType implements UserType, ParameterizedType {public static final String NAME = "ja_nee";private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());private int length = 1;@Overridepublic int[] sqlTypes() {return new int[] { Types.VARCHAR };}@SuppressWarnings("rawtypes")@Overridepublic Class returnedClass() {return Boolean.class;}@Overridepublic boolean equals(final Object x, final Object y) throws HibernateException {if (x == null || y == null) {return false;} else {return x.equals(y);}}@Overridepublic int hashCode(final Object x) throws HibernateException {assert (x != null);return x.hashCode();}@Overridepublic Object nullSafeGet(final ResultSet rs, final String[] names, final SessionImplementor session, final Object owner) throws HibernateException, SQLException {final String s = rs.getString(names[0]);if (StringUtils.isBlank(s)) {return false;}if ("J".equalsIgnoreCase(s.trim())) {return Boolean.TRUE;}return Boolean.FALSE;}@Overridepublic void nullSafeSet(final PreparedStatement st, final Object value, final int index, final SessionImplementor session) throws HibernateException, SQLException {String s = Boolean.TRUE.equals(value) ? "J" : "N";if (this.length > 1) {s = StringUtils.rightPad(s, this.length);}st.setString(index, s);}@Overridepublic Object deepCopy(final Object value) throws HibernateException {return value;}@Overridepublic boolean isMutable() {return true;}@Overridepublic Serializable disassemble(final Object value) throws HibernateException {return (Serializable) value;}@Overridepublic Object assemble(final Serializable cached, final Object owner) throws HibernateException {return cached;}@Overridepublic Object replace(final Object original, final Object target, final Object owner) throws HibernateException {return original;}@Overridepublic void setParameterValues(final Properties parameters) {if (parameters != null && !parameters.isEmpty()) {final String lengthString = parameters.getProperty("length");try {if (StringUtils.isNotBlank(lengthString)) {this.length = Integer.parseInt(lengthString);}} catch (final NumberFormatException e) {LOGGER.error("Error parsing int " + lengthString, e);}}}}翻譯自: https://www.javacodegeeks.com/2015/06/custom-boolean-user-type-with-hibernate-jpa.html
總結(jié)
以上是生活随笔為你收集整理的使用Hibernate JPA的自定义布尔用户类型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 云盾ddos全网攻防态势(云盾ddos全
- 下一篇: 建安七子顺口溜怎么读(建安七子是指哪七个