Hibernate的强大用过的童鞋肯定会知道的,通过OR映射我们可以很方便的实现数据库操作,Hibernate对我们一些类型的映射都提供了很好的支持,但是显然也有不给力的地方,比如简单的注册,一个人可能有好多邮箱,对于这个问题怎么做呢?有人说简单,可以另外开一张表,恩,很不错,确实可以,可是这样有时候可能小题大作了。也有人说,直接将邮箱拼接成字符串然后在存储,这个想法也很好,但在我们读出来的时候就要再进行一次解析操作,将EMAIL还原,这些都要求我们编程人员自己完成。那么Hibernate有没有提供什么好的支持呢?回答是肯定的,Hibernate给我们提供了一个UserType接口,通过UserType我们可以对一些常见的类型进行封转,转变成具有个性的类型。下面我们就来体验一下吧:
首先我么创建一个自定义类型的类,让他实现UserType接口:
/**
* @author :LYL
*@date:2011-4-26,下午08:39:42
*/
package com.lyl.hibernate.mytype;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import com.opensymphony.oscache.util.StringUtil;
public class ArrayType implements UserType{
private static final char Spliter=';';
/**
* 自定义类型的完全复制方法,构造返回对象
* 1. 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前
* deepCopy方法被调用,它将根据自定义数据对象构造一个完全拷贝,把拷贝返还给客户使用。
* 2.此时我们就得到了自定义数据对象的两个版本
* 原始版本由hibernate维护,用作脏数据检查依据,复制版本由用户使用,hibernate将在
* 脏数据检查过程中比较这两个版本的数据。
*
*
*/
@Override
public Object deepCopy(Object value) throws HibernateException {
List source=(List)value;
List target=new ArrayList();
target.addAll(source);
return target;
}
/**
* 自定义数据类型比对方法
* 用作脏数据检查,X,Y为两个副本
*/
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x==y) {
return true;
}
if(x!=null&&y!=null){
List xList=(List)x;
List ylList=(List)y;
if (xList.size()!=ylList.size()) {
return false;
}
for(int i=0;i<xList.size();i++){
String s1=(String)xList.get(i);
String s2=(String)ylList.get(i);
if (!s1.equals(s2)) {
return false;
}
}
return true;
}
return false;
}
/**
* 返回给定类型的hashCode
*/
@Override
public int hashCode(Object value) throws HibernateException {
return value.hashCode();
}
/**
* 表示本类型实例是否可变
*/
@Override
public boolean isMutable() {
// TODO Auto-generated method stub
return false;
}
/**
* 读取数据转换为自定义类型返回
* names包含了自定义类型的映射字段名称
*/
@SuppressWarnings("deprecation")
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
//取得字段名称并查询
String value=(String)Hibernate.STRING.nullSafeGet(rs, names[0]);
if (value!=null) {
return parse(value);
}else {
return null;
}
}
/**
* 数据保存时被调用
*/
@Override
public void nullSafeSet(PreparedStatement ps, Object value, int index)
throws HibernateException, SQLException {
if(value!=null){
String str=combain((List)value);
//保存数据
Hibernate.STRING.nullSafeSet(ps, str,index);
}else {
//空值就直接保存了
Hibernate.STRING.nullSafeSet(ps,value.toString(),index);
}
}
/**
* 将数据解析为LIST返回
* @param value
* @return
*/
private List parse(String value){
List list=StringUtil.split(value, Spliter);
return list;
}
private String combain(List list){
StringBuffer sb=new StringBuffer();
for(int i=0;i<list.size()-1;i++){
sb.append(list.get(i)).append(Spliter);
}
sb.append(list.get(list.size()-1));
return sb.toString();
}
/**
* 修改类型对应的java类型
* 我们这边使用LIST类型
*/
@Override
public Class returnedClass() {
return List.class;
}
/**
* 修改类型对应的SQL类型
* 使用VARCHAR
*/
@Override
public int[] sqlTypes() {
return new int[]{Types.VARCHAR};
}
@Override
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
return null;
}
/**
* 不知干嘛用的
*/
@Override
public Object assemble(Serializable arg0, Object arg1)
throws HibernateException {
return null;
}
@Override
public Serializable disassemble(Object arg0) throws HibernateException {
return null;
}
}
然后我们在配置OR映射文件时,指定一下自己的类型:
<property name="emails" column="emails" type="com.lyl.hibernate.mytype.ArrayType"/>
之后我们运行起来,给EMAILS传LIST类型的即可保存,读出来也是LIST类型,是不是很方便?
分享到:
相关推荐
11.2.2 用UserType映射枚举类型 11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类...
fileContent字段映射为Spring所提供的BlobByteArrayType类型,BlobByteArrayType是用户自定义的数据类型,它实现了Hibernate 的org.hibernate.usertype.UserType接口。BlobByteArrayType使用从sessionFactory获取...
8.3.1 定制SQL名称和数据类型 8.3.2 确保数据一致性 8.3.3 添加领域约束和列约束 8.3.4 表级约束 8.3.5 数据库约束 8.3.6 创建索引 8.3.7 添加辅助的DDL 8.4 小结 第三部分 会话...
11.2.2 用UserType映射枚举类型 11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类...
11.2.2 用UserType映射枚举类型 11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类...
11.2.2 用UserType映射枚举类型 11.2.3 实现CompositeUserType接口 11.2.4 运行本节范例程序 11.3 操纵Blob和Clob类型数据 11.4 小结 11.5 思考题 第12章 映射继承关系 12.1 继承关系树的每个具体类...
VC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zip
商业编程-源码-VC开发工具使用技巧源代码 usertype.zip
在VS中配置CUDA时,本身是不识别CUDA关键字的,关键字不能高亮。早期的CUDA版本在SDK中提供了usertype.dat,其中包含CUDA的关键字,但后来的CUDA没有这个文件,网上找了好久,现在贴出来亲测可用~
1. 创建或编辑usertype.dat文件(此文件在VS安装目录下的Common7\IDE下面,比如我的就在D:\Program Files\Microsoft Visual Studio 8\Common7\IDE\usertype.dat),添加如下的关键字列表,每个单词占一行,如果你想...
HLSL的关键字,放在vs的IDE文件下,以在vs中高亮HLSL的关键字
- UserType - PasswordResetter - Profile(Foreign)[nulluble] - Company(Foreign)[nullable] - Role(Foreign) 订阅内容 - Id - Name - Email - Status 工作 - Id - Organisation - Location - Grade - ...
初始化工程,支持基本数据格式校验 mark 2018.5.21 一口气写完的,还没有怎么测试,先提交上来再说 remark:最近刚到新公司接收项目,发现这里校验参数的没有做,纯硬编码的起判参数的值,主要是为了处理前端传的...
1.1. Part 1 - The first Hibernate Application ................................................................ 1 1.1.1. Setup .............................................................................
Hibernate测试存储和检索 SmartMeter 数据。 对于Hibernate部分,我在这里得到了灵感: : jodatime 和 hybernate .... 没那么容易。 需要使用这个:添加到 build.gradle compile 'org.jadira.usertype:usertype.joda...
React本机哇直播流实时流媒体组件是React Native Jitsi( )之上的自定义包装器安装$ npm install react-native-wow-rn-live-stream --save用法import { LiveStreamComp } from 'react-native-wow-rn-live-stream' ;...
" "Spoilage "损坏商品表 " 自定义数据类型(custem) "字段名 "数据类型 "长度 "主/外键 "字段值约 "对应中文名 " " " " " "束 " " "gcxCaption"Varchar "100 " "Not null "实体名称 " "gxcID "Int "4 "P "Not null ...
" "Spoilage "损坏商品表 " 自定义数据类型(custem) "字段名 "数据类型 "长度 "主/外键 "字段值约 "对应中文名 " " " " " "束 " " "gcxCaption"Varchar "100 " "Not null "实体名称 " "gxcID "Int "4 "P "Not null ...
V5.1之后的修改(2006-01-20 至 2007-1-27) ----------------------------------------------------------------------------- ...1、修正UserType=102时利润就不对的问题 2008-04-14 V7.18_4: 1、增加一品多码功能...