1,一对一外键映射
(1)表结构:tuser表:
tpass表:
(2)bean:
Tuser:
@Entity
@Table(name="tuser")
public class TUser implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="name")
private String name
//一对一外键关联,主表,外键字段是pass_id,对应的表是tpass。
@OneToOne(fetch=FetchType.EAGER,optional=true)
@JoinColumn(name="pass_id",insertable=true,unique=true)
private TPass tPass;
...get,set
}
Tpass:
@Entity
@Table(name="tpass")
public class TPass implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="cardno")
private String cardno;
//一对一外键关联,从表,mappedBy字段必须是主表的字段
@OneToOne(cascade=CascadeType.MERGE,fetch=FetchType.EAGER,optional=true,mappedBy="tPass")
private TUser user;
。。。set,get
}
(3)测试:
TUser user=new TUser();
user.setName("hyman");
TPass pass=new TPass();
pass.setCardno("4311");
user.settPass(pass);
pass.setUser(user);
session.save(user);
session.save(pass);
2,一对一主键映射–单向关联:person 和 card 表一对一关联,person表示主表,card是从表
(1)表结构
(2)bean:
@Entity
@Table(name="person")
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
//person表的主键生成策略根据情况自行选择,mysql一般是自增,oracle一般是序列
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(name="name")
private String name;
//必须指定@PrimaryKeyJoinColumn,否则会在person表中多出一列,并且作为外键进行关联
@OneToOne(cascade=CascadeType.ALL)
@Fetch(value=FetchMode.SELECT)//查询关联数据时采用select的方式而不是左外连接
@PrimaryKeyJoinColumn //代表是主键关联
private Card card;
...get,set...
}
@Entity
@Table(name="card")
public class Card implements Serializable {
private static final long serialVersionUID = 1L;
//设置主键生成方式为person表的主键
@Id
@GenericGenerator(name="foreignGenerator",strategy="foreign",
parameters={@Parameter(value="person",name="property")})
@GeneratedValue(generator="foreignGenerator")
private int id;
@Column(name="cardno")
private String cardno;
//mappedBy属性必须是person类的关联属性名
@OneToOne(mappedBy="card",fetch=FetchType.LAZY)
private Person person;
...set,get...
}
(3)测试:
–保存记录
Person person=new Person();
person.setName("hyman");
Card card=new Card();
card.setCardno("1111");
card.setPerson(person);
person.setCard(card);
session.save(person);
–获取记录
Person person=(Person)session.get(Person.class, 1);
System.out.println(person.getName());
System.out.println(person.getCard().getId());
System.out.println(person.getCard().getCardno());
–更新记录
Person person=(Person)session.get(Person.class, 2);
person.setName("haha");
session.save(person);
–删除记录
Person person=(Person)session.get(Person.class, 1);
session.delete(person);//由于设置了cascade=CascadeType.ALL,card表中的记录也会被删除
3,一对一主键映射–双向关联 –person 和 card 表一对一双向关联
(1)数据库和上面一样,Person类写法和上面一样,Card类需要做些调整,如下:
@OneToOne(targetEntity=Person.class,mappedBy="card",cascade=CascadeType.ALL)
@PrimaryKeyJoinColumn(name="id",referencedColumnName="id")
private Person person;
这样就可以实现person和card的双向关系了:
(2)测试:
与上面单向关联的区别在于,单向关联只能通过主表来查询从表的信息,而双向关联则可以从任何一张表出发来获取另一张表的记录。
例如:
-- 保存记录时,单向关联必须写:session.save(person),而双向关联时写session.save(card)也可以实现相同效果。
-- 删除记录时,单向关联必须写:session.delete(person),而双向关联时写session.delete(card)也可以实现相同效果。