实体关系映射(四)

一、实体关系概述    
    实体关系是指实体与实体之间的关系,从方向上分为单向关联和双向关联;从实体数量上分一对一,一对多和多对多。
1、实体关系的方向性 
1)单向关联
    单向关联是一个实体中引用了另外一个实体。简单地说,就是通过一个实体可以获得另一个实体对象。
例如,实体A对实体B的单向关联。
实体A的代码如下:

01

public class EntityA {<span style="font-family:Verdana;"></span> private EntityB entityB;

02

 

 

03

  public EntityB getEntityB() {

04

    return entityB;

 

05

  }

06

   

 

07

  public void setEntityB(EntityB entityB) {

08

    this.entityB = entityB;

 

09

  }

10

}

实体B的代码如下:

1

public class EntityB {}


2)双向关联
此时实体A的代码不变,将实体B的代码修改为:

1

public class EntityB {

2

  private EntityA entityA;

 

3

  //省略getter、setter方法

4

}


2、实体关系的数量性
1)一对一
  一对一是一个实体只能获得一个实体的引用,如上所述
2)一对多
  一个实体可以获得多个实体的引用,如:

1

public class EntityA {

2

  private Collection<EntityB> entitys;

 

3

  // 省略getter、setter方法

4

}


3)多对多
此时实体A代码如一对多一样,而实体B代码改为:

1

public class EntityB {

2

  private Collection<EntityA> entitys;

 

3

  // 省略getter、setter方法

4

}


二、一对一(@OneToOne
  下面以客户实体(CustomerEO)与地址实体(AddressEO)为例
 1、单向关联
假设一个客户对应一个地址,在数据库中表customer和表address定义的结构SQL语句如下:

01

--客户表

02

create table customer (

 

03

  id int(20) not null auto_increment,

04

  name varchar(100),

 

05

  address_id int(20),

06

  primary key (id)

 

07

)

08

--地址表

 

09

create table address (

10

  id int(20) not null auto_increament,

 

11

  province varchar(50),

12

  city varchar(50),

 

13

  postcode varcahr(50),

14

  detail varchar(50),

 

15

  primary key (id)

16

)

此时将表customer映射为CustomerEO,代码如下:

01

@Entity

02

@Table(name="customer")

 

03

public class CustomerEO implements java.io.Serializable {

04

  @Id

 

05

  @GeneratedValue(strategy = GenerationType.AUTO)

06

  private Integer id;

 

07

 

08

  @OneToOne(cascade = { CascadeType.ALL })

 

09

  @JoinColumn(name = "address_id")

10

  private AddressEO address;

 

11

 

12

  。。。

 

13

}

将表address映射为AddressEO实体,代码如下:

01

@Entity

02

@Table(name="address")

 

03

public class AddressEO implements java.io.Serializable {

04

  @Id

 

05

  @GeneratedValue(strategy = GenerationType.AUTO)

06

  private Integer id;

 

07

   

08

  private String province;

 

09

  private String city;

10

  ...

 

11

  //省略getter、setter方法

12

}


现在来看看@OneToOne的定义:

1

@Target({METHOD, FIELD}) @Retention(RUNTIME)

2

public @interface OneToOne {

 

3

 Class targetEntity() default void.class;

4

 CascadeType[] cascade() default ();

 

5

 FetchType fetch() default EAGER;

6

 boolean optional() default true;

 

7

 String mappedBy() default "";

8

}

使用@OneToOne标记是,需要注意:
atargetEntity 属性表示默认关联的实体类型,默认为当前标注的实体类。
bcascade属性表示与此实体一对一关联的实体的级联样式类型。
cfetch属性是该实体的加载方式,默认为即时加载EAGER
doptional属性表示关联的该实体是否能够存在null值,默认为ture,如果设置为false,则该实体不能为null,并且要配合使用@JoinColumn标记,将实体关系关系设置为唯一的,不为null而且不能更新,代码如下:

1

@OneToOne(optional=false)

2

@JoinColumn(name="address_id", unique=true, nullable=false, updatable=false)

 

3

private AddressEo address;

 

emappedBy属性用于酸性关联实体时,标注在不保存关系的实体中。后讲

下面讲下@JoinColumn标记:

01

@Target({METHOD, FIELD}) @Retention(RUNTIME)

02

public @interface JoinColumn {

 

03

 String name() default "";

04

 String referencedColumnName() default "";

 

05

 boolean unique() default false;

06

 boolean nullable() default true;

 

07

 boolean insertable() default true;

08

 boolean updatable default true;

 

09

 String columnDefinition() default "";

10

 String table() default "";

 

11

}


使用@JoinColumn标记是,需要注意一下几点: 
a@JoinColumn@Column标记一样,是用来注释表中的字段的,它的属性和@Column有很多相似之处,不在详述。 
b、但是它们的区别在于:@JoinColumn注释是保存表与表之间关系的字段 
c、如果不设置name,默认为name = 关联表的名称+"-"+关联表主键的字段名,在上面实例中,默认为“address_id” 
e、默认情况下,关联的实体的主键一般是用来做外键的,但如果此时不想用主键作为外键,则需要设置referencedColumnName属性,例如: 

1

create table address (

2

  id int(20) not null auto_increament,

 

3

  ref_id int(20) not null,

4

  province varchar(50),

 

5

  city varchar(50),

6

  postcode varcahr(50),

 

7

  detail varchar(50),

8

  primary key (id)

 

9

)

实体类中修改为:

1

@OneToOne

2

@JoinColumn(name="address_id", referencedColumnName="ref_id")

 

3

private AddressEO address;


2、双向关联 
前面只能通过实体CustomerEO对象来获得AddressEO对象,是单向关联,若在AddressEO中加入CustomerEO的引用,即为双向关联 
双向关联后AddressEO实体的代码为: 

01

@Entity

02

@Table(name="address")

 

03

public class AddressEO implements java.io.Serializable {

04

  ...

 

05

  @OneToOne(mappedBy="address")

06

  private CustomerEO customer;

 

07

  ...

08

  

 

09

  

10

}

其中mappedBy属性用来指明所映射的实体关系,它的值为所关联实体中该属性的名称,如在CustomerEO实体中address为它的属性存在。

3、主键关联(@PrimaryKeyJoinColumn
在上面使用的字段关联,现在谈下主键关联,在两个表的结构中customer表中,去掉address_id字段,其他不变。但是实体类配置修改为:

01

@Entity

02

@Table(name="customer")

 

03

public class CustomerEO implements java.io.Serializable {

04

  ...

 

05

  @OneToOne(cascade = { CascadeType.ALL })

06

  @PrimaryKeyJoinColumn

 

07

  private AddressEO address;

08

  

 

09

  ...

10

}

 

11

 

12

@Entity

 

13

@Table(name="address")

14

public class AddressEO implements java.io.Serializable {

 

15

  ...

16

  @OneToOne

 

17

  @PrimaryKeyJoinColumn

18

  private CustomerEO customer;

 

19

   

20

  ...

 

21

 

22

}

@PrimarKeyJoinColumn注释定义如下:

1

@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)

2

public @interface PrimaryKeyJoinColumn {

 

3

  String name() default "";

4

  String referencedColumnName() default "";

 

5

  String columnDefinition() default "";

6

}


4、默认关联 
在建立customeraddress后,加入外键约束如: 

1

alter table customer add constraint fk_custommer_address

2

foreign key (address_id) references address (id);

 

则在实体类中只需要加@OneToOne标记即可

注:使用外键利用的是数据库底层的机制,有利于数据的完整性。但是外键减少了数据的灵活性。

5、最后,说下一对一映射的一般步骤:
1)第一步,确定实体与实体的关系,如果是一对一,则要使用@OneToOne注释
2)第二步,考虑表结构的设计。
  a、若使用外键关联,则考虑默认关联。
  b、若使用主键关联,则需要配合@PrimaryKeyColumn注释
  c、若使用字段关联,则需要配合@JoinColumn注释使用
3)第三部,考虑实体关系的方向性。

今天现在到这里,码字累了,明天继续写关于@OneToMany@ManyToOne@ManyToMany的内容。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值