`
dreamoftch
  • 浏览: 496624 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用hibernate中的UserType解决乱码问题

 
阅读更多
转自:http://hi.baidu.com/gacmotor/item/3ea2e62952c99acbddf69aea

总的思想还是一样:
页面编码都是utf-8,数据库是xxx,那就new String("你好".getBytes("utf-8"),"xxx")

然后读取出来的时候new String("...".getBytes("xxx"),"utf-8")
 

hibernate 访问 oracle 乱码 oracle的字符集是WE8ISO8859P1,由于历史原因,不可修改。已经修改本地 NLS_LANG,因此使用PL/SQL developer可以正常访问。 但是 hibernate使用thin方式连接数据库,中文乱码。 为了使页面可以正常显示,在取数据时在form的get方法中使用 
String new_str = new String(old_str.getBytes("iso-8859-1"));

 得到的new_str可以正常显示中文。 但是这样增加了冗余代码,而且使用好多第三方组件时,由于无法控制转码细节,导致乱码。 在互联网上搜索解决方案,搜到的大多是一个方法,加入filter,使用org.springframework.web.filter.CharacterEncodingFilter 但是对我这个情况完全无效,存取数据都是乱码,存到数据库里的数用客户端看也是乱码。 我觉得CharacterEncodingFilter应该是在oracle的字符集正确设置的情况下,比如使用ZHS16GBK,解决乱码的问题。 现在请教各位高手有没有遇到过同样的问题,如何解决这种情况下的乱码。是否需要写一个filter或者是hibernate直接可以对oracle字符集进行配置。 问题已经解决,说一下我的解决方案吧。使用hibernate的UserType 在hbm.xml中配置,

比如 <property name="roleName" type="com.xtmcc.framework.dao.GBKString"> <column name="ROLE_NAME" length="50" />
 </property> 

自定义GBKString 类
package two;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.driver.OracleTypes;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class a1 implements UserType {
	public a1() {
		super();
	}

	public int[] sqlTypes() {
		return new int[] { OracleTypes.VARCHAR };
	}

	public Class returnedClass() {
		return String.class;
	}

	public boolean equals(Object x, Object y) throws HibernateException {
		return (x == y) || (x != null && y != null && (x.equals(y)));
	}

	public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
			throws HibernateException, SQLException {
		String val = rs.getString(names[0]);
		if (null == val) {
			return null;
		} else {
			try {
				val = new String(val.getBytes("iso-8859-1"), "GBK");
			} catch (UnsupportedEncodingException e) {
				throw new HibernateException(e.getMessage());
			}
			return val;
		}
	}

	public void nullSafeSet(PreparedStatement st, Object value, int index)
			throws HibernateException, SQLException {
		if (value == null) {
			st.setNull(index, OracleTypes.VARCHAR);
		} else {
			String val = (String) value;
			try {
				val = new String(val.getBytes("GBK"), "ISO_8859_1");
			} catch (UnsupportedEncodingException e) {
				throw new HibernateException(e.getMessage());
			}
			st.setObject(index, val, OracleTypes.VARCHAR);
		}
	}

	public Object deepCopy(Object value) throws HibernateException {
		if (value == null)
			return null;
		return new String((String) value);
	}

	public boolean isMutable() {
		return false;
	}

	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 {
		return HashCodeBuilder.reflectionHashCode(this);
	}

	public Object replace(Object arg0, Object arg1, Object arg2)
			throws HibernateException {
		// TODO Auto-generated method stub//
		return null;
	}
}
 
分享到:
评论
8 楼 小天蝎 2014-02-19  
xush_319 写道
问题解决 下面贴出我的代码

谢谢xush_319 ,我也遇到与你一样的问题,主要是与未使用那个deepCopy引起中文值的丢失,多谢!
7 楼 dreamoftch 2013-04-17  
xush_319 写道
public class GBKString implements UserType
{

public GBKString()
{
super();
}

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

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

    /**   
  * 自定义数据类型的比对方法   
  * 此方法将用作脏数据检查,参数x、y分别为数据的两个副本   
  * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中   
  * @param x   
  * @param y   
  * @return   
  * @throws HibernateException   
  */
@Override
public boolean equals(Object x, Object y) throws HibernateException
{
return (x == y) || (x != null && y != null && (x.equals(y))); 
}

@Override
public int hashCode(Object x) throws HibernateException
{
return HashCodeBuilder.reflectionHashCode(this); 
}

/**   
  * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回   
  * (此方法要求对克能出现null值进行处理)   
  * names中包含了当前自定义类型的映射字段名称   
  * @param rs   
  * @param names   
  * @param owner   
  * @return   
  * @throws HibernateException   
  * @throws SQLException   
  */ 
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException
{

String val = rs.getString(names[0]); 
        if (val != null) { 
        try { 
                val = new String(val.getBytes("ISO-8859-1"), "GBK"); 
            } catch (UnsupportedEncodingException e) { 
                throw new HibernateException(e.getMessage()); 
            } 
            return val; 
           
        } else { 
        return null; 
        } 
}

/**   
  * 本方法将在Hibernate进行数据保存时被调用   
  * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段   
  * 这个方法将在数据保存时使用。本方法可以使用PreparedStatement将数据写入对应的数据库字段中。 
  * 其中的value表示的是要写入的值。index表示的是在statement的参数中的index.
  * @param st   
  * @param value   
  * @param index   
  * @throws HibernateException   
  * @throws SQLException   
  */ 
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException
{
if (value != null) { 
String val = (String) value; 
            try { 
                val = new String(val.getBytes("GBK"), "ISO-8859-1"); 
            } catch (UnsupportedEncodingException e) { 
                throw new HibernateException(e.getMessage()); 
            } 
            st.setObject(index, val, Types.VARCHAR); 
        } else { 
        st.setNull(index, Types.VARCHAR); 
        } 
}

/**   
  * 提供自定义类型的完全复制方法   
  * 本方法将用构造返回对象   
  * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前,   
  * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户   
  * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过   
  * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作   
  * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用   
  * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作   
  *   
  * @param value   
  * @return   
  * @throws HibernateException   
  */ 
@Override
public Object deepCopy(Object value) throws HibernateException
{
if (value == null) 
            return null; 
        return new String((String) value); 
//        return (String) value; 
}

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

@Override
public Serializable disassemble(Object value) throws HibernateException
{
return (Serializable) deepCopy(value);
}

@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException
{
return deepCopy(cached);
}

@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException
{
return deepCopy(original);
}

}

是后面那三个方法的原因?
@Override
public Serializable disassemble(Object value) throws HibernateException
{
return (Serializable) deepCopy(value);
}

@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException
{
return deepCopy(cached);
}

@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException
{
return deepCopy(original);
}
这三个方法肿么会有影响(⊙o⊙)…。。。不过问题解决了就行,O(∩_∩)O哈哈~
6 楼 xush_319 2013-04-16  
public class GBKString implements UserType
{

public GBKString()
{
super();
}

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

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

    /**   
  * 自定义数据类型的比对方法   
  * 此方法将用作脏数据检查,参数x、y分别为数据的两个副本   
  * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中   
  * @param x   
  * @param y   
  * @return   
  * @throws HibernateException   
  */
@Override
public boolean equals(Object x, Object y) throws HibernateException
{
return (x == y) || (x != null && y != null && (x.equals(y))); 
}

@Override
public int hashCode(Object x) throws HibernateException
{
return HashCodeBuilder.reflectionHashCode(this); 
}

/**   
  * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回   
  * (此方法要求对克能出现null值进行处理)   
  * names中包含了当前自定义类型的映射字段名称   
  * @param rs   
  * @param names   
  * @param owner   
  * @return   
  * @throws HibernateException   
  * @throws SQLException   
  */ 
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException
{

String val = rs.getString(names[0]); 
        if (val != null) { 
        try { 
                val = new String(val.getBytes("ISO-8859-1"), "GBK"); 
            } catch (UnsupportedEncodingException e) { 
                throw new HibernateException(e.getMessage()); 
            } 
            return val; 
           
        } else { 
        return null; 
        } 
}

/**   
  * 本方法将在Hibernate进行数据保存时被调用   
  * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段   
  * 这个方法将在数据保存时使用。本方法可以使用PreparedStatement将数据写入对应的数据库字段中。 
  * 其中的value表示的是要写入的值。index表示的是在statement的参数中的index.
  * @param st   
  * @param value   
  * @param index   
  * @throws HibernateException   
  * @throws SQLException   
  */ 
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException
{
if (value != null) { 
String val = (String) value; 
            try { 
                val = new String(val.getBytes("GBK"), "ISO-8859-1"); 
            } catch (UnsupportedEncodingException e) { 
                throw new HibernateException(e.getMessage()); 
            } 
            st.setObject(index, val, Types.VARCHAR); 
        } else { 
        st.setNull(index, Types.VARCHAR); 
        } 
}

/**   
  * 提供自定义类型的完全复制方法   
  * 本方法将用构造返回对象   
  * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前,   
  * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户   
  * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过   
  * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作   
  * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用   
  * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作   
  *   
  * @param value   
  * @return   
  * @throws HibernateException   
  */ 
@Override
public Object deepCopy(Object value) throws HibernateException
{
if (value == null) 
            return null; 
        return new String((String) value); 
//        return (String) value; 
}

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

@Override
public Serializable disassemble(Object value) throws HibernateException
{
return (Serializable) deepCopy(value);
}

@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException
{
return deepCopy(cached);
}

@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException
{
return deepCopy(original);
}

}
5 楼 xush_319 2013-04-16  
问题解决 下面贴出我的代码
4 楼 xush_319 2013-04-12  
自己写的转码方法 在查询的时候是没有问题的。下面是代码



/**
* 序列化号码
*/
private static final long serialVersionUID = 5801390347850112447L;

public GBKString()
{
super();
}

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

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

    /**   
  * 自定义数据类型的比对方法   
  * 此方法将用作脏数据检查,参数x、y分别为数据的两个副本   
  * 如果equals方法返回false,则Hibernate将认为数据发生变化,并将变化更新到数据库表中   
  * @param x   
  * @param y   
  * @return   
  * @throws HibernateException   
  */
@Override
public boolean equals(Object x, Object y) throws HibernateException
{
return (x == y) || (x != null && y != null && (x.equals(y))); 
}

@Override
public int hashCode(Object x) throws HibernateException
{
return HashCodeBuilder.reflectionHashCode(this); 
}

/**   
  * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回   
  * (此方法要求对克能出现null值进行处理)   
  * names中包含了当前自定义类型的映射字段名称   
  * @param rs   
  * @param names   
  * @param owner   
  * @return   
  * @throws HibernateException   
  * @throws SQLException   
  */ 
@Override
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException
{

String val = rs.getString(names[0]); 
        if (val != null) { 
        try { 
                val = new String(val.getBytes("ISO-8859-1"), "GBK"); 
            } catch (UnsupportedEncodingException e) { 
                throw new HibernateException(e.getMessage()); 
            } 
            return val; 
           
        } else { 
        return null; 
        } 
}

/**   
  * 本方法将在Hibernate进行数据保存时被调用   
  * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段   
  * 这个方法将在数据保存时使用。本方法可以使用PreparedStatement将数据写入对应的数据库字段中。 
  * 其中的value表示的是要写入的值。index表示的是在statement的参数中的index.
  * @param st   
  * @param value   
  * @param index   
  * @throws HibernateException   
  * @throws SQLException   
  */ 
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException
{
if (value != null) { 
String val = (String) value; 
            try { 
                val = new String(val.getBytes("GBK"), "ISO-8859-1"); 
            } catch (UnsupportedEncodingException e) { 
                throw new HibernateException(e.getMessage()); 
            } 
            st.setObject(index, val, Types.VARCHAR); 
        } else { 
        st.setNull(index, Types.VARCHAR); 
        } 
}

/**   
  * 提供自定义类型的完全复制方法   
  * 本方法将用构造返回对象   
  * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前,   
  * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户   
  * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过   
  * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作   
  * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用   
  * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作   
  *   
  * @param value   
  * @return   
  * @throws HibernateException   
  */ 
@Override
public Object deepCopy(Object value) throws HibernateException
{
if (value == null) 
            return null; 
//        return new String((String) value); 
        return (String) value; 
}

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

@Override
public Serializable disassemble(Object value) throws HibernateException
{
return null;
}

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

@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException
{
return null;
}

3 楼 xush_319 2013-04-12  
我在实体类 属性上是这样写的@Type(type = "commons.util.hibernate.GBKString")
@Column(name="admintruename", length=100)
private String realname;
2 楼 dreamoftch 2013-04-12  
xush_319 写道
我在使用UserType 的时候发现更新数据时 不能获取到该属性的值。正在研究。谁有解决方案共享下。
你是怎么做的?详细问题方便说下么
1 楼 xush_319 2013-04-11  
我在使用UserType 的时候发现更新数据时 不能获取到该属性的值。正在研究。谁有解决方案共享下。

相关推荐

    hibernate映射Oracle中LONG类型

    使用自定义类型映射 Oracle 中的 LONG 类型字段是解决 Hibernate 框架中 LONG 类型字段读写问题的一种有效方法。通过实现 UserType 接口,我们可以定制 LONG 类型字段的读写操作,并提高 Hibernate 框架的灵活性和可...

    hibernate4.1中文api

    - **使用org.hibernate.usertype.UserType**: 实现自定义用户类型。 - **使用org.hibernate.usertype.CompositeUserType**: 映射复合类型。 - **类型注册**: 注册自定义类型。 #### 7. 集合映射 - **持久化集合*...

    Hibernate的char问题.txt

    在给定的文件“Hibernate的char问题.txt”中,虽然描述较为模糊,但我们可以根据提供的 SQL 语句推测出,这里讨论的是在使用 Hibernate 进行数据查询时,如何正确地处理 `char` 类型的数据字段。 #### 三、问题分析...

    Hibernate3.2EnumTypeMapping-demo.zip

    本示例代码工程"Hibernate3.2EnumTypeMapping-demo.zip"就是为了演示如何在Hibernate中正确地处理枚举类型,以提高数据模型的清晰度和安全性。 在传统的Hibernate应用中,枚举通常通过String或整型来映射,但这种...

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

    当我们发现Hibernate默认的数据类型无法满足我们存储数据的特殊要求时,例如需要处理复杂对象或者自定义逻辑时,就可以通过自定义类型进行解决。 自定义类型主要有两种实现方式: 1. 实现`UserType`接口:这是最...

    Hibernate实战(第2版 中文高清版)

     1.1.3 在Java中使用SQL   1.1.4 面向对象应用程序中的持久化   1.2 范式不匹配   1.2.1 粒度问题   1.2.2 子类型问题   1.2.3 同一性问题   1.2.4 与关联相关的问题   1.2.5 数据导航的问题   ...

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

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作与业务...在实际开发中,理解并熟练运用自定义类型能帮助我们更好地解决复杂的数据存储问题,提高系统的扩展性和适应性。

    mysql 让hibernate支持text字段的方言

    - 在Hibernate中,字段类型与数据库类型之间需要有映射。例如,可以创建一个自定义的`UserType`实现,覆盖`sqlTypes()`方法,返回`TEXT`字段对应的SQL类型代码(如` Types.LONGVARCHAR`),并在`returnedClass()`...

    hibernate3中文手册

    10. **集合映射**:阐述List、Set、Map等集合类型在Hibernate中的映射方法。 11. **自定义类型**:如果需要对特殊类型的属性进行映射,可以实现UserType接口来自定义类型。 12. **实体状态管理**:区分临时态、...

    Hibernate4实战 之第七部分

    尽管在Hibernate中标识符属性不是强制性的,但强烈推荐使用它们。标识符应当是“人造”的,即由系统自动生成,不携带任何业务逻辑上的意义。这样做的好处包括: - **一致性**:确保在整个应用程序中实体的唯一...

    Hibernate 配置跟数据库字段的对应关系

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库,而无需关心底层SQL语句。本文将深入探讨如何在Hibernate配置中设置与数据库字段的对应关系,以及...

    hibernate需要的jar包们

    在使用Hibernate时,确保正确配置并包含必要的JAR(Java Archive)文件至关重要,因为这些库提供了框架运行所需的功能。下面我们将详细探讨Hibernate所需的JAR包及其作用。 1. **hibernate-core.jar**:这是...

    hibernate(api_介绍)

    在Hibernate中,Transaction提供了原子性和隔离性的保证,确保数据的一致性。 - **Query和Criteria**:这两个接口用于执行数据库查询。Query接口支持HQL(Hibernate Query Language),类似于SQL但面向对象。...

    hibernate(api 介绍).docx

    我们在 Hibernate 应用中使用最广泛的接口,也被称为持久化管理器,提供了相关的数据库操作,比如添、更、删、加、查等基本操作。特点:非线程安全,轻量级,其创建及销毁消耗资源少。每个客户请求对应一个 Session...

    动态添加hibernate domain的属性的例子

    在Hibernate中,动态添加属性的一个常见方法是使用动态扩展的Entity(Dynamic-Entity)。动态扩展Entity允许我们在运行时添加或移除属性,而无需重新编译和部署应用程序。这通常通过实现`org.hibernate.usertype....

    hibernate annotations 中文文档

    《Hibernate Annotations 中文文档》是针对Hibernate框架注解配置的详细指南,旨在帮助开发者更深入地理解和使用Hibernate的注解功能。Hibernate是一个流行的Java对象关系映射(ORM)框架,它允许开发人员将数据库...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  11.2.1 用客户化映射类型取代Hibernate组件  11.2.2 用UserType映射枚举类型  11.2.3 实现CompositeUserType接口  11.2.4 运行本节范例程序  11.3 ...

    VC开发工具使用技巧源代码_usertype.zip

    VC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zipVC开发工具使用技巧源代码_usertype.zip

    hibernate_persistence第02-16章书中源码

    在Hibernate中,你可以通过实现UserType接口来自定义数据类型的映射,使非标准的Java类型能够被持久化。"BKBLX"可能是对“备份策略”的简称,表明这部分内容可能涉及到如何自定义类型以适应特定的备份需求。 7. **...

    hibernate3.2API

    **hibernate3.2 API** 是一个针对Java开发者的重要框架,主要用于简化对象关系映射(ORM)的工作,使得在Java应用中操作数据库变得更加便捷。这个API提供了丰富的接口和类,帮助开发者将业务对象和数据库表之间的...

Global site tag (gtag.js) - Google Analytics