hibernate之自定义数据类型
2016-04-28 17:33
525 查看
简介
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 } }
输出结果:
相关文章推荐
- 发布cocoapods
- 当孩子伸手向你要钱时,千万不能这样做,一辈子的阴影。
- 盲打练习
- 二进制数转化
- 十进制转化为十六进制
- 冲刺第九天
- GUI for git|SourceTree|入门基础
- 集合框架(List集合的特点)
- 设置UITextField输入小数点位数的限制
- Codeforces 236B Easy Number Challenge 【因子和】
- 设计模式二三事——单例模式
- Android之EditText属性详解
- Unity5.3.4以前的旧版本打包问题Xcode7.3编译问题 Error "unknown type name __declspec" after Xcode 7.3 upgrade
- Linux进阶之bash编程(函数及总结)
- oracle函数
- UIPopoverPresentationController -
- 微信公众平台
- 【leetcode】String——Restore IP Addresses (93)
- 一文读懂机器学习
- 2进制