hibernate一对一关联OneToOne

知兮丶青
阅读(349) 2017-12-26
hibernate一对一关联OneToOne
hibernate一对一关联OneToOne

什么用场景需要hibernate一对一关联呢?举个例子:例如用户表与账户表,我们查询用户基本信息,不希望账户信息也拥挤在基本信息中,分开表管理又与之关联,单查用户信息的时候不用查账户,如登录,那么就用一对一。


一对一外键关联,使用@OneToOne


用户表:User

@OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)

一对一外键关联,使用@OneToOne,并设置了级联操作

@JoinColum设置了外键的名称为account_id如果不设置,则默认为account_id;

外键的值是唯一的(unique),不可重复,与Account的主键一至

package com.weizhixi.entity;

import javax.persistence.*;

/**
 * Created by cxq on 2017-12-26.
 */
@Entity
public class User {
    private int id;
    private String name;
    private Account account;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinColumn(name="account_id",unique=true)
    public Account getAccount() {
        return account;
    }
    public void setAccount(Account account) {
        this.account = account;
    }
}


账户表:Account

@OneToOne(mappedBy="account",cascade = CascadeType.ALL)

一对一双向关联关系,使用@OneToOne

注意:需要加上mappedBy="account",如果不加上的话,Account也会生成一个外键(user_id)。

mappedBy="account"需要指向与他关联的对象的一个属性,说明双向关联关系中,有且有一端是作为主体端存在的。

主体端负责维护关联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明mappedBy的值指向主体的关联属性。

规律:只有是双向关联关系,不维护的那一端要加上mappedBy,mappedBy谁用谁不维护。

package com.weizhixi.entity;

import javax.persistence.*;

/**
 * Created by cxq on 2017-12-26.
 */
@Entity
public class Account {
    private int id;
    private double money;
    private User user;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
    @OneToOne(mappedBy="account", cascade=CascadeType.ALL)
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

谁主谁从你自己根据业务决定。以上配置User为主表,Account为从表,由User维护双方关系。



来试下:Test

使用junit测试

//创建用户
User u = new User();
u.setName("weizhixi");
//创建用户的账户
Account a = new Account();
a.setMoney(100.00);
//把账户分配给该用户
u.setAccount(a);

//提交后就关闭session,不要自己再关闭session
session = sessionFactory.getCurrentSession();
session.beginTransaction();
//保存用户
session.save(u);
session.getTransaction().commit();

从日志看到发送了2句SQL插入语句

Hibernate: insert into Account (money) values (?)

Hibernate: insert into User (account_id, name) values (?, ?)


查询:主表

session = sessionFactory.getCurrentSession();
session.beginTransaction();

//查询主表 - 懒加载
User user = (User)session.get(User.class , 1);
System.out.println(user.getName());
//再获取从表信息
Account account = user.getAccount();
System.out.println(account.getMoney());

session.getTransaction().commit();

从日志看到,在查询User表的时候,并没有真正去查询Account,只发送了1条查询User表的SQL

在获取从表信息的时候才真正发送查询Account表的SQL。

Hibernate: select user0_.id as id2_0_, user0_.account_id as account3_2_0_, user0_.name as name2_0_ from User user0_ where user0_.id=?
weizhixi
Hibernate: select account0_.id as id3_1_, account0_.money as money3_1_, user1_.id as id2_0_, user1_.account_id as account3_2_0_, user1_.name as name2_0_ from Account account0_ left outer join User user1_ on account0_.id=user1_.account_id where account0_.id=?
Hibernate: select user0_.id as id2_0_, user0_.account_id as account3_2_0_, user0_.name as name2_0_ from User user0_ where user0_.account_id=?
100.0


查询:从表

session = sessionFactory.getCurrentSession();
session.beginTransaction();

Account user = (Account)session.get(Account.class , 1);
System.out.println(user.getMoney());
User user1 = user.getUser();
System.out.println(user1.getName());

session.getTransaction().commit();
Hibernate: select account0_.id as id3_1_, account0_.money as money3_1_, user1_.id as id2_0_, user1_.account_id as account3_2_0_, user1_.name as name2_0_ from Account account0_ left outer join User user1_ on account0_.id=user1_.account_id where account0_.id=?
100.0
weizhixi


用户表

mysql> select * from user;
+----+----------+------------+
| id | name     | account_id |
+----+----------+------------+
|  1 | weizhixi |          1 |
+----+----------+------------+
1 row in set (0.00 sec)

账户表

mysql> select * from account;
+----+-------+
| id | money |
+----+-------+
|  1 |   100 |
+----+-------+
1 row in set (0.00 sec)



原创文章,转载请注明出处:https://www.weizhixi.com/article/41.html