http://www.cnblogs.com/fancyzero/archive/2012/06/10/hibernate-one-to-one-annotation.html
——————————————————————————————————————————————————————————
环境:
Hibernate
3.3.
1
Maven 3.0. 4
MySQL 5.5. 13
Myeclipse 8.6. 1
Maven 3.0. 4
MySQL 5.5. 13
Myeclipse 8.6. 1
建表语句:
DROP
TABLE
IF
EXISTS `t_card`;
CREATE TABLE `t_card` (
`cardId` int( 10) unsigned NOT NULL AUTO_INCREMENT,
`cardNumber` char( 18) NOT NULL,
PRIMARY KEY (`cardId`)
) ENGINE =InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET =gb2312;
INSERT INTO `t_card` VALUES ( ' 1 ', ' 440911199008011122 ');
CREATE TABLE `t_card` (
`cardId` int( 10) unsigned NOT NULL AUTO_INCREMENT,
`cardNumber` char( 18) NOT NULL,
PRIMARY KEY (`cardId`)
) ENGINE =InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET =gb2312;
INSERT INTO `t_card` VALUES ( ' 1 ', ' 440911199008011122 ');
DROP
TABLE
IF
EXISTS `t_person`;
CREATE TABLE `t_person` (
`personId` int( 10) unsigned NOT NULL AUTO_INCREMENT,
`personName` varchar( 15) NOT NULL,
`cid` int( 10) unsigned NOT NULL,
PRIMARY KEY (`personId`)
) ENGINE =InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET =gb2312;
INSERT INTO `t_person` VALUES ( ' 1 ', ' fancy ', ' 1 ');
CREATE TABLE `t_person` (
`personId` int( 10) unsigned NOT NULL AUTO_INCREMENT,
`personName` varchar( 15) NOT NULL,
`cid` int( 10) unsigned NOT NULL,
PRIMARY KEY (`personId`)
) ENGINE =InnoDB AUTO_INCREMENT = 2 DEFAULT CHARSET =gb2312;
INSERT INTO `t_person` VALUES ( ' 1 ', ' fancy ', ' 1 ');
Person.java
package com.fancy.po;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* -----------------------------------------
* @文件: Person.java
* @作者: fancy
* @邮箱: fancyzero@yeah.net
* @时间: 2012-6-10
* @描述: 实体类
* -----------------------------------------
*/
/**
* @Entity 声明一个类为实体Bean
* @Table(name = "xx")指定实体类映射的表,如果表名和实体类名一致,可以不指定
*/
@Entity
@Table(name = "t_person")
public class Person {
private Integer personId;
private String personName;
private Card card;
/**
* @Id 映射主键属性,这里采用uuid的主键生成策略
* @GeneratedValue —— 注解声明了主键的生成策略。该注解有如下属性
* strategy 指定生成的策略,默认是GenerationType. AUTO
* GenerationType.AUTO 主键由程序控制
* GenerationType.TABLE 使用一个特定的数据库表格来保存主键
* GenerationType.IDENTITY 主键由数据库自动生成,主要是自动增长类型
* GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列
* generator 指定生成主键使用的生成器
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getPersonId() {
return personId;
}
/**
* @OneToOne:一对一关联
* cascade:级联,它可以有有五个值可选,分别是:
* CascadeType.PERSIST:级联新建
* CascadeType.REMOVE : 级联删除
* CascadeType.REFRESH:级联刷新
* CascadeType.MERGE : 级联更新
* CascadeType.ALL : 以上全部四项
* @JoinColumn:主表外键字段
* cid:Person所映射的表中的一个字段
*/
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "cid")
public Card getCard() {
return card;
}
public String getPersonName() {
return personName;
}
public void setPersonId(Integer personId) {
this.personId = personId;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public void setCard(Card card) {
this.card = card;
}
}
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* -----------------------------------------
* @文件: Person.java
* @作者: fancy
* @邮箱: fancyzero@yeah.net
* @时间: 2012-6-10
* @描述: 实体类
* -----------------------------------------
*/
/**
* @Entity 声明一个类为实体Bean
* @Table(name = "xx")指定实体类映射的表,如果表名和实体类名一致,可以不指定
*/
@Entity
@Table(name = "t_person")
public class Person {
private Integer personId;
private String personName;
private Card card;
/**
* @Id 映射主键属性,这里采用uuid的主键生成策略
* @GeneratedValue —— 注解声明了主键的生成策略。该注解有如下属性
* strategy 指定生成的策略,默认是GenerationType. AUTO
* GenerationType.AUTO 主键由程序控制
* GenerationType.TABLE 使用一个特定的数据库表格来保存主键
* GenerationType.IDENTITY 主键由数据库自动生成,主要是自动增长类型
* GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列
* generator 指定生成主键使用的生成器
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getPersonId() {
return personId;
}
/**
* @OneToOne:一对一关联
* cascade:级联,它可以有有五个值可选,分别是:
* CascadeType.PERSIST:级联新建
* CascadeType.REMOVE : 级联删除
* CascadeType.REFRESH:级联刷新
* CascadeType.MERGE : 级联更新
* CascadeType.ALL : 以上全部四项
* @JoinColumn:主表外键字段
* cid:Person所映射的表中的一个字段
*/
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "cid")
public Card getCard() {
return card;
}
public String getPersonName() {
return personName;
}
public void setPersonId(Integer personId) {
this.personId = personId;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public void setCard(Card card) {
this.card = card;
}
}
Card.java
package com.fancy.po;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* -----------------------------------------
* @文件: Card.java
* @作者: fancy
* @邮箱: fancyzero@yeah.net
* @时间: 2012-6-10
* @描述: 实体类
* -----------------------------------------
*/
@Entity
@Table(name = "t_card")
public class Card {
private Integer cardId;
private String cardNumber;
private Person person;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getCardId() {
return cardId;
}
/**
* @OneToOne:一对一关联
* mappedBy = "card":意思是说这里的一对一配置参考了card
* card又是什么呢?card是Person类中的getCard(),注意不是Person类中的
* card属性,Person类中的OneToOne配置就是在getCard()方法上面配的.
* 如果Person类中的getCard()方法改成getIdCard(),其他不变的话,
* 这里就要写成:mappedBy = "idCard"
*/
@OneToOne(mappedBy = "card")
public Person getPerson() {
return person;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardId(Integer cardId) {
this.cardId = cardId;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public void setPerson(Person person) {
this.person = person;
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* -----------------------------------------
* @文件: Card.java
* @作者: fancy
* @邮箱: fancyzero@yeah.net
* @时间: 2012-6-10
* @描述: 实体类
* -----------------------------------------
*/
@Entity
@Table(name = "t_card")
public class Card {
private Integer cardId;
private String cardNumber;
private Person person;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getCardId() {
return cardId;
}
/**
* @OneToOne:一对一关联
* mappedBy = "card":意思是说这里的一对一配置参考了card
* card又是什么呢?card是Person类中的getCard(),注意不是Person类中的
* card属性,Person类中的OneToOne配置就是在getCard()方法上面配的.
* 如果Person类中的getCard()方法改成getIdCard(),其他不变的话,
* 这里就要写成:mappedBy = "idCard"
*/
@OneToOne(mappedBy = "card")
public Person getPerson() {
return person;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardId(Integer cardId) {
this.cardId = cardId;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public void setPerson(Person person) {
this.person = person;
}
}
pom.xml
<
project
xmlns
="http://maven.apache.org/POM/4.0.0"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 " >http://maven.apache.org/xsd/maven-4.0.0.xsd">
< modelVersion >4.0.0 </ modelVersion >
< groupId >com.fancy </ groupId >
< artifactId >hibernate-annotation-on-to-one-example </ artifactId >
< version >0.0.1-SNAPSHOT </ version >
< packaging >jar </ packaging >
< name >hibernate-annotation-on-to-one-example </ name >
< url >http://maven.apache.org </ url >
< properties >
< project.build.sourceEncoding >UTF-8 </ project.build.sourceEncoding >
</ properties >
< dependencies >
<!-- hibernate jar -->
< dependency >
< groupId >org.hibernate </ groupId >
< artifactId >hibernate-entitymanager </ artifactId >
< version >3.3.1.ga </ version >
</ dependency >
<!-- hibernate annotation jar -->
< dependency >
< groupId >org.hibernate </ groupId >
< artifactId >hibernate-annotations </ artifactId >
< version >3.3.1.GA </ version >
</ dependency >
<!-- mysql -->
< dependency >
< groupId >mysql </ groupId >
< artifactId >mysql-connector-java </ artifactId >
< version >5.1.17 </ version >
</ dependency >
< dependency >
< groupId >junit </ groupId >
< artifactId >junit </ artifactId >
< version >3.8.1 </ version >
< scope >test </ scope >
</ dependency >
</ dependencies >
</ project >
xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 " >http://maven.apache.org/xsd/maven-4.0.0.xsd">
< modelVersion >4.0.0 </ modelVersion >
< groupId >com.fancy </ groupId >
< artifactId >hibernate-annotation-on-to-one-example </ artifactId >
< version >0.0.1-SNAPSHOT </ version >
< packaging >jar </ packaging >
< name >hibernate-annotation-on-to-one-example </ name >
< url >http://maven.apache.org </ url >
< properties >
< project.build.sourceEncoding >UTF-8 </ project.build.sourceEncoding >
</ properties >
< dependencies >
<!-- hibernate jar -->
< dependency >
< groupId >org.hibernate </ groupId >
< artifactId >hibernate-entitymanager </ artifactId >
< version >3.3.1.ga </ version >
</ dependency >
<!-- hibernate annotation jar -->
< dependency >
< groupId >org.hibernate </ groupId >
< artifactId >hibernate-annotations </ artifactId >
< version >3.3.1.GA </ version >
</ dependency >
<!-- mysql -->
< dependency >
< groupId >mysql </ groupId >
< artifactId >mysql-connector-java </ artifactId >
< version >5.1.17 </ version >
</ dependency >
< dependency >
< groupId >junit </ groupId >
< artifactId >junit </ artifactId >
< version >3.8.1 </ version >
< scope >test </ scope >
</ dependency >
</ dependencies >
</ project >
Test.java
package com.fancy.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import com.fancy.po.Card;
import com.fancy.po.Person;
/**
* -----------------------------------------
* @文件: Test.java
* @作者: fancy
* @邮箱: fancyzero@yeah.net
* @时间: 2012-6-10
* @描述: 测试类
* -----------------------------------------
*/
public class Test {
public static void main(String[] args) {
// 读取hibernate配置,默认读取classpath下的hibernate.cfg.xml
Configuration conf = new AnnotationConfiguration();
// 构建session工厂
SessionFactory sessionFactory = conf.configure().buildSessionFactory();
// 打开session
Session session = sessionFactory.openSession();
// 开始事务
session.beginTransaction();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// test1(session); // 测试 1
// test2(session); // 测试 2
test3(session); // 测试 3
// * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// 提交事务
session.getTransaction().commit();
// 关闭session工厂
sessionFactory.close();
// 关闭session
session.close();
}
/**
* 数据库初始值:
* personName:fancy
* cardNumber:440911199008011122
*/
// 测试方法1
public static void test1(Session session){
Person person = (Person)session.get(Person. class, 1); // 发出Person和Card的select语句
Card card = person.getCard();
System.out.println(person.getPersonName());
System.out.println(card.getCardNumber());
person.setPersonName("fancy"); // 与初始值一致
card.setCardNumber("440911199008011122"); // 与初始值一致
session.save(person); // 不发出sql语句
// session.save(card); // 不发出sql语句
}
// 测试方法2
public static void test2(Session session){
Person person = (Person)session.get(Person. class, 1); // 发出Person和Card的select语句
Card card = person.getCard();
System.out.println(person.getPersonName());
System.out.println(card.getCardNumber());
person.setPersonName("fancyzero"); // 与初始值不一致
card.setCardNumber("440911199008011122"); // 与初始值一致
session.save(person); // 发出Person的update语句,数据库中personName被修改,不发出Card的update语句
// session.save(card); // 发出Person的update语句,数据库中personName被修改,不发出Card的update语句
}
// 测试方法3
public static void test3(Session session){
Person person = (Person)session.get(Person. class, 1); // 发出Person和Card的select语句
Card card = person.getCard();
System.out.println(person.getPersonName());
System.out.println(card.getCardNumber());
person.setPersonName("fancy"); // 与初始值不一致
card.setCardNumber("440911199008080808"); // 与初始值不一致
session.save(person); // 同时发出Person和Card的update语句,数据库中的数据相应被修改
// session.save(card); // 同时发出Person和Card的update语句,数据库中的数据相应被修改
}
}
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import com.fancy.po.Card;
import com.fancy.po.Person;
/**
* -----------------------------------------
* @文件: Test.java
* @作者: fancy
* @邮箱: fancyzero@yeah.net
* @时间: 2012-6-10
* @描述: 测试类
* -----------------------------------------
*/
public class Test {
public static void main(String[] args) {
// 读取hibernate配置,默认读取classpath下的hibernate.cfg.xml
Configuration conf = new AnnotationConfiguration();
// 构建session工厂
SessionFactory sessionFactory = conf.configure().buildSessionFactory();
// 打开session
Session session = sessionFactory.openSession();
// 开始事务
session.beginTransaction();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// test1(session); // 测试 1
// test2(session); // 测试 2
test3(session); // 测试 3
// * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// 提交事务
session.getTransaction().commit();
// 关闭session工厂
sessionFactory.close();
// 关闭session
session.close();
}
/**
* 数据库初始值:
* personName:fancy
* cardNumber:440911199008011122
*/
// 测试方法1
public static void test1(Session session){
Person person = (Person)session.get(Person. class, 1); // 发出Person和Card的select语句
Card card = person.getCard();
System.out.println(person.getPersonName());
System.out.println(card.getCardNumber());
person.setPersonName("fancy"); // 与初始值一致
card.setCardNumber("440911199008011122"); // 与初始值一致
session.save(person); // 不发出sql语句
// session.save(card); // 不发出sql语句
}
// 测试方法2
public static void test2(Session session){
Person person = (Person)session.get(Person. class, 1); // 发出Person和Card的select语句
Card card = person.getCard();
System.out.println(person.getPersonName());
System.out.println(card.getCardNumber());
person.setPersonName("fancyzero"); // 与初始值不一致
card.setCardNumber("440911199008011122"); // 与初始值一致
session.save(person); // 发出Person的update语句,数据库中personName被修改,不发出Card的update语句
// session.save(card); // 发出Person的update语句,数据库中personName被修改,不发出Card的update语句
}
// 测试方法3
public static void test3(Session session){
Person person = (Person)session.get(Person. class, 1); // 发出Person和Card的select语句
Card card = person.getCard();
System.out.println(person.getPersonName());
System.out.println(card.getCardNumber());
person.setPersonName("fancy"); // 与初始值不一致
card.setCardNumber("440911199008080808"); // 与初始值不一致
session.save(person); // 同时发出Person和Card的update语句,数据库中的数据相应被修改
// session.save(card); // 同时发出Person和Card的update语句,数据库中的数据相应被修改
}
}