Hibernate對自定義類型UserType的用法
系統
1807 0
Hibernate允許我們自定義映射屬性的類型,比如一個學生有聯系地址,而聯系地址又分為家庭地址和工作地址,我們可以把兩個地址信息抽象成一個新的Address類,作為Student的成員變量
數據庫結構:
?
create
?
table
?typestu?(id?
varchar
(
32
)?
primary
?
key
,name?
varchar
(
32
),homeaddr?
varchar
(
32
),workaddr?
varchar
(
32
));
Hibernate.cfg.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"
>
<!--
?Generated?by?MyEclipse?Hibernate?Tools.???????????????????
-->
<
hibernate-configuration
>
<
session-factory
>
????
<
property?
name
="connection.username"
>
root
</
property
>
????
<
property?
name
="connection.url"
>
????????jdbc:mysql://localhost:3306/schoolproject?characterEncoding=gb2312
&
useUnicode=true
????
</
property
>
????
<
property?
name
="dialect"
>
????????org.hibernate.dialect.MySQLDialect
????
</
property
>
????
<
property?
name
="myeclipse.connection.profile"
>
mysql
</
property
>
????
<
property?
name
="connection.password"
>
1234
</
property
>
????
<
property?
name
="connection.driver_class"
>
????????com.mysql.jdbc.Driver
????
</
property
>
????
<
property?
name
="hibernate.dialect"
>
????????org.hibernate.dialect.MySQLDialect
????
</
property
>
????
<
property?
name
="hibernate.show_sql"
>
true
</
property
>
????
<
property?
name
="current_session_context_class"
>
thread
</
property
>
????
<
mapping?
resource
="Search/UserType/Student.hbm.xml"
?
/>
</
session-factory
>
</
hibernate-configuration
>
?Pojo
?
package
?Search.UserType;
public
?
class
?Student?
...
{
????
private
?String?id;?
//
標識id
????
private
?String?name;?
//
學生姓名
????
private
?AddressType?address;
//
地址
????
public
?String?getId()?
...
{
????????
return
?id;
????}
????
public
?
void
?setId(String?id)?
...
{
????????
this
.id?
=
?id;
????}
????
public
?String?getName()?
...
{
????????
return
?name;
????}
????
public
?
void
?setName(String?name)?
...
{
????????
this
.name?
=
?name;
????}
????
public
?AddressType?getAddress()?
...
{
????????
return
?address;
????}
????
public
?
void
?setAddress(AddressType?address)?
...
{
????????
this
.address?
=
?address;
????}
?
?
?
}
?
自定義類型
?
package
?Search.UserType;
import
?java.io.Serializable;
import
?java.sql.PreparedStatement;
import
?java.sql.ResultSet;
import
?java.sql.SQLException;
import
?java.sql.Types;
import
?org.apache.commons.lang.builder.EqualsBuilder;
import
?org.apache.commons.lang.builder.HashCodeBuilder;
import
?org.hibernate.HibernateException;
import
?org.hibernate.usertype.UserType;
public
?
class
?AddressType?
implements
?UserType,?Serializable?
...
{
????
private
?String?homeAddr;
????
private
?String?workAddr;
????
/**/
/*
?有幾個字段就有幾個值,這里容易出錯,要多注意?
*/
????
private
?
static
?
final
?
int
[]?SQL_TYPES?
=
?
...
{?Types.VARCHAR,?Types.VARCHAR?}
;
????
/**/
/*
?這個方法告訴Hibernate在成生DDL時對列采用什么樣的SQL語法?
*/
????
public
?
int
[]?sqlTypes()?
...
{
????????
return
?SQL_TYPES;
????}
????
/**/
/*
?????*?Hibernate返回什么樣的映射類型,與?<property?name="address"?type="model.AddressType">
?????*?指定的類一致。事實上也可以把AddressType拆分為兩個類,一個類是只攜帶信息的JavaBean,它里面
?????*?沒有邏輯操作也沒有實現UserType(比如AddressBean);而另一個類實現了UserType,它所面對的就不是現在這個
?????*?AddressType類的homeAddr和homeAddr屬性,它面對的是AddressBean。在本例中為了簡潔方便,只用了一個類。
?????
*/
????
public
?Class?returnedClass()?
...
{
????????
return
?AddressType.
class
;
????}
????
/**/
/*
?????*?表明這個類的實例在創建以后就不可以改變屬性。Hibernate能為不可改變的類作一些性能優化。
?????
*/
????
public
?
boolean
?isMutable()?
...
{
????????
return
?
false
;
????}
????
/**/
/*
?????*?由于AddressType是不可變的,所以深拷貝可以直接返回對象引用。拷貝的對象由應用程序使用,?而原版對象由Hibernate維護以做臟數據檢查
?????
*/
????
public
?Object?deepCopy(Object?value)?
...
{
????????
return
?value;?
//
?Address?is?immutable
????}
????
/**/
/*
?兩個對象是否相等,使用了apache的common工具包來進行屬性比對?
*/
????
public
?
boolean
?equals(Object?x,?Object?y)?
...
{
????????
if
?(x?
==
?y)
????????????
return
?
true
;
????????
if
?(x?
==
?
null
?
||
?y?
==
?
null
)
????????????
return
?
false
;
????????AddressType?add1?
=
?(AddressType)?x;
????????AddressType?add2?
=
?(AddressType)?y;
????????
return
?
new
?EqualsBuilder()?
//
使用EqualsBuilder類來方便地進行比對
????????????????.append(add1.getHomeAddr(),?add2.getHomeAddr()).append(
????????????????????????add2.getWorkAddr(),?add2.getWorkAddr()).isEquals();
????}
????
/**/
/*
?得到hash碼?
*/
????
public
?
int
?hashCode(Object?x)?
throws
?HibernateException?
...
{
????????AddressType?address?
=
?(AddressType)?x;
????????
return
?
new
?HashCodeBuilder()
//
使用HashCodeBuilder類來方便地進行比對
????????????????.append(address.getHomeAddr()).append(address.getWorkAddr())
????????????????.toHashCode();
????}
????
/**/
/*
?讀取數據并組裝成一個AddressType對象。names[]中的參數順序依照映射文件中定義的順序?
*/
????
public
?Object?nullSafeGet(ResultSet?rs,?String[]?names,?Object?owner)
????????????
throws
?HibernateException,?SQLException?
...
{
????????
if
?(rs.wasNull())
????????????
return
?
null
;
????????String?homeAddr?
=
?rs.getString(names[
0
]);
????????String?schoolAddr?
=
?rs.getString(names[
1
]);
????????AddressType?address?
=
?
Hibernate對自定義類型UserType的用法
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元