hibernate之自定义数据类型
Posted 帅性而为1号
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate之自定义数据类型相关的知识,希望对你有一定的参考价值。
简介
Hibernate的强大用过的童鞋肯定会知道的,通过OR映射我们可以很方便的实现数据库操作,Hibernate对我们一些类型的映射都提供了很好的支持,但是显然也有不给力的地方,比如简单的注册,一个人可能有好多邮箱,对于这个问题怎么做呢?有人说简单,可以另外开一张表,恩,很不错,确实可以,可是这样有时候可能小题大作了。也有人说,直接将邮箱拼接成字符串然后在存储,这个想法也很好,但在我们读出来的时候就要再进行一次解析操作,将EMAIL还原,这些都要求我们编程人员自己完成。那么Hibernate有没有提供什么好的支持呢?回答是肯定的,Hibernate给我们提供了一个UserType接口,通过UserType我们可以对一些常见的类型进行封转,转变成具有个性的类型。实现UserType的源码:
package com.zhushuai.hibernate;
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;
public class EmailType 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 mail_str=(String)Hibernate.STRING.nullSafeGet(rs,names[0]);
List temp=new ArrayList<String>();
if(mail_str==null)
return null;
else
String[] strs=mail_str.split(";");
for(int i=0;i<strs.length;i++)
temp.add(strs[i]);
return temp;
/**
* 数据保存时被调用
*/
@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);
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;
Student实体类:
package com.zhushuai.hibernate;
import java.util.HashMap;
import java.util.List;
public class Student
String id;
String name;
int age;
String birthday;
List emails;
public String getId()
return id;
public void setId(String id)
this.id = id;
public List getEmails()
return emails;
public void setEmails(List emails)
this.emails = emails;
public String getName()
return name;
public void setName(String name)
this.name = name;
public int getAge()
return age;
public void setAge(int age)
this.age = age;
public String getBirthday()
return birthday;
public void setBirthday(String birthday)
this.birthday = birthday;
student.hbm.xml的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.zhushuai.hibernate.Student">
<id name="id">
<generator class="uuid"></generator>
</id>
<property name="name" ></property>
<property name="age"></property>
<property name="birthday"></property>
<property name="emails" column="emails" type="com.zhushuai.hibernate.EmailType"/>
</class>
</hibernate-mapping>
client类:
package com.zhushuai.hibernate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Client
/**
* @param args
*/
public static void main(String[] args)
//读取hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
//建立sessionfactory
SessionFactory sessionfactory = cfg.buildSessionFactory();
Session session = null;
try
//开启session
session = sessionfactory.openSession();
//开启事务
session.beginTransaction();
// 插入数据
/*
Student student = new Student();
List list=new ArrayList<String>();
list.add("shuai.zhu@kodak.com");
list.add("454942607@qq.com");
student.setAge(23);
student.setBirthday("1990");
student.setName("zhushuai");
student.setEmails(list);
session.save(student);*/
//获取数据
String hql = "from Student where name='zhushuai'";
Query query = session.createQuery(hql);
List list = query.list();
Iterator it = list.iterator();
while(it.hasNext())
Student student = (Student) it.next();
List emailList = student.getEmails();
for(int i=0;i<emailList.size();i++)
System.out.println("email "+i+":"+emailList.get(i));
session.getTransaction().commit();
catch(Exception e)
e.getStackTrace();
session.getTransaction().rollback();
finally
if(session != null)
if(session.isOpen())
//关闭session
session.close();
// TODO Auto-generated method stub
输出结果:
以上是关于hibernate之自定义数据类型的主要内容,如果未能解决你的问题,请参考以下文章