2.一对多(对于一对多的关系来说,建议使用双向的外键关联)
1.1单向-》外键关联(由SubTest获取Test)
Test.class(idauto_increment)
SubTest.class
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
privateint id;
@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="ddd")//默认不填JoinColumn会自动生成一个外键字段
privateTest test;
一对多的单向只需在多的类SubTest中设置ManytoOne注解,级联方式的区别在于更新,删除,插入的时候是否对Test也同样进行操作。
单向关联时,在查询时,EARGER方式也是以SubTest左外连接Test。在save数据时,需要关心其级联方式。
1.2单向-》外键关联(由Test获取SubTest)
两个id都为auto_increment
Test.class
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinColumn(name="ddd")
publicList<SubTest> subtests;
由Test获取到SubTest的外键关联只要配置OneToMany和JoinColumn,这样会在SubTest表中多一个外键字段。
1.3单向-》表间关联
Test.class(idauto_increment)
SubTest.class
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
privateint id;
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinTable(name="dog",joinColumns = {@JoinColumn(name="bcd")},
inverseJoinColumns= { @JoinColumn(name = "abc")} )
privateTest test;
表间关联单向在save只需save一个Subtest对象,SubTest对象中需要set一个Test对象。
在查询时,EAGER的方式也是以外连接的方式。多处一个表来维护两个表之间的关系,也是不建议使用。
2.1双向-》外键关联
Test.class
idauto_increment
@OneToMany(cascade=CascadeType.ALL)(方便save保存数据)
@JoinColumn(name="ddd")
publicList<SubTest> subtests;
SubTest.class
idauto_increment
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="ddd")//默认不填JoinColumn会自动生成一个外键字段
privateTest test;
双向的外键关联,只需在Test设置OneToMany,JoinColumn,注意JoinColumn的name需要与SubTest中的JoinColumn的name名字相同。
在save数据的时候,根据级联关系来对save进行操作。在查询数据时,从Test获取到SubTest继续获取Test依旧只会查询Test左外连接SubTest,不用担心多连接关系。
单向和双向的区别只在于查询的时候,能否从一个对象中获取到其包含的对象,在数据库的表现上是一样的。双向外键关联在通过一个对象获取到另一个或者多个对象是,区别在于是谁左外连接谁,一般情况是主要对象左外连接次要对象的表。(次要对象为需要获取的对象)。所以其实,在一对多的关系中没必要去区分单向和双向,都同意规定为双向,即使没有这样的需求。
2.2双向-》表间关联
Test和SubTest的id都为auto_increment
Test.class
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(name="dog",joinColumns = @JoinColumn(name="abc"),
inverseJoinColumns= @JoinColumn(name = "bcd"))
publicList<SubTest> subtests;
SubTest.class
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinTable(name="dog",joinColumns = {@JoinColumn(name="bcd")},
inverseJoinColumns= { @JoinColumn(name = "abc")} )
privateTest test;
双向的表间关联二者都使用JoinTable标签注解,joinColumns为dog表对应自身的字段,inverseJoinColumns为相对应表在dog表的字段,均为外键。SubTest和Test的设置应该相反。字段。
上面介绍了单向和双向的区别。这里再讲讲表间关联和外键关联的区别。单对于一对多的关系来说,维护一对多的关系,在外键关联看来,只需在多的一方(即SubTest)中设置一个外键,而表间关联需要多维护一张关系表。这里的效率不言而喻,使用外键关联的效率反而会比较好。如果要说外键关联在什么时候会比表间关联效率差,可能只有当你只需要查询SubTest的时候,而不需要获取到Test的对象,这时表间关联的SubTest的数据会比外键关联少一个外键字段。(这里我暂时没有考虑到外键对于查询效率的影响),还有就是表间关联能有效减少数据的冗余问题。