HIbernate自定义类型 UserType的简单使用

经典的例子是一个用户对多个邮件的例子,在数据库中,用varchar存储,逗号或者分号隔开,而在程序中用数组或者List来操作。直接贴代码:
java vo:

package org.vo;

import java.util.List;


public class Tuser implements java.io.Serializable {

// Fields

private Integer toid;
private String name;
private Integer age;

private List email;
// Constructors

public List getEmail() {
return email;
}

public void setEmail(List email) {
this.email = email;
}

/** default constructor */
public Tuser() {
}

/** full constructor */
public Tuser(String name, Integer age) {
this.name = name;
this.age = age;
}

// Property accessors

public Integer getToid() {
return this.toid;
}

public void setToid(Integer toid) {
this.toid = toid;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return this.age;
}

public void setAge(Integer age) {
this.age = age;
}

}



<?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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<!-- entity-name="DynamicUserMap" 假如把name属性换成这个,那么可以映射成map 但一般不提倡这样用 -->
<class name="org.vo.Tuser" table="tuser" >
<id name="toid" type="java.lang.Integer">
<column name="toid" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="10">
<comment>姓名</comment>
</column>
</property>
<property name="age" type="java.lang.Integer">
<column name="age">
<comment>年龄</comment>
</column>
</property>

<!--注意:此时的type是下面自定义的类型-->
<property name="email" type="org.vo.EmailList">
<column name="email">
<comment>邮箱</comment>
</column>
</property>

</class>
</hibernate-mapping>



下面是自定义的类型,实现UserType接口

package org.vo;

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;

/**
* 自定义数据类型
*
* @author afei
*
*/
public class EmailList implements UserType {

private List emails;

private static final String SPLITTER = ";";

private static final int[] TYPES = new int[] { Types.VARCHAR };

/**
* 深度copy一个副本给用户使用,脏数据检查时候发现不相同,会执行相应的持久化操作 在这里创建一个新的list,包含原来的所有元素
*/
@Override
public Object deepCopy(Object value) throws HibernateException {
List sourcelist = (List) value;
List targetlist = new ArrayList();
if(sourcelist!=null){
targetlist.addAll(sourcelist);
}
return targetlist;
}

@Override
public Serializable disassemble(Object arg0) throws HibernateException {
System.out.println("disassemble()");
return null;
}

/**
* 此方法用户账数据检查,假如返回false,则认为数据发生变化,并将变化更新到库表中 这里判断email list是否发生改变
*/
@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 yList = (List) y;

if (xList.size() != yList.size())
return false;

for (int i = 0; i < xList.size(); i++) {
String strx = (String) xList.get(i);
String stry = (String) yList.get(i);
if (!(strx.equals(stry)))
return false;
}
return true;
}
return false;
}

@Override
public int hashCode(Object arg0) throws HibernateException {
// TODO Auto-generated method stub
return 0;
}

/**
* 本类型实例是否可变
*/
@Override
public boolean isMutable() {
return false;
}

/**
* 从JDBC ResultSet读取数据,将其转换为自定义类型后返回 (此方法要求对可能出现的null值进行处理)
* names中包含了当前自定义类型的映射字段名称
*/
@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;
}

}

/**
* 自定义方法,将";"分隔的字符串解析为一个字符串数组
* @return
*/
private List parse(String value){
String[] args=value.split(SPLITTER);
List<String> emailList=new ArrayList<String>();
for(String email:args){
emailList.add(email);
}
return emailList;
}

/**
* 本方法将在hibernate进行数据保存时调用 我们可以通过PreparedStatement将自定义数据写入对应的库表字段
* 将List型的email用";"分隔后存入数据库
*/
@Override
public void nullSafeSet(PreparedStatement ps, Object value, int index)
throws HibernateException, SQLException {
if(value!=null){
Object str=this.assemble((List)value);
Hibernate.STRING.nullSafeSet(ps,str,index);
}else{
Hibernate.STRING.nullSafeSet(ps,value,index);
}

}


@Override
public Object assemble(Serializable str, Object emailList)
throws HibernateException {
return null;
}

/**
* 以字符串拼接
*/
public String assemble(List emailList)
throws HibernateException {
String str="";
for(Object email:emailList){
if(str.equals("")){
str=(String)email;
}else{
str=str+SPLITTER+(String)email;
}

}
System.out.println("assemble");
return str;
}

@Override
public Object replace(Object arg0, Object arg1, Object arg2)
throws HibernateException {
// TODO Auto-generated method stub
return null;
}

/**
* UserType.nullSafeGet()所返回的自定义数据类型
*/
@Override
public Class returnedClass() {
return List.class;
}

/**
* 返回UserType所映射字段的类型(java.sql.Types) 返回类型为int[],其中包含了映射各字段的SQL类型代码
* (UserType可以映射到一个或多个字段)
*/
@Override
public int[] sqlTypes() {
// TODO Auto-generated method stub
return TYPES;
}

}


ok,咱们做实验:

package org;

import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.EntityMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.usertype.UserType;
import org.util.HibernateSessionFactory;
import org.vo.Tuser;

public class TestHib {

/**
* @param args
*/
public static void main(String[] args) {
Tuser user=new Tuser();
user.setName("hehe1");
user.setAge(20);
List<String> emailList=new ArrayList<String>();
emailList.add("6646590081@qq.com");
emailList.add("2957375892@qq.com");
user.setEmail(emailList);
add(user);
printVos();
}

public static void add(Tuser user){
Session session=HibernateSessionFactory.getSession();
Transaction tran=session.beginTransaction();
session.save(user);
tran.commit();
}



public static void printVos(){
Session session=HibernateSessionFactory.getSession();
List<Tuser> list=session.createQuery(" from Tuser ").list();
for(Tuser u:list){
List<String> emailList=u.getEmail();
System.out.println(u.getName()+" "+u.getAge()+" "+emailList);
if(emailList!=null){
for(String e:emailList){
System.out.println(e);
}
}

}
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值