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