次讲@OneToOne的用法。而且是基于主外键的关联。因为这个是实际开发中最最常见的。
这里先说明一下,我的java类的命名都以Test开头。而对应的对象名却没有用test开头。这里是为了更好的说明注视中的value到底是类名还是对象名。
先看java代码:
TestUser
package net.paoding.forum.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class TestUser
{
String id;
String username;
TestCard card;
/**
* @return the id
*/
@Id
public String getId()
{
return id;
}
/**
* @param id the id to set
*/
public void setId(String id)
{
this.id = id;
}
/**
* @return the username
*/
public String getUsername()
{
return username;
}
/**
* @param username the username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* @return the card
*/
@OneToOne
public TestCard getCard()
{
return card;
}
/**
* @param card the card to set
*/
public void setCard(TestCard card)
{
this.card = card;
}
}
TestCard:
package net.paoding.forum.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class TestCard
{
String id;
String cardNumber;
/**
* @return the id
*/
@Id
public String getId()
{
return id;
}
/**
* @param id the id to set
*/
public void setId(String id)
{
this.id = id;
}
/**
* @return the cardNumber
*/
public String getCardNumber()
{
return cardNumber;
}
/**
* @param cardNumber the cardNumber to set
*/
public void setCardNumber(String cardNumber)
{
this.cardNumber = cardNumber;
}
}
这样子就是OneToOne了。这个是单向的关系,即:由TestCard控制TestUser。看sql语句就知道了。
hibernate自动生成的sql为:
drop table test_card cascade constraints;
drop table test_user cascade constraints;
create table test_card (
id varchar2(255 char) not null,
card_number varchar2(255 char),
primary key (id)
);
create table test_user (
id varchar2(255 char) not null,
username varchar2(255 char),
card_id varchar2(255 char),
primary key (id)
);
alter table test_user
add constraint FKB9A96B58A237D846
foreign key (card_id)
references test_card;
个人认为,应该这样子理解OneToOne。
首先,他是用来申明在方法上的。(这句好似废话)
然后,他其实是用来描述这个方法的返回值的。即:描述TestCard的。也就是说:TestCard 为控制方。TestUser为被控方。那么对应的表中,test_user表有一个外键字段对应着test_card表中的一个主键。
这样,就好理解了。
上面的为单向关联。那么,双向关联呢?修改TestCard如下:
package net.paoding.forum.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class TestCard
{
String id;
String cardNumber;
TestUser user;
/**
* @return the id
*/
@Id
public String getId()
{
return id;
}
/**
* @param id the id to set
*/
public void setId(String id)
{
this.id = id;
}
/**
* @return the user
*/
@OneToOne
public TestUser getUser()
{
return user;
}
/**
* @param user the user to set
*/
public void setUser(TestUser user)
{
this.user = user;
}
/**
* @return the cardNumber
*/
public String getCardNumber()
{
return cardNumber;
}
/**
* @param cardNumber the cardNumber to set
*/
public void setCardNumber(String cardNumber)
{
this.cardNumber = cardNumber;
}
}
这样,产生的sql为:
drop table test_card cascade constraints;
drop table test_user cascade constraints;
create table test_card (
id varchar2(255 char) not null,
card_number varchar2(255 char),
user_id varchar2(255 char),
primary key (id)
);
create table test_user (
id varchar2(255 char) not null,
username varchar2(255 char),
card_id varchar2(255 char),
primary key (id)
);
alter table test_card
add constraint FKB9A0FA9D7876DA66
foreign key (user_id)
references test_user;
alter table test_user
add constraint FKB9A96B58A237D846
foreign key (card_id)
references test_card;
可以看到,当我双方都声明了OneToOne时候,也就达到了双向的One2One效果。但是很遗憾。Hibernate不知道你由哪边控制哪边,或者说由哪边来维护关系。所以,他生成的sql语句中可以看到,都有test_card和test_user是相互关联的,即:都有FK关联上堆放的PK。很明显,这个不是我们要的效果。
我们需要的是,po中能双向one2one,但是db中不需要。所以,我们需要修改一下。
修改TestCard.java代码:
package net.paoding.forum.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class TestCard
{
String id;
String cardNumber;
TestUser user;
/**
* @return the id
*/
@Id
public String getId()
{
return id;
}
/**
* @param id the id to set
*/
public void setId(String id)
{
this.id = id;
}
/**
* @return the user
*/
@OneToOne(mappedBy="card")
public TestUser getUser()
{
return user;
}
/**
* @param user the user to set
*/
public void setUser(TestUser user)
{
this.user = user;
}
/**
* @return the cardNumber
*/
public String getCardNumber()
{
return cardNumber;
}
/**
* @param cardNumber the cardNumber to set
*/
public void setCardNumber(String cardNumber)
{
this.cardNumber = cardNumber;
}
}
注意annotation的部分。mappedBy就指出了此处返回的TestUser对应的test_user表中有一个指向TestUser的属性"card"的外键。可以看sql。
drop table test_card cascade constraints;
drop table test_user cascade constraints;
create table test_card (
id varchar2(255 char) not null,
card_number varchar2(255 char),
primary key (id)
);
create table test_user (
id varchar2(255 char) not null,
username varchar2(255 char),
card_id varchar2(255 char),
primary key (id)
);
alter table test_user
add constraint FKB9A96B58A237D846
foreign key (card_id)
references test_card;
而这得"mappedBy=card"中的card是TestUser中的TestCard类型的成员变量名。这也就是为什么我要用Test修饰类名,而对象名却不用的理由。
或者,还可以这样子来理解OneToOne。
单向OneToOne中。声明了OneToOne这个Annotation的方法,他的返回值即:维护方。(主键方)
双向OneToOne中。在OneToOne中声明了mappedBy="xx"的,他的返回值即:被维护方。(外键方)
分享到:
相关推荐
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
Hibernate 快速入门的工程包 包括用xml和annotation映射数据表
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 ...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. ...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 ...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二...
Hibernate原理的模拟,重点讲思路,代码不全部实现,Hibernate的基本配置 Hibernate核心接口介绍,对象的三种状态,Hibernate关系映射:一对一、 一对多 、 多对多。 Hibernate查询(HQL语句的使用)。
本书是《轻量级java ee企业应用实战》的姊妹篇,《轻量级java ee企业应用实战》主要介绍以spring+hibernate为基础的java ee应用;本书则主要介绍以ejb 3+jpa为基础的java ee应用。ejb 3、jpa规范都属于sun公司所...
HibernateValidatorJSR303的参考实现使用指南.pdf JSR 303 的参考实现 使用指南 由 Hardy Ferentschik和Gunnar Morling and thanks to Shaozhuang Liu 4.3.1.Final 版权 © 2009 - 2011 Red Hat, Inc. & Gunnar ...
经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练使用Spring的各项功能的同时,还能透彻理解Spring的内部实现,真正做到知其然知其所以然。...
经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练使用Spring的各项功能的同时,还能透彻理解Spring的内部实现,真正做到知其然知其所以然。...
GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...
GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...