使用Hibernate JPA的自定义布尔用户类型

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS文件信息收集工具-LinkFinder

0x00 前言 我们在渗透测试的之前&#xff0c;信息收集是必要的步骤&#xff0c;而JS文件中往往会暴露出很多的信息&#xff0c;比如一些注释的中铭感信息&#xff0c;内网ip地址泄露等等&#xff0c;还会有一些绝对路径或者相对路径的url&#xff0c;而这些url中很有可能就存在…

extjs中Store和grid的刷新问题

问题1&#xff1a;Store.load() 和Store.setproxy()区别 问题2:修改后的Grid 更新&#xff1a; Store.reload() 问题3&#xff0c;store删除后刷新会出问题 Store移除一行&#xff1a;Store.removeAt(Number index) 从数据集中删除指定索引位置的记录     或者Store.reload…

linux将txt文件复制为bak,Linux命令:cp (copy)复制文件或目录

复制文件&#xff0c;只有源文件较目的文件的修改时间新时&#xff0c;才复制文件cp -u -v file1 file2.将文件file1复制成文件file2cp file1 file2.采用交互方式将文件file1复制成文件file2cp -i file1 file2.将文件file1复制成file2&#xff0c;因为目的文件已经存在&#xf…

【APICloud系列|28】苹果开发者账号应该如何续费?

本次更新时间:2020/7/13 登录苹果开发者账号,一般还有1个月到期官方会给你发邮件,不懂英文的可以使用谷歌翻译功能。 目前的后台提醒是这样的,我给你翻译一下 这个如果没有到期,使用Apple Developer这个应用程序进行充值缴费。 对应地址:https://developer.apple.com/i…

linux中第一个进程的形成,Linux进程管理

1.进程基本概述定义&#xff1a;进程是已经启动的可执行程序的运行中实例。/proc目录下以数字为名的目录&#xff0c;每一个目录代表一个进程&#xff0c;保留着进程的属性信息&#xff0c;每一个进程的PID是唯一的&#xff0c;就算进程退出了&#xff0c;其他进程也不会占用其…

XX(北京)科技股份公司为啥需要购置服务器?

其实老板只是要一个量化的标准,只是没人能讲明白,我简单陈述一下: 公司现在只有一台阿里的1核两G的1M带宽服务器40G,属于低配,买了3年的,打了三折花了2800元左右,为啥需要额外购置服务器呢? 目前服务器上有,一个后台管理系统,一个小程序,一个APP,一个网站,目前就…

[BZOJ 1588] [HNOI 2002] 营业额统计

1588: [HNOI2002]营业额统计 Time Limit: 5 SecMemory Limit: 162 MBDescription 营业额统计 Tiger最近被公司升任为营业部经理&#xff0c;他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本&#xff0c;账本上记录了公司成立以…

Python----socket编程

socket 一、socket是什么&#xff1f; socket 通常也称为“套接字”&#xff0c;用于描述 IP 地址和端口&#xff0c;是一个通讯链的句柄。应用程序通常通过 “套接字”向网络发出请求或者应答网络请求。说白了&#xff0c;就是一种通讯机制。它类似于公司的电话客服部门&…

怎样编写测试类测试分支_测试技巧–不编写测试

怎样编写测试类测试分支对此没有太多疑问&#xff0c;测试代码的方式是一个有争议的问题。 不同的测试技术由于各种原因&#xff08;包括企业文化&#xff0c;经验和总体心理观点&#xff09;而受到不同开发人员的青睐。 例如&#xff0c;您可能更喜欢编写经典的单元测试&#…

linux文件权限umask,linux系统中UMASK权限的用法讲解

原标题&#xff1a;linux系统中UMASK权限的用法讲解umask一般是用在你初始创建一个目录或者文件的时候赋予他们的权限。这里要说明两点&#xff1a;1、针对目录来说x权限代表可以进入该目录&#xff0c;所以说对于这个权限初始赋值是没什么问题的;2、针对文件的x的权限代表执行…

怎么样才算高级java工程师

高级水平&#xff1a; 1.能对需求进行架构设计&#xff0c;选择框架以适应最合适的业务&#xff0c;作为某个项目的领导&#xff0c;带领团队完成项目。 2.有自己的开源项目&#xff0c;可以写出自己的组件&#xff0c;对开源的框架能够进行二次编写&#xff0c;java核心技术有…

Win32+API学习笔记:创建基本的窗口控件

创建一个标签 CreateWindowEx(0, "static", "姓名&#xff1a;", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 12, // xpos …

Autorize插件的使用方法

在Proxy或者Repeater有Request请求包后&#xff0c;要ctrlA全选&#xff0c;然后再右键发送到Autorize插件中&#xff1a; 如果只是像这样空白的发送是不会发送过去的&#xff1a;

粉丝提问:求问大神您会查exif吗?

无需下载安装任何软件,直接上传图片即可查看EXIF。支持JPEG、TIFF、CR2、NEF、XMP等多种图片格式破解Canon、

linux和windows的分区区别,Linux分区与Windows分区的区别

打开开始-管理工具-计算机管理&#xff0c;如下图所示&#xff1a;在Windows系统中&#xff0c;计算机的分区是用磁盘0&#xff0c;磁盘1&#xff0c;磁盘2&#xff0c;磁盘3来表示多块硬盘的&#xff0c;比如磁盘0表示第一块硬盘&#xff0c;磁盘2表示第二块硬盘&#xff0c;以…

《构建之法》--阅读(第13章-第17章)

第13章 软件测试 1.名词解释 Bug &#xff1a;软件的缺陷 Test Case &#xff1a;测试用例。测试用例描述了一个完整的测试过程&#xff0c;包括测试环境、输入、期望的结果等 Test Suite &#xff1a;测试用例集。即一组相关的测试用例 2.Bug解释与实例 <1>、Bug可以分解…

一个用于伪造IP地址进行爆破的BurpSuite插件:BurpFakeIP

BurpFakeIP介绍 一个用于伪造ip地址进行爆破的BurpSuite插件&#xff0c;burpsuite伪造ip可用于突破waf及进行安全规则绕过等场景&#xff1b;昨天我们分享了《BurpSuite IP代理扩展&#xff0c;使用AWS API网关动态更改请求&#xff1a;IPRotate_Burp_Extension》有同学也发现…

学习Spring-Cloud –编写微服务

继续我的Spring-Cloud学习历程&#xff0c; 之前我已经介绍了如何编写典型的基于Spring-Cloud和Netflix OSS的微服务环境的基础架构组件–在此特定实例中&#xff0c;有两个关键组件&#xff0c;用于注册和发现服务的Eureka和Spring Cloud用于维护服务配置集中式配置库的配置。…

CSS页面DEMO

层叠样式表(英文全称&#xff1a;Cascading Style Sheets)是一种用来表现HTML&#xff08;标准通用标记语言的一个应用&#xff09;或XML&#xff08;标准通用标记语言的一个子集&#xff09;等文件样式的计算机语言。CSS不仅可以静态地修饰网页&#xff0c;还可以配合各种脚本…

linux内核配置usb虚拟串口,Linux USB虚拟串口设备

Linux内核中usb设备侧驱动程序分成3个层次&#xff1a;UDC驱动程序、Gadget API和Gadget驱动程序。UDC驱动程序(USB控制器)直接访问硬件&#xff0c;控制USB设备和主机间的底层通信&#xff0c;向上层提供与硬件相关操作的回调函数。Gadget API是UDC驱动程序回调函数的简单包装…