博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate复合主键
阅读量:4199 次
发布时间:2019-05-26

本文共 4741 字,大约阅读时间需要 15 分钟。

哎~~~前一个礼拜csdn博客当掉了,使我都懒得写博客了~~等这博客稳定了再写吧,先转载下一些好文章。

基于业务需求,您会需要使用两个字段来作复合主键,例如在User数据表中,您也许会使用"name""phone"两个字段来定义复合主键。

假设您这么建立User表格:

CREATE
 
TABLE
 
user
 (
    name 
VARCHAR
(
100
NOT
 
NULL
,
    phone 
VARCHAR
(
50
NOT
 
NULL
,
    age 
INT
,
    
PRIMARY
 
KEY
(name, phone)
);

 

 

在表格中,"name""age"被定义为复合主键,在映像时,您可以让User类别直接带有"name""age"这两个属性,而Hibernate要求复合主键类别要实作Serializable接口,并定义equals()hashCode()方法:

User.java

package
 onlyfun.caterpillar;
 
import
 java.io.Serializable;
import
 org.apache.commons.lang.builder.EqualsBuilder;
import
 org.apache.commons.lang.builder.HashCodeBuilder;
 
//
 复合主键类的对应类别必须实作Serializable接口
public
 
class
 User 
implements
 Serializable {
    
private
 String name;
    
private
 String phone;
    
private
 Integer age;
   
    
public
 User() {
    }
 
    
public
 Integer getAge() {
        
return
 age;
    }
 
    
public
 
void
 setAge(Integer age) {
        
this
.age 
=
 age;
    }
 
    
public
 String getName() {
        
return
 name;
    }
 
    
public
 
void
 setName(String name) {
        
this
.name 
=
 name;
    }
 
    
public
 String getPhone() {
        
return
 phone;
    }
 
    
public
 
void
 setPhone(String phone) {
        
this
.phone 
=
 phone;
    }
   
    
//
 必须重新定义equals()与hashCode()
    
public
 
boolean
 equals(Object obj) {
        
if
(obj 
==
 
this
) {
            
return
 
true
;
        }
       
        
if
(
!
(obj 
instanceof
 User)) {
            
return
 
false
;
        }
       
        User user 
=
 (User) obj;
        
return
 
new
 EqualsBuilder()
                 .append(
this
.name, user.getName())
                 .append(
this
.phone, user.getPhone())
                 .isEquals();
       
    }
   
    
public
 
int
 hashCode() {
        
return
 
new
 HashCodeBuilder()
                 .append(
this
.name)
                 .append(
this
.phone)
                 .toHashCode();
    }
}

 

 

equals()hashCode()方法被用作两笔不同数据的识别依据;接着您可以使用<composite-id>在映射文件中定义复合主键与对象的属性对应:

User.hbm.xml

<?
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
="onlyfun.caterpillar.User"
 table
="user"
>
        
<
composite-id
>
            
<
key-property 
name
="name"
                          column
="name"
                          type
="java.lang.String"
/>
            
<
key-property 
name
="phone"
                          column
="phone"
                          type
="java.lang.String"
/>
        
</
composite-id
>
 
        
<
property 
name
="age"
 column
="age"
 type
="java.lang.Integer"
/>
   
    
</
class
>
</
hibernate-mapping
>

 

 

在储存数据方面,复合主键的储存没什么区别,现在的问题在于如何依据复合主键来查询数据,例如使用load()方法,您可以创建一个User实例,并设定复合主键对应的属性,接着再透过load()查询对应的数据,例如:

User user 
=
 
new
 User();
user.setName(
"
bush
"
);
user.setPhone(
"
0970123456
"
);
       
Session session 
=
 sessionFactory.openSession();
//
 以实例设定复合主键并加载对应的数据
user 
=
 (User) session.load(User.
class
, user);
       
System.out.println(user.getAge() 
+
 
"
/t
"
 
+
                                  user.getName() 
+
 
"
/t
"
 
+
                                  user.getPhone());
session.close();
 

 

 

可以将主键的信息独立为一个类别,例如:

UserPK.java

package
 onlyfun.caterpillar;
 
import
 java.io.Serializable;
 
import
 org.apache.commons.lang.builder.EqualsBuilder;
import
 org.apache.commons.lang.builder.HashCodeBuilder;
 
public
 
class
 UserPK 
implements
 Serializable {
    
private
 String name;
    
private
 String phone;
 
    
public
 String getName() {
        
return
 name;
    }
 
    
public
 
void
 setName(String name) {
        
this
.name 
=
 name;
    }
 
    
public
 String getPhone() {
        
return
 phone;
    }
 
    
public
 
void
 setPhone(String phone) {
        
this
.phone 
=
 phone;
    }
   
    
public
 
boolean
 equals(Object obj) {
        
if
(obj 
==
 
this
) {
            
return
 
true
;
        }
       
        
if
(
!
(obj 
instanceof
 User)) {
            
return
 
false
;
        }
       
        UserPK pk 
=
 (UserPK) obj;
        
return
 
new
 EqualsBuilder()
                 .append(
this
.name, pk.getName())
                 .append(
this
.phone, pk.getPhone())
                 .isEquals();
       
    }
   
    
public
 
int
 hashCode() {
        
return
 
new
 HashCodeBuilder()
                 .append(
this
.name)
                 .append(
this
.phone)
                 .toHashCode();
    }
}

 

 

现在User类别的主键信息被分离出来了,例如:

User.java

package
 onlyfun.caterpillar;
 
import
 java.io.Serializable;
 
public
 
class
 User 
implements
 Serializable {
    
private
 UserPK userPK; 
//
 主键
    
private
 Integer age;
   
    
public
 User() {
    }
 
    
public
 UserPK getUserPK() {
        
return
 userPK;
    }
 
    
public
 
void
 setUserPK(UserPK userPK) {
        
this
.userPK 
=
 userPK;
    }
 
    
public
 Integer getAge() {
        
return
 age;
    }
 
    
public
 
void
 setAge(Integer age) {
        
this
.age 
=
 age;
    }
}

 

 

在映像文件方面,需要指定主键类的信息,例如:

User.hbm.xml

<?
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
="onlyfun.caterpillar.User"
 table
="user"
>
        
<
composite-id 
name
="userPK"
                      class
="onlyfun.caterpillar.UserPK"
                      unsaved-value
="any"
>
            
<
key-property 
name
="name"
                          column
="name"
                          type
="java.lang.String"
/>
            
<
key-property 
name
="phone"
                          column
="phone"
                          type
="java.lang.String"
/>
        
</
composite-id
>
       
        
<
property 
name
="age"
 column
="age"
 type
="java.lang.Integer"
/>
   
    
</
class
>
 
</
hibernate-mapping
>

 

 

在查询数据时,必须指定主键信息,例如:

UserPK pk 
=
 
new
 UserPK();
pk.setName(
"
bush
"
);
pk.setPhone(
"
0970123456
"
);
      
Session session 
=
 sessionFactory.openSession();
//
 以主键类实例设定复合主键并加载对应的数据
User user 
=
 (User) session.load(User.
class
, pk);
      
System.out.println(user.getAge() 
+
 
"
/t
"
 
+
                                  user.getUserPK().getName() 
+
 
"
/t
"
 
+
                                  user.getUserPK().getPhone());
session.close();
你可能感兴趣的文章
(七)Git--自定义Git
查看>>
(五)Git--分支管理
查看>>
(四)Git--远程仓库
查看>>
(六) Git--标签管理
查看>>
java中继承,子类是否继承父类的构造函数
查看>>
什么是Spring Cloud ?
查看>>
pyqt实现界面化编程
查看>>
qt写DLL文件并调用和出现的问题分析
查看>>
工厂模式(Factory)-设计模式(一)
查看>>
建造者模式(Builder)-设计模式(三)
查看>>
初学Java必备基础知识,编程领域你需要掌握的关键点!
查看>>
阿里五年Java程序员的总结,献给还在迷茫中的你!
查看>>
程序员身上有异味,同事为什么都不会直接告诉他?
查看>>
Java、C、C+ +、PHP、Python分别用来开发什么?一篇文章告诉你!
查看>>
Linux-SHELL常用命令
查看>>
Linux-网络运维基础
查看>>
Verilog编程网站学习——门电路、组合电路、时序电路
查看>>
android——学生信息显示和添加
查看>>
Android——ImageSwitcher轮流显示动画
查看>>
Android——利用手机端的文件存储和SQLite实现一个拍照图片管理系统
查看>>