Hibernate4注解详解之一对一对象映射

1.一对一(在考虑一对一的设计模式中优先选择主键关联方式,无论是单向还是双向

         1.1单向-》主键关联(Test->SubTest)从SubTest能获取Test对象

         Test.class(idauto_increment)                                           

         SubTest.class

         @Id

         @GenericGenerator(name ="pkGenerator",strategy="foreign",parameters={@Parameter(name = "property", value ="test")})

    @GeneratedValue(generator="pkGenerator")

         @Column(name="id")

         privateint id;

         @OneToOne

         //@JoinColumn(name="ddd") 默认不填JoinColumn会自动生成一个外键字段

         //@PrimaryKeyJoinColumn 这样的对应的外键变为主键关联

         @PrimaryKeyJoinColumn

         privateTest test;

(主键关联必须采用@PrimaryKeyJoinColumn否则默认采用@JoinColumn这时会在SubTest表中多出一个字段,且有外键关联Test的主键约束)

主键策略必须为外键,虽然建表是没有外键约束。但在对SubTest的对象进行save时,会因为你的外键策略,先插入Test表的数据,获取Test记录的主键id为SubTest表的主键Id,然后进行insert。这样两张表的数据的主键id值一样,所以是主键关联,但是是单向的,只能从SubTest的对象中获取到Test的对象数据。在获取的同时,如果获取方式为LAZY的方式,则会先获取SubTest表的记录,通过主键的id,在去查询Test记录。如果方式是EAGER,则会通过SubTest左外连接Test(保留SubTest表,如果Test没有满足条件的记录则值为空(select的为空的字段,不受本身数据库字段是否能为空约束。)),条件为主键关联。

(级联方式还没测试)

         1.2单向-》外键关联

         Test.class(idauto_increment)                                           

         SubTest.class

         @Id

   @GeneratedValue

         @Column(name="id")

         privateint id;

         @OneToOne

         @JoinColumn(name="ddd")//默认不填JoinColumn会自动生成一个外键字段

         privateTest test;

(当使用外键关联必须使用@JoinColumn否则不会生成外键。使用则会产生外键约束。)

两个表的主键策略都选择auto_increment,在SubTest表中会多一个字段,受到Test表的id 的外键约束。与1.1主键关联的约束不同的是,主键关联约束只需在SubTest对象中set一个Test对象,然后save一个SubTest对象即可完成两表的insert操作。而外键关联需要在SubTest对象中set一个Test对象,然后通过先save一个Test对象的条件,获取到Test记录保存的id才能save一个SubTest对象。总的来说,外键关联需要对两个对象都进行save操作,而且有先后顺序。

         1.3单向-》表间关联

         Test.class(idauto_increment)

         @Id

   @GeneratedValue

         @Column(name="id")

         privateint id;

         @OneToOne

         @JoinTable(name="dog",joinColumns = @JoinColumn(name="bcd"),  

         inverseJoinColumns= { @JoinColumn(name = "abc") } )

         privateTest test;

        

表间关联需要使用@JoinTable(name="dog", joinColumns =@JoinColumn(name="bcd"),  

         inverseJoinColumns = { @JoinColumn(name = "abc") })

dog为关系表的名称,bcd,abc为dog表的外键约束,受SubTest的主键约束,abc受Test的主键约束。表间关联会额外产生一张关系表。同时需要对两个对象SubTest和Test都进行save操作。(其中,SubTest对象需要set一个Test对象)

        

         2.1双向-》主键关联

         Test.class

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         @Column(name="id")

         privateint id;

         @OneToOne

         @PrimaryKeyJoinColumn

         publicSubTest subtest;

        

         SubTest.class

         @Id

         @GenericGenerator(name="pkGenerator",strategy="foreign" ,parameters={@Parameter(name= "property", value = "test")})

    @GeneratedValue(generator="pkGenerator")

         @Column(name="id")

         privateint id;

         @OneToOne

         @PrimaryKeyJoinColumn

         privateTest test;

 

双向的主键关联只能在一个类中(Test或者SubTest)的主键(id)策略上设置外键策略,并指向另一个的主键,另一个类为自动增长策略。同时两者都需要有OneToOne和PrimaryKeyJoinColumn的注解。这样两个类的区别在于,在save有一个数据的时候,只需对设置外键策略的对象进行save操作,(前提是SubTest对象中set一个Test对象),即可对两表完成insert操作。(其实这里已经不考虑Test对象中是否set了一个SubTest对象,无论是否为空,或者set了一个新的SubTest对象)

在查询时,都可从一个对象中获取到另一个对象。如果是从SubTest中获取Test对象,则SubTest的表会左外连接Test表。其次则相反。

         2.2双向-》外键关联

         Test.class

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         @Column(name="id")

         privateint id;

         @OneToOne

         @JoinColumn(name="eee")

         publicSubTest subtest;

         SubTest.class

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         @Column(name="id")

         privateint id;

         @OneToOne

         @JoinColumn(name="ddd")//默认不填JoinColumn会自动生成一个外键字段

         privateTest test;

    双向的外键关联对于两个类的配置一样,都需要OneToOne和JoinColumn注解,在save数据时,需要同时save两个对象SubTest和Test,并且两个对象需要互相set对方,否则没有set的一方在save时,外键约束的字段值为空。

    若对OneToOne的注解没有设置fetch方式,默认为EAGER,如此当我们只获取SubTest时,会去左外连接Test。我们获取SubTest下的Test对象是,SubTest左外连接Test,继续左外连接SubTest。这样的效率是非常低的,我个人建议将加载方式设置成LAZY。

   2.3双向-》表间关联(不建议使用

         查询时候的链接表重复链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值