您的位置:首页 > 其它

Hibernate关系映射(二)一对一双向外键关联@OneToOne Annotation方式

2015-02-27 09:57 645 查看
在上一篇,也就是Hibernate关系映射(一)中已经介绍了一对一单向外键关联,本篇介绍一对一双向外键关联

首先还是来构造一个实际应用的场景,比如实体类车辆(Car),它具有以下属性:Id,品牌(brand),车牌(lisencePlate);实体类车牌(LisencePlate),它具有以下属性:Id,号码(number),所属车辆(car)。那么车辆和车牌是一对一的关系,一辆车只能有一个车牌,一个车牌也只能属于一辆车,不允许套牌,典型的一对一关系,依然是根据PowerDesigner反向工程反向出来的表结构如图:



car这个表中有一个字段lisencePlate_id作为外键指向了lisence_plate表的主键id字段。

重点内容

看表结构,单向关联的表结构和双向关联的表结构在数据库中的表示是一致的,但是单向关联和双向关联的区别在于,双向关联,你可以用car.getLisencePlate来找到该车辆的车牌,也可以用lisencePlate.getCar来找到该车牌所属车辆,但是单向关联只能从车找到车牌,或者从车牌找到车。

下面是实体类:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="car")
public class Car {

private Integer id;
private String brand;
private LisencePlate lisencePlate;

public Car() {
super();
}

public Car(Integer id, String brand, LisencePlate lisencePlate) {
super();
this.id = id;
this.brand = brand;
this.lisencePlate = lisencePlate;
}

@Id
@GeneratedValue
public Integer getId() {
return id;
}

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

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

@OneToOne
public LisencePlate getLisencePlate() {
return lisencePlate;
}

public void setLisencePlate(LisencePlate lisencePlate) {
this.lisencePlate = lisencePlate;
}

}


每一个使用到的标签的含义在上一篇介绍过了,这里不再赘述。

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="lisence_plate")
public class LisencePlate {
private Integer id;
private String number;
private Car car;

public LisencePlate() {
super();
}

public LisencePlate(Integer id, String number, Car car) {
super();
this.id = id;
this.number = number;
this.car = car;
}

@Id
@GeneratedValue
public Integer getId() {
return id;
}

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

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}

@OneToOne(mappedBy="lisencePlate")
public Car getCar() {
return car;
}

public void setCar(Car car) {
this.car = car;
}

}


注意:双向关联,那么在车牌类中也需要一个属性,所属车辆(car),设置上get和set方法后,在get方法上有这么一个标签@OneToOne(mappedBy=”lisencePlate”),@OneToOne表示车牌和车辆也是一对一的关系并且关联上车辆,mappeBy表示被谁映射,并且mappedBy应该存在于“被拥有方”,指向“拥有方”,那么指向拥有方应该指向车辆类,mappedBy=”lisencePlate”表示指向车辆类的lisencePlate属性,表示被lisencePlate属性映射,并且lisencePlate是主导。

重点内容

双向关联必须设置mappedBy

最后在hibernate.cfg.xml配置文件中设置上实体的映射就可以了

<!-- 一对一双向外键关联 -->
<mapping class="com.ht.entity.one2one.bi.fk.Car"/>
<mapping class="com.ht.entity.one2one.bi.fk.LisencePlate"/>


下面来看CRUD的测试,首先测试添加新数据testCreate()方法

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.ht.entity.one2one.bi.fk.Car;
import com.ht.entity.one2one.bi.fk.LisencePlate;

public class One2OneTest2 {

private static SessionFactory sessionFactory;

@BeforeClass
public static void beforeClass() {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}
@AfterClass
public static void afterClass() {
sessionFactory.close();
}

@Test
public void testCreate(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

Car car = new Car();
car.setBrand("Jeep Grand Cherokee");

LisencePlate lisencePlate = new LisencePlate();
lisencePlate.setNumber("云A 12345");

car.setLisencePlate(lisencePlate);
lisencePlate.setCar(car);

session.save(lisencePlate);
session.save(car);

session.getTransaction().commit();
}


结果如图:

Hibernate:
insert
into
lisence_plate
(number)
values
(?)
Hibernate:
insert
into
car
(brand, lisencePlate_id)
values
(?, ?)






接下来测试数据读取,testRead()方法

@Test
public void testRead(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

Car car = (Car) session.load(Car.class, 1);
System.out.println(car.getBrand()+"  "+car.getLisencePlate().getNumber());

LisencePlate lisencePlate = (LisencePlate) session.load(LisencePlate.class, 1);
System.out.println(lisencePlate.getNumber()+"  "+lisencePlate.getCar().getBrand());

session.getTransaction().commit();
}


这里就体现了双向关联和单向关联的区别,双向关联可以从车辆找到车牌信息,也可以从车牌找到所属车辆的信息。

Hibernate:
select
car0_.id as id2_1_,
car0_.lisencePlate_id as lisenceP3_2_1_,
car0_.brand as brand2_1_,
lisencepla1_.id as id3_0_,
lisencepla1_.number as number3_0_
from
car car0_
left outer join
lisence_plate lisencepla1_
on car0_.lisencePlate_id=lisencepla1_.id
where
car0_.id=?
Hibernate:
select
car0_.id as id2_1_,
car0_.lisencePlate_id as lisenceP3_2_1_,
car0_.brand as brand2_1_,
lisencepla1_.id as id3_0_,
lisencepla1_.number as number3_0_
from
car car0_
left outer join
lisence_plate lisencepla1_
on car0_.lisencePlate_id=lisencepla1_.id
where
car0_.lisencePlate_id=?

Jeep Grand Cherokee  云A 12345
云A 12345  Jeep Grand Cherokee


下面测试修改数据,testUpdate()方法

@Test
public void testUpdate(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

Car car = (Car) session.load(Car.class, 1);
car.setBrand("Jeep大切诺基");

LisencePlate lisencePlate = (LisencePlate) session.load(LisencePlate.class, 1);
lisencePlate.setNumber("云A 66666");

session.saveOrUpdate(car);
session.saveOrUpdate(lisencePlate);

session.getTransaction().commit();
}


结果如下:

Hibernate:
update
lisence_plate
set
number=?
where
id=?
Hibernate:
update
car
set
lisencePlate_id=?,
brand=?
where
id=?






最后是删除操作,testDelete()方法,一样的,如果只是删除车牌,那么就要先解除该车牌和所属车辆之间的约束

@Test
public void testDelete(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();

Car car = (Car) session.load(Car.class, 1);

LisencePlate lisencePlate = (LisencePlate) session.load(LisencePlate.class, 1);

car.setLisencePlate(null);
session.delete(lisencePlate);

session.getTransaction().commit();
}


结果如下:

Hibernate:
update
car
set
lisencePlate_id=?,
brand=?
where
id=?
Hibernate:
delete
from
lisence_plate
where
id=?






希望对你所有帮助,下一篇介绍多对一的单向关联

[上一篇 Hibernate关系映射(一)一对一单向外键关联@OneToOne Annotation方式](/article/11175517.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: