ANSI SQL 1999标准引入了BOOLEAN数据类型(尽管遗憾的是仅作为可选功能)。 但是到目前为止,大多数主要的数据库系统仍未实现它。 结果,布尔列以各种方式实现。 例如,包含“ Y”或“ N”的CHAR列,或使用BIT列。 随后,JPA无法提供将实体的布尔字段映射到数据库列的标准化方法。

Hibernate为使用包含“ Y”或“ N”字符的CHAR(1)列的布尔实现提供了一个自定义YesNoType。 但是对于其他实践,您基本上必须提供自己的解决方案。 幸运的是,Hibernate提供了创建自己的自定义UserType的可能性。 在此博客条目中,我将提供一个这样的自定义布尔UserType的示例。

最近,我遇到了一个荷兰传统数据库架构,其中“ Y”(表示“是”)和“ N”(表示“否”)分别由“ J”(“ ja”)和“ N”(“ nee”)表示, 分别。 排除使用Hibernate的YesNoType。 更复杂的是,其中一些列使用CHAR(1),另一些使用带有填充空间的CHAR(2)–不要问为什么!

因此,我最终编写了一个自定义UserType,使我基本上可以转换以下内容…

起点

@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;// …
}

进入...

理想情况

@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;// …
}

编码自定义类型被证明是相当简单的。 我只需要实现org.hibernate.usertype.UserType接口。 要处理变化的列长度,需要添加“ length”参数,这需要实现第二个接口org.hibernate.usertype.ParameterizedType。

下面给出的是我所做的最终结果。

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

使用Hibernate JPA的自定义布尔用户类型相关推荐

  1. Hibernate JPA 缓存配置

    Hibernate JPA 缓存配置 1.一级缓存 一级缓存指的是 EntityManager 级的缓存,对于这样的缓存几乎是一直存在的,也就是说只要用户进行JPA的操作,那么就永远都会存在有一级缓存 ...

  2. Spring Hibernate JPA 联表查询 复杂查询

    (转自:http://www.cnblogs.com/jiangxiaoyaoblog/p/5635152.html) 今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的 ...

  3. Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释...

    转自Hibernate JPA中@Transient.@JsonIgnoreProperties.@JsonIgnore.@JsonFormat.@JsonSerialize等注解解释 1.@Tran ...

  4. jpa vue管理系统_如何通过利用Java流获取类型安全和直观的Hibernate / JPA查询

    jpa vue管理系统 大部分Java数据库应用程序都在使用Hibernate / JPA来弥合Java和SQL之间的鸿沟. 直到最近,我们还被迫将Java和JPQL混合使用,或者使用复杂的命令式标准 ...

  5. Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统

    Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统 Demo 相关阅读: 1.Spring MVC+Hibernate JPA+ Bootstrap 搭建的博 ...

  6. Hibernate JPA

    2019独角兽企业重金招聘Python工程师标准>>> 1.JPA概述 2.JPA中的第一个程序 3.JPA中常用的注解(重点) 4.JPA中的CRUD 5.JPA中的多表映射的配置 ...

  7. R语言使用dplyr聚合统计分组数据、ggplot2可视化分组线图、使用geom_line函数自定义设置线条类型、粗细、颜色(Change line types + colors by groups)

    R语言ggplot2可视化分组线图.使用geom_line函数自定义设置线条类型.宽度(粗细.).颜色(Change line types by groups.Change line types + ...

  8. 【Android 逆向】Android 系统中文件的用户和分组 ( 文件所有者与分组 | /sdcard/ 的文件分组 | /data/ 目录分析 | 用户类型 )

    文章目录 一.文件所有者与分组 二./sdcard/ 的文件分组 三./data/ 目录分析 四.用户类型 一.文件所有者与分组 使用 ls -l 命令 , 查看 Android 系统根目录 , 下图 ...

  9. shell脚本第一篇——自定义创建用户和批量创建用户

    shell脚本第一篇--自定义创建用户和批量创建用户 1.用shell脚本建立Linux用户 # vim /root/user.sh #!/bin/bash #通过脚本自定义创建用户 read -p ...

最新文章

  1. The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the argument
  2. Office2010启动慢的解决方法
  3. 【spark】SparkSession的API
  4. linux 支持的字体命令,Linux设置显示中文和字体
  5. 什么是java的元数据_学习大数据,为什么要先学习Java?
  6. mysql如何大矩阵_如何打印矩阵
  7. Oracle 11gR2 RAC OCR和votingdisk故障恢复案例
  8. 卡巴世界,卡巴斯基,卡巴斯基key,卡巴斯基激活码,软件下载,每天更新
  9. 【无标题】java班级管理系统
  10. 2014全国计算机二级visual foxpro,全国计算机等级考试二级_VisualFoxPro语言程序设计_全.pdf...
  11. mysql中rand的用法_MySQL RAND()用法及代码示例
  12. python:实现balanced parentheses平衡括号表达式算法(附完整源码)
  13. 医疗检查报告和影像资料,扫二维码就能查看!
  14. Web3 | DID赛道之 Galxe(原 Project Galaxy)
  15. Java工程师必备软件大合集,手把手教你如何下载和安装
  16. 知之者不如好之者 好之者不如乐之者
  17. 【2017年第3期】“云治理”设想
  18. 重新学习Python--天勤量化
  19. 用什么软件抓cd音轨音质最好_什么是音乐制作以及工作流程?
  20. Web指纹识别器系列2:他山之石,可以攻玉

热门文章

  1. jquery动画与事件案例
  2. 2017蓝桥杯省赛---java---B---10(k倍区间)
  3. 2018蓝桥杯省赛---java---B---7(螺旋折线)
  4. HBase的hbase shell 详解
  5. 区间数多属性决策matlab,区间数多属性决策的改进理想解法
  6. jvm内存分配与收回策略
  7. 一文搞懂ThreadLocal及相关的内存泄露问题
  8. 如何导出数据到Excel表格
  9. 混合多云架构_使用混合多云每个人都应避免的3个陷阱(第4部分)
  10. ljc.framework_Java 9模块系统(拼图)@ LJC的HackTheTower