介绍Hibernate使用UserType--ClobStringType
有两个方法,一个是修改映射TUSER的 java 类在其中增加一个 getEmail 方法,返回一个 list ,该方法对原先的 getEmail 方法进行二次处理。第二个方法就是采用UserType 。
UserType就是用户自定义类型,这里的类型指的是除了Hibernate定义的那些类型之外的用户自己定义的。
一个实现Hibernate使用UserType接口的 email 类如下(里面的每个方法都是必须实现的接口方法,许多都可以复制粘贴的,不复杂):(madp:详细代码看文章结尾)
package org.springframework.orm.hibernate3.support;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import javax.transaction.TransactionManager;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
/**
?* Hibernate UserType implementation for Strings that get mapped to CLOBs.
?* Retrieves the LobHandler to use from LocalSessionFactoryBean at config time.
?*
?* <p>Particularly useful for storing Strings with more than 4000 characters in an
?* Oracle database (only possible via CLOBs), in combination with OracleLobHandler.
?*
?* <p>Can also be defined in generic Hibernate mappings, as DefaultLobCreator will
?* work with most JDBC-compliant database drivers. In this case, the field type
?* does not have to be CLOB: For databases like MySQL and MS SQL Server, any
?* large enough character type will work.
?*
?* @author Juergen Hoeller
?* @since 1.2
?* @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler
?*/
public class ClobStringType extends AbstractLobType {
?/**
? * Constructor used by Hibernate: fetches config-time LobHandler and
? * config-time JTA TransactionManager from LocalSessionFactoryBean.
? * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler
? * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager
? */
?public ClobStringType() {
??super();
?}
?/**
? * Constructor used for testing: takes an explicit LobHandler
? * and an explicit JTA TransactionManager (can be <code>null</code>).
? */
?protected ClobStringType(LobHandler lobHandler, TransactionManager jtaTransactionManager) {
??super(lobHandler, jtaTransactionManager);
?}
?public int[] sqlTypes() {
??return new int[] {Types.CLOB};
?}
?public Class returnedClass() {
??return String.class;
?}
?protected Object nullSafeGetInternal(
???ResultSet rs, String[] names, Object owner, LobHandler lobHandler)
???throws SQLException {
??return lobHandler.getClobAsString(rs, names[0]);
?}
?protected void nullSafeSetInternal(
???PreparedStatement ps, int index, Object value, LobCreator lobCreator)
???throws SQLException {
??lobCreator.setClobAsString(ps, index, (String) value);
?}
}
)
?
(madp:
?
首先看一下 hibernate给我们提供的借口。UserType接口。具体的接口方法可以去看hiberate的文档或者看夏昕的深入浅出hiberate。里面都有详细的介绍。下面看一下,我们要实现该接口 需要实现的几个方法。
??? 1. 首先因为 数据库的 字符串映射到java端的list数据类型。所以 需要包含一个list的属性。
?????? private List emails;
??? 2. 其次需要实现 判断俩个自定义数据类型是否相等的函数。
?????? public boolean equals(Object x, Object y) throws HibernateException
??? 3.然后是在hiberate查询和更新操作时真正需要调用的方法,该方法从resultset中取出email字段,并将其解析为List类型后返回。
??????? public Object nullSafeGet(ResultSet rs, String[] names, Object owner)?
??? 4//将list类型组装成字符串后保存到email字段
????? public void nullSafeSet(PreparedStatement st, Object value, int index)?
??? 当然,需要自己具体的实现组装list和拆开list使其成为string的方法。
??? 下面贴出代码:
user.hbm.xml
?view plaincopy to clipboardprint?
<?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.chenlong.usertype.tuser" table="tuser">?
??????? <id name="id" type="java.lang.Integer">?
??????? <column name="ID" />????
??????? <generator type="java.lang.String">????
???????????? <column name="NAME" length="255" not-null="false" />????
??????? </property>?
??????? <property name="age" type="java.lang.Integer" column="age"></property>?
??????? <property name="email" type="com.chenlong.usertype.EmailList">?
??????? <column name = "EMAIL" length="300"/>?
??????? </property>?
??????? </class>?
</hibernate-mapping>?
<?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.chenlong.usertype.tuser" table="tuser">
???? <id name="id" type="java.lang.Integer">
???? <column name="ID" />?
???? <generator type="java.lang.String">?
???????????? <column name="NAME" length="255" not-null="false" />?
??????? </property>
???? <property name="age" type="java.lang.Integer" column="age"></property>
???? <property name="email" type="com.chenlong.usertype.EmailList">
???? <column name = "EMAIL" length="300"/>
???? </property>
???? </class>
</hibernate-mapping>
???? EmailList.java
view plaincopy to clipboardprint?
package com.chenlong.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 java.lang.String;???
????
? import org.hibernate.HibernateException;????
? import org.hibernate.Hibernate;????
??????
? /**??
?? * 必须得引用java.io.Serializable,UserType是反序列化??
?? * 另外,我使用的hibernate版本是3.2,UserType从2.0到3.2有很大的差异,应该多多看看官方的doc??
?? *???
?? * @author @家军.严重注意org.hibernate.usertype.UserType,不要自己造车呀.?
?? *???
?? */????
? public class EmailList implements java.io.Serializable,org.hibernate.usertype.UserType{????
??????
????? private List emails;??
??????
????? private static final String SPLITTER = ";";????
??????
????? private static final int[] TYPES = new int[] { Types.VARCHAR };????
??????
????? public int[] sqlTypes() {????
??????????????
????????? 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;????
????? }????
??????
????? //从resultset中取出email字段,并将其解析为List类型后返回。??
????? 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;????
????????? }????
????? }????
???????
????? //将list类型组装成字符串后保存到email字段??
????? public void nullSafeSet(PreparedStatement st, Object value, int index)????
????????????? throws HibernateException, SQLException {????
????????? System.out.println("Set method excecuted");????
????????? 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() {????????????
????????? return false;????
????? }????
??????
????? //将list组装成一个string返回给hibernate??
????? private String assemble(List emailList) {????
????????? StringBuffer strBuf = new StringBuffer();????
????????? for (int i = 0; i < emailList.size() - 1; i++) {????
????????????? strBuf.append(emailList.get(i)).append(SPLITTER);????
????????? }????
????????? strBuf.append(emailList.get(emailList.size() - 1));????
????????? return strBuf.toString();????
????? }????
??????
????? //将string拆开,放到list中??
????? private List parse(String value) {????
????????? String[] strs = value.split(SPLITTER);??
????????? List emailList = new ArrayList();????
????????? for (int i = 0; i < strs.length; i++) {????
????????????? emailList.add(strs[i]);????
????????? }????
????????? return emailList;????
????? }????
??????
????? public Object assemble(Serializable arg0, Object arg1) throws HibernateException {????
????????? // TODO Auto-generated method stub????
????????? return null;????
????? }????
??????
????? public Serializable disassemble(Object arg0) throws HibernateException {????
????????? // TODO Auto-generated method stub????
????????? return null;????
????? }????
??????
????? public int hashCode(Object arg0) throws HibernateException {????
????????? // TODO Auto-generated method stub????
????????? return 0;????
????? }????
??????
????? public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {????
????????? // TODO Auto-generated method stub????
????????? return null;????
????? }????
??????
? }???
package com.chenlong.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 java.lang.String;
?
? import org.hibernate.HibernateException;?
? import org.hibernate.Hibernate;?
???
? /**
?? * 必须得引用java.io.Serializable,UserType是反序列化
?? * 另外,我使用的hibernate版本是3.2,UserType从2.0到3.2有很大的差异,应该多多看看官方的doc
?? *?
?? * @author @家军.严重注意org.hibernate.usertype.UserType,不要自己造车呀.
?? *?
?? */?
? public class EmailList implements java.io.Serializable,org.hibernate.usertype.UserType{?
???
????? private List emails;
???
????? private static final String SPLITTER = ";";?
???
????? private static final int[] TYPES = new int[] { Types.VARCHAR };?
???
????? public int[] sqlTypes() {?
???????????
????????? 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;?
????? }?
???
????? //从resultset中取出email字段,并将其解析为List类型后返回。
????? 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;?
????????? }?
????? }?
????
????? //将list类型组装成字符串后保存到email字段
????? public void nullSafeSet(PreparedStatement st, Object value, int index)?
????????????? throws HibernateException, SQLException {?
????????? System.out.println("Set method excecuted");?
????????? 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() {?????????
????????? return false;?
????? }?
???
????? //将list组装成一个string返回给hibernate
????? private String assemble(List emailList) {?
????????? StringBuffer strBuf = new StringBuffer();?
????????? for (int i = 0; i < emailList.size() - 1; i++) {?
????????????? strBuf.append(emailList.get(i)).append(SPLITTER);?
????????? }?
????????? strBuf.append(emailList.get(emailList.size() - 1));?
????????? return strBuf.toString();?
????? }?
???
????? //将string拆开,放到list中
????? private List parse(String value) {?
????????? String[] strs = value.split(SPLITTER);
????????? List emailList = new ArrayList();?
????????? for (int i = 0; i < strs.length; i++) {?
????????????? emailList.add(strs[i]);?
????????? }?
????????? return emailList;?
????? }?
???
????? public Object assemble(Serializable arg0, Object arg1) throws HibernateException {?
????????? // TODO Auto-generated method stub?
????????? return null;?
????? }?
???
????? public Serializable disassemble(Object arg0) throws HibernateException {?
????????? // TODO Auto-generated method stub?
????????? return null;?
????? }?
???
????? public int hashCode(Object arg0) throws HibernateException {?
????????? // TODO Auto-generated method stub?
????????? return 0;?
????? }?
???
????? public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {?
????????? // TODO Auto-generated method stub?
????????? return null;?
????? }?
???
? }??
javabean--?? tuser.java
view plaincopy to clipboardprint?
package com.chenlong.usertype;????
import java.util.List;????
???????
?? /**??
???? * EchoMessageEmail generated by MyEclipse Persistence Tools??
???? */????
???????
public class tuser? implements java.io.Serializable {????
???????
?????? private Integer id;????
?????? private String name;????
?????? private Integer age;??
?????? private List email;????
??????
???? /** default constructor */????
???? public tuser() {????
????? }????
?????
???? /** minimal constructor */????
????? public tuser(String name) {????
????????? this.name = name;????
??? }????
??????????
????? /** full constructor */????
?????? public tuser(String name,Integer age, List email) {????
???????? this.name = name;????
???????? this.email = email;????
???????? this.age = age;??
????? }????
?????
?????????
???? // Property accessors????
?????
???? public Integer getId() {????
??????? return this.id;????
??? }????
??????????
???? public void setId(Integer id) {????
?????????? this.id = id;????
???? }????
?????
???? 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;????
???? }????
???? public List getEmail() {????
??????? return email;????
???? }????
??????
????? public void setEmail(List email) {????
???????? this.email = email;????
???? }????
}??
??
package com.chenlong.usertype;?
import java.util.List;?
????
?? /**
???? * EchoMessageEmail generated by MyEclipse Persistence Tools
???? */?
????
public class tuser? implements java.io.Serializable {?
????
?????? private Integer id;?
?????? private String name;?
?????? private Integer age;
?????? private List email;?
???
???? /** default constructor */?
???? public tuser() {?
????? }?
??
???? /** minimal constructor */?
????? public tuser(String name) {?
????????? this.name = name;?
??? }?
???????
????? /** full constructor */?
?????? public tuser(String name,Integer age, List email) {?
???????? this.name = name;?
???????? this.email = email;?
???????? this.age = age;
????? }?
??
??????
???? // Property accessors?
??
???? public Integer getId() {?
??????? return this.id;?
??? }?
???????
???? public void setId(Integer id) {?
?????????? this.id = id;?
???? }?
??
???? 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;?
???? }?
???? public List getEmail() {?
??????? return email;?
???? }?
???
????? public void setEmail(List email) {?
???????? this.email = email;?
???? }?
}
?
?
测试类 -- HibernateTest.java
view plaincopy to clipboardprint?
package com.chenlong.usertype;??
????
import java.util.List;????
import java.util.ListIterator;????
import com.chenlong.usertype.tuser;??
import org.hibernate.Query;????
import org.hibernate.Session;????
import org.hibernate.SessionFactory;????
import org.hibernate.Transaction;??
import org.hibernate.cfg.Configuration;????
??????
? public class HibernateTest {????
??????
????? public static void main(String[] args) throws Exception{????????????
????????? Configuration config = new Configuration().configure();??
????????? SessionFactory factory = config.buildSessionFactory();????
????????? Session session = factory.openSession();????
????????? Query query = session.createQuery("from tuser as a");????
????????? /**??
?????????? * 理论上来说,这里不存在lazy加载,为了安全起见使用了Iterator??
?????????? *???
?????????? */????
????????? ListIterator iterator = query.list().listIterator();????
????????? tuser tt = (tuser) iterator.next();//只找第一个????
????????? List emails = tt.getEmail();?????
????????? for (int i = 0; i < emails.size(); i++) {????
????????????? String emailStr = (String)emails.get(i);????
????????????? System.out.println(emailStr);????
????????? }?????
????????? tuser user = (tuser) session.load(tuser.class, new Integer(2));??
????????? List list = user.getEmail();??
????????? for(int i=0;i<list.size();i++)??
????????? {??
????????????? System.out.println(list.get(i));??
????????? }??
????????????
????????? list.remove("54beikehanmu@163.com");??
????????? list.remove("54beikehanmu@163.com");??
????????? //list.("54beikehanmu@163.com");??
????????? Transaction tx = session.beginTransaction();??
????????? session.save(user);??
????????? tx.commit();??
????????????
????????????
????????? session.close();????
????? }???????
? }?
?
?)
1 楼 beforezero 2011-03-10 介紹個2級緩存與UserType看看