Hibernate一对一主键关联(基于annotation注解方式)

[b]前言:使用@OneToOne注解可以建立实体bean之间的一对一的关联. 一对一关联有三种情况: 一是关联的实体都共享同样的主键, 二是其中一个实体通过外键关联到另一个实体的主键 (注意要模拟一对一关联必须在外键列上添加唯一约束). 三是通过关联表来保存两个实体之间的连接关系 (注意要模拟一对一关联必须在每一个外键上添加唯一约束).

(1)共享主键来进行一对一关联映射(单向)[/b]
例子:我们用一个男人只有一个妻子为例


import javax.persistence.*;

@Entity
@Table(name = "husband")
public class Husband {

private int id;
private String name;
private Wife wife;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

//记得cascade一定要有哦要不同时保存时不会保存wife对象
@OneToOne(cascade = { CascadeType.ALL })
@PrimaryKeyJoinColumn
public Wife getWife() {
return wife;
}

public void setWife(Wife wife) {
this.wife = wife;
}

}
---------------------------
@Entity
@Table(name = "wife")
public class Wife {

private int id;
private String name;

@Id
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}
--------------------------
测试方法
public static void installData() {
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();

Husband husband = new Husband();
husband.setName("丁元伟");
Wife wife = new Wife();
wife.setName("不知道");
husband.setWife(wife);

session.save(husband); //只需保存husband就可以同时保存wife了

tx.commit();
/*Hibernate:   生成的sql语句
insert
into
husband
(id, name)
values
(null, ?)
Hibernate:
select
wife_.id,
wife_.name as name5_
from
wife wife_
where
wife_.id=?
Hibernate:
insert
into
wife
(name, id)
values
(?, ?)*/
}
//查询时只需查询husband就可以把wife也查出来


[b](2) 主键来进行一对一关联映射(双向)[/b]

  Husband类不变同上
  Wife类有所改变
@Entity
@Table(name = "wife")
public class Wife {

private int id;
private String name;

private Husband husband;

@Id
@GenericGenerator(name = "pkGenerator", strategy = "foreign", parameters = { @Parameter(name = "property", value = "husband") })
@GeneratedValue(generator = "pkGenerator")
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@OneToOne(cascade = CascadeType.ALL, mappedBy = "wife")
@PrimaryKeyJoinColumn
public Husband getHusband() {
return husband;
}

public void setHusband(Husband husband) {
this.husband = husband;
}

}


----------------测试代码save
public static void installData() {
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();

Husband husband = new Husband();
husband.setName("丁元伟");
Wife wife = new Wife();
wife.setName("不知道");
husband.setWife(wife);//这边得写
wife.setHusband(husband); //这边也得写
session.save(husband); //只需保存husband就可以同时保存wife了

tx.commit();

}
-----------------find
public static void findDate() {
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
/*
因为mappedBy是定义在classes中,即classes类不负责维护级联关系.即维护者是student.所以,
1.要将clsses的数据,赋给student,即用student的setClasses()方法去捆定class数据;
2.在进行数据插入/更新session.save()/session.update()时,最后操作的是student.
*/
/*Husband husband = (Husband) session.get(Husband.class, 1);

System.out.println(husband.getName());

Wife wife = husband.getWife();
System.out.println(wife.getName());*/
//上下都可行
Wife wife = (Wife) session.get(Wife.class, 1);
System.out.println(wife.getName());
Husband husband = wife.getHusband();
System.out.println(husband.getName());
tx.commit();
}


[b](3)一对一外键双向关联(没有中间表)[/b]

@Entity
@Table(name = "husband")
public class Husband {

private int id;
private String name;
private Wife wife;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

//记得cascade一定要有哦要不同时保存时不会保存wife对象
@OneToOne(cascade = CascadeType.ALL, mappedBy = "husband")//必须有cascade

public Wife getWife() {
return wife;
}

public void setWife(Wife wife) {
this.wife = wife;
}

}

---------------------------------------
@Entity
@Table(name = "wife")
public class Wife {

private int id;
private String name;
private Husband husband;

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@OneToOne(cascade = CascadeType.ALL) //必须有cascade
@JoinColumn(name = "husband_id")
public Husband getHusband() {
return husband;
}

public void setHusband(Husband husband) {
this.husband = husband;
}

}
---------------------------------------
public static void installData() {
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();

tx.begin();
Husband husband = new Husband();
husband.setName("张三");
Wife wife = new Wife();
wife.setName("如花");
wife.setHusband(husband);
husband.setWife(wife);
session.save(husband);
//或session.save(wife); 但双方得相互设入对方
tx.commit();
}
-------------------------------------

下面查询时如果只查一方都会带出另一方内容(left outer join关联所以得设置为延迟加载)
/*
因为mappedBy是定义在classes中,即classes类不负责维护级联关系.即维护者是student.所以,
1.要将clsses的数据,赋给student,即用student的setClasses()方法去捆定class数据;
2.在进行数据插入/更新session.save()/session.update()时,最后操作的是student.
*/
Husband husband = (Husband) session.get(Husband.class, 1);

System.out.println(husband.getName());

Wife wife = husband.getWife();
System.out.println(wife.getName());
//上下都可行
/*Wife wife = (Wife) session.get(Wife.class, 1);
System.out.println(wife.getName());
Husband husband = wife.getHusband();
System.out.println(husband.getName());*/


4)一对一外键单向关联(没有中间表)

单向关联就是一边不设关联

//这边没有设置关联操作其他的和上面3的一样

@Entity
@Table(name = "husband")
public class Husband {

private int id;
private String name;


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


}


(5)hibernate 注解一对一关系 关联表关联

请参考
[url]http://gyfbao.blog.sohu.com/166353836.html[/url]

测试关联表时如出现下面这个错,需先主键类持久化或保存相对应的另一个非主键类
org.hibernate.PropertyValueException: not-null property references a null or transient value:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值