`
wangzl2222
  • 浏览: 150944 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Hibernate映射自定义数据类型

阅读更多

数据库中存在一个email字段,并允许其中存储多个email地址,各地址之间使用 ; 分割,但是在POJO中,为了便于处理,email定义为一个List对象。
如何将String字段映射为List类型,Hibernate并没有提供原生支持,需要我们实现自己的UserType。
1.数据库定义

DROP   TABLE  t_user_mail;

CREATE   TABLE  t_user_mail (
       id 
INT   NOT   NULL  AUTO_INCREMENT
     , name 
VARCHAR ( 50 )
     , age 
INT
     , email 
VARCHAR ( 300 )
     , 
PRIMARY   KEY  (id)
);


2.
实现了UserType的自定义数据类型类EMailList

package  cn.blogjava.usertype;

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.apache.commons.lang.StringUtils;
import  org.hibernate.Hibernate;
import  org.hibernate.HibernateException;
import  org.hibernate.usertype.UserType;

public   class  EMailList  implements  UserType {

    
private   static   final   char  SPLITTER =   ' ; ' ;
    
private   static   final   int [] TYPES  =   new   int [] {Types.VARCHAR};
    
    
public   int [] sqlTypes() {
        
//  TODO Auto-generated method stub
         return  TYPES;
    }

    
public  Class returnedClass() {
        
//  TODO Auto-generated method stub
         return  List. class ;
    }

    
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 str1 
=  (String)xlist.get(i);
                String str2 
=  (String)ylist.get(i);
                
if ( ! str1.equals(str2))  return   false ;
            }
            
return   true ;
        }
        
return   false ;
    }

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

    
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 ;
        }
    }

    
public   void  nullSafeSet(PreparedStatement st, Object value,  int  index)
            
throws  HibernateException, SQLException {
        
if (value  !=   null ) {
            String str 
=  assemble((List)value);
            Hibernate.STRING.nullSafeSet(st, str, index);
        } 
else  {
            Hibernate.STRING.nullSafeSet(st, value, index);
        }
    }

    
public  Object deepCopy(Object value)  throws  HibernateException {
        List sourceList 
=  (List)value;
        List targetList 
=   new  ArrayList();
        targetList.addAll(sourceList);
        
return  targetList;
    }

    
public   boolean  isMutable() {
        
//  TODO Auto-generated method stub
         return   false ;
    }

    
public  Serializable disassemble(Object arg0)  throws  HibernateException {
        
//  TODO Auto-generated method stub
         return   null ;
    }

    
public  Object assemble(Serializable arg0, Object arg1)
            
throws  HibernateException {
        
//  TODO Auto-generated method stub
         return   null ;
    }

    
public  Object replace(Object arg0, Object arg1, Object arg2)
            
throws  HibernateException {
        
//  TODO Auto-generated method stub
         return   null ;
    }
    
    
private  String assemble(List emailList) {
        StringBuffer strBuf 
=   new  StringBuffer();
        
for  ( int  i  =   0 ; i  <  emailList.size() - 1 ; i ++ ) {
            strBuf.append((String)emailList.get(i)).append(SPLITTER);            
        }
        strBuf.append(emailList.get(emailList.size()
- 1 ));
        
return  strBuf.toString();
    }
    
    
private  List parse(String value) {
        String[] strs 
=  StringUtils.split(value, SPLITTER);
        List emailList 
=   new  ArrayList();
        
for  ( int  i  =   0 ; i  <  strs.length; i ++ ) {
            emailList.add(strs[i]);
        }
        
return  emailList;
    }

}



3.
配置文件TUserMail.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 
        Auto-generated mapping file from
        the hibernate.org cfg2hbm engine
-->
    <class name
="cn.blogjava.usertype.TUserMail" table="t_user_mail" catalog="sample">
        <id name
="id" type="integer">
            <column name
="id" />
            <generator class
="native" />
        </id>
        <property name
="name" type="string">
            <column name
="name" length="50" />
        </property>
        <property name
="age" type="integer">
            <column name
="age" />
        </property>
        <property name
="email" type="cn.blogjava.usertype.EMailList">
            <column name
="email" length="300" />
        </property>
    </class>
</hibernate-mapping>


4.
在hibernate.cfg.xml载入TUserMail.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name
="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name
="hibernate.connection.password">1234</property>
        <property name
="hibernate.connection.url">jdbc:mysql://localhost:3306/sample</property>
        <property name
="hibernate.connection.username">root</property>
        <property name
="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <mapping resource
="cn/blogjava/start/TUser.hbm.xml" />
        <mapping resource
="cn/blogjava/usertype/TUserMail.hbm.xml" />
    </session-factory>
</hibernate-configuration>


5.
测试类HibernateTest.java

package cn.blogjava.usertype;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;


public class HibernateTest extends TestCase {
    
    Session session 
= null;
    
/**
     * JUnit中的setUp方法在TestCase初始化的时候会自动调用
     * 一般用于初始化公用资源
     
*/
    
protected void setUp() {
        
try {
            
/**
             * 可以采用hibernate.properties或者hibernate.cfg.xml
             * 配置文件的初始化代码
             * 
             * 采用hibernate.properties
             * Configuration config = new Configuration();
             * config.addClass(TUser.class);
             
*/
            
            
//采用hibernate.cfg.xml配置文件,与上面的方法对比,两个差异
            
//1.Configuration的初始化方式
            
//2.xml
            Configuration config = new Configuration().configure();
            SessionFactory sessionFactory 
= config.buildSessionFactory();
            session 
= sessionFactory.openSession();
            
        } 
catch (HibernateException e) {
            
// TODO: handle exception
            e.printStackTrace();
        }        
    }

    
/**
     * JUnit中的tearDown方法在TestCase执行完毕的时候会自动调用
     * 一般用于释放资源
     
*/    
    
protected void tearDown() {
        
try {
            session.close();        
        } 
catch (HibernateException e) {
            
// TODO: handle exception
            e.printStackTrace();
        }        
    }    
    
    
/**
     * 对象持久化测试(Insert方法)
     
*/        
    
public void testInsert() {
        Transaction tran 
= null;
        
try {
            tran 
= session.beginTransaction();
            TUserMail user 
= new TUserMail();
            user.setName(
"byf");
            List list 
= new ArrayList();
            list.add(
"baiyf@msn.com");
            list.add(
"bexy@163.com");
            user.setEmail(list);
            session.save(user);
            session.flush();
            tran.commit();
            Assert.assertEquals(user.getId().intValue()
>0 ,true);
        } 
catch (HibernateException e) {
            
// TODO: handle exception
            e.printStackTrace();
            Assert.fail(e.getMessage());
            
if(tran != null) {
                
try {
                    tran.rollback();
                } 
catch (Exception e1) {
                    
// TODO: handle exception
                    e1.printStackTrace();
                }
            }
        }
    }
    
    
/**
     * 对象读取测试(Select方法)
     
*/            
    
public void testSelect(){
        String hql 
= " from TUserMail where name='byf'";
        
try {
            List userList 
= session.createQuery(hql).list();
            TUserMail user 
= (TUserMail)userList.get(0);
            List mailList 
= user.getEmail();

            Assert.assertEquals((String)mailList.get(
0), "baiyf@msn.com");
            Assert.assertEquals((String)mailList.get(
1), "bexy@163.com");
        } 
catch (Exception e) {
            
// TODO: handle exception
            e.printStackTrace();
            Assert.fail(e.getMessage());
        }
    }
}

运行测试代码,观察数据库中,可以发现email地址信息已经以";"分隔的形式保存。同时,在数据读取时,我们也无需面对原始的";"分隔字符串,转而只需要处理List类型数据即可。
from:http://www.blogjava.net/knowhow/archive/2006/06/29/55774.html

分享到:
评论

相关推荐

    Hibernate使用——自定义数据类型

    本篇文章将深入探讨如何在Hibernate中实现自定义数据类型。 首先,我们需要理解Hibernate是如何处理数据类型的。默认情况下,Hibernate使用Java的标准数据类型来映射数据库中的列。例如,Integer对应INT,String...

    JAVA数据类型与Hibernate的类型映射

    此外,自定义对象的映射是Hibernate映射中的一个重要部分。通过在实体类上使用@Entity注解,并使用@Id注解指定主键字段,可以将一个Java类映射到数据库的一张表。字段则通过@Column注解来指定列名和属性,如长度、...

    hibernate映射枚举类型

    在Java编程中,枚举类型(Enum)是一种...正确地映射枚举类型可以增强代码的可读性和可维护性,同时减少因数据类型转换导致的潜在错误。在实际开发中,我们应该根据业务场景和枚举特性的需求,选择最合适的映射策略。

    简要分析Java的Hibernate框架中的自定义类型

    在Java的Hibernate框架中,自定义类型是一种非常实用的功能,它允许开发者根据特定业务需求扩展Hibernate内置的数据类型。当我们发现Hibernate默认的数据类型无法满足我们存储数据的特殊要求时,例如需要处理复杂...

    hibernate映射Oracle中LONG类型

    "hibernate映射Oracle中LONG类型" Hibernate 框架映射 Oracle 中的 LONG 类型字段是一种复杂的技术问题。Oracle 中的 LONG 类型字段是一种特殊的数据类型,用于存储可变长字符串,最大长度限制是 2GB。这与 Java ...

    Java数据类型,Hibernate数据类型,标准sql数据类型之间的对应表

    此外,Hibernate还支持自定义数据类型的映射,允许开发者根据需求扩展和定制。 在实际开发中,理解这些映射关系至关重要,因为它直接影响到数据的存储和查询效率,以及数据的一致性和完整性。例如,如果错误地将...

    java根据实体类生成Hibernate映射文件

    映射文件包含了类名、表名、字段及其数据类型等信息。例如: ```xml &lt;hibernate-mapping&gt; &lt;/hibernate-mapping&gt; ``` 在上述示例中,`User`类与`users`表对应,`id`字段表示主键,`username`和`...

    常用 Hibernate 映射配置说明.doc

    ### 常用Hibernate映射配置详解 #### 1. hibernate-mapping节点解析 `hibernate-mapping`节点是Hibernate映射文件中的顶级节点,用于定义一系列配置选项,控制整个映射文件的行为和映射规则。这些配置包括数据库...

    用MyEclipse自动生成hibernate映射文件和实体类

    3. **逆向工程(Hibernate Reverse Engineering)**:选中要映射的数据库表,右键选择`Hibernate Reverse Engineering`,这是MyEclipse提供的将数据库表转换为Hibernate映射文件和实体类的工具。 4. **配置生成选项...

    用Hibernate实现领域对象的自定义字段

    当我们说“自定义字段”,通常是指领域对象中的一些特殊属性,这些属性可能无法直接通过标准的数据类型来表示,比如日期范围、地理位置等。这时,我们需要创建自定义的Hibernate类型来处理这些特殊的字段。 创建...

    Hibernate 映射文件 结构

    属性包括`name`(Java属性名)、`column`(数据库列名)、`type`(数据类型,如`integer`、`string`等)。 5. ****:一对多关系映射,表示一个实体类的某个属性引用了另一个实体类的一个实例。 6. ****:多对一...

    hibernate关联映射的作用和常用属性解释

    - **`type`**:指定数据类型。 - **`not-null`**:是否不允许为空。 - **`unique`**:是否唯一。 - **`insert`**:是否参与插入操作,默认为`true`。 - **`update`**:是否参与更新操作,默认为`true`。 - **`...

    Hibernate映射

    **Hibernate映射详解** 在Java世界中,关系型数据库与对象模型之间的转换一直是开发中的一个挑战。Hibernate,作为一款强大的对象关系映射(ORM)框架,有效地解决了这个问题。本篇文章将深入探讨Hibernate映射的...

    hibernate 映射

    在Java世界中,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者将数据库操作转化为对Java对象的操作,极大地简化了数据访问层的编程。"hibernate 映射"是这个框架的核心概念之一,涉及到如何将数据库表...

    Hibernate关系映射XML生成工具

    在使用Middlegen时,开发者需要注意的是,虽然自动化工具能减轻工作量,但生成的XML映射文件可能需要根据实际需求进行调整,例如添加自定义的属性或者处理复杂的数据类型和关系。此外,随着技术的发展,许多现代ORM...

    Hibernate和java中的对应数据类型

    然而,当我们与数据库进行交互,特别是使用ORM(对象关系映射)框架如Hibernate时,这些数据类型需要与数据库中对应的数据类型相匹配,以确保数据的正确存储和检索。下面我们将详细探讨Java、Hibernate以及SQL之间的...

    hibernate 调用oracle函数

    本文将深入探讨如何在Hibernate中调用Oracle的函数,以实现高效的数据操作。 首先,我们需要理解Hibernate的核心理念,它允许开发者通过面向对象的方式来处理数据库操作,而无需编写大量的SQL语句。Hibernate通过...

    Hibernate中映射枚举类型

    在Hibernate中映射枚举类型是一个常见的需求,利用好Hibernate提供的工具和自定义映射器可以让我们更加灵活地处理不同场景下的枚举类型映射需求。通过本文介绍的方法,我们可以轻松地将枚举类型的`name`、`ordinal`...

    达梦Hibernate方言2.0至4.0

    例如,达梦Hibernate方言会包含对达梦特有的数据类型、函数和存储过程的适配。 对于“达梦Hibernate方言2.0至4.0”,这意味着该方言支持Hibernate框架从2.0到4.0的多个版本。每个新版本的Hibernate都可能引入新的...

    解决Hibernate对于Date类型的数据返回结果中时分秒不对的问题

    在使用Hibernate进行数据库操作时,有时会遇到一个常见的问题,即当从数据库中查询Date类型的数据并由Hibernate返回时,发现结果中的时分秒部分不正确。这个问题通常源于多个因素,包括日期时间的序列化与反序列化...

Global site tag (gtag.js) - Google Analytics