前言:
现时我们对“注解onetomany”大体比较珍视,咱们都需要知道一些“注解onetomany”的相关知识。那么小编在网上搜集了一些关于“注解onetomany””的相关内容,希望兄弟们能喜欢,我们一起来了解一下吧!SpringDataJPA中实体关联映射OneToOne
JPA中关联关系的映射,是映射关系中比较复杂的一种映射关系,概括起来说来有一对一、一对多和多对多几种关系。细分起来他们又有单向和双向之分。今天我们详细地介绍一下OneToOne关系的具体实现和各种属性设置带来的影响。
一、默认单向OneToOne
我们有两个实体User 和 UserExtra,在User 中使用OneToOne 关联UserExtra。代码如下:
package com.xtoad.ecms.baseinfo.model;import com.xtoad.ecms.common.web.base.BaseModel;import org.hibernate.annotations.Table;import org.springframework.data.jpa.domain.support.AuditingEntityListener;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.ConstraintMode;import javax.persistence.Entity;import javax.persistence.EntityListeners;import javax.persistence.FetchType;import javax.persistence.ForeignKey;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.OneToOne;import java.util.List;/** * 用户实体类 * * @author xtoad * @date 2020/05/29 */@Entity@Table(appliesTo = "user", comment = "用户表")@EntityListeners(AuditingEntityListener.class)public class User extends BaseModel { private static final long serialVersionUID = -1616905035103332302L; /** * 用户扩展信息 */ @OneToOne private UserExtra userExtra; /** * 获取 用户扩展信息 */ public UserExtra getUserExtra() { return this.userExtra; } /** * 设置 用户扩展信息 */ public void setUserExtra(UserExtra userExtra) { this.userExtra = userExtra; } /////////////////忽略其他属性和方法,完整代码请参照文末的git地址}
package com.xtoad.ecms.baseinfo.model;import com.xtoad.ecms.baseinfo.enums.Sex;import com.xtoad.ecms.common.web.base.BaseModel;import org.hibernate.annotations.Table;import org.springframework.data.jpa.domain.support.AuditingEntityListener;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.EntityListeners;import javax.persistence.EnumType;import javax.persistence.Enumerated;import javax.persistence.Temporal;import javax.persistence.TemporalType;import java.util.Date;/** * 用户扩展信息实体类 * * @author xtoad * @date 2020/05/29 */@Entity@Table(appliesTo = "user_extra", comment = "用户扩展信息表")@EntityListeners(AuditingEntityListener.class)public class UserExtra extends BaseModel { private static final long serialVersionUID = 4833292279765547874L; /** * 姓名 */ @Column(length = 100, columnDefinition = "VARCHAR(100) COMMENT '姓名'") private String name; /** * 生日 */ @Temporal(TemporalType.DATE) @Column(columnDefinition = "DATE COMMENT '生日'") private Date birthday; /** * 性别 */ @Column(nullable = false, length = 10, columnDefinition = "VARCHAR(10) COMMENT '性别'") @Enumerated(EnumType.STRING) private Sex sex; /** * 默认构造函数 */ public UserExtra() { } /** * 获取 姓名 */ public String getName() { return this.name; } /** * 设置 姓名 */ public void setName(String name) { this.name = name; } /** * 获取 生日 */ public Date getBirthday() { return this.birthday; } /** * 设置 生日 */ public void setBirthday(Date birthday) { this.birthday = birthday; } /** * 获取 性别 */ public Sex getSex() { return this.sex; } /** * 设置 性别 */ public void setSex(Sex sex) { this.sex = sex; } @Override public String toString() { return "UserExtra{" + "name='" + name + '\'' + ", birthday=" + birthday + ", sex=" + sex + "} " + super.toString(); }}
我们看生成的表结构:
并且生成了外键:
扩展表则没有任何变化:
下面我们修改一下关联注解,让生成的关联字段不生成外键,并且指定关联实体的加载方式和级联修改方式:
/** * 用户扩展信息 */ @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) private UserExtra userExtra;
我们再生成看一下两张表结构无变化,只是User表中的外键消失了:
我们来插入数据和测试数据试试:
/* * Copyright 2019-2029 联通集团财务有限公司版权所有 */package com.xtoad.ecms.baseinfo.service.impl;import com.xtoad.ecms.baseinfo.enums.Sex;import com.xtoad.ecms.baseinfo.model.User;import com.xtoad.ecms.baseinfo.model.UserExtra;import com.xtoad.ecms.baseinfo.repository.IProductRepository;import com.xtoad.ecms.baseinfo.repository.IShoeRepository;import com.xtoad.ecms.baseinfo.repository.IUserExtraRepository;import com.xtoad.ecms.baseinfo.repository.IUserRepository;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;/** * 用户实体测试类 * * @author xtoad * @date 2021/3/3 */@SpringBootTestpublic class UserTest { @Autowired private IUserRepository userRepository; @Autowired private IUserExtraRepository userExtraRepository; @Test void saveUser() { User user = new User(); user.setLoginNo("Junit5_user"); user.setPhone("13456781234"); user.setEmail("13456781234@test.com"); user.setPassword("123"); UserExtra userExtra = new UserExtra(); userExtra.setBirthday(new Date()); userExtra.setSex(Sex.MALE); userExtra.setName("单元测试用户01"); user.setUserExtra(userExtra); userRepository.save(user); }}
结果:
我们看一下执行日志:
[11:42:40.499] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl 53 <init> - On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false[11:42:40.500] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl 81 begin - begin[11:42:40.596] DEBUG org.hibernate.engine.spi.ActionQueue 281 addResolvedEntityInsertAction - Executing identity-insert immediately[11:42:40.608] DEBUG org.hibernate.engine.jdbc.spi.SqlStatementLogger 127 logStatement - insert into user_extra (create_time, create_user, last_update_time, last_update_user, birthday, name, sex) values (?, ?, ?, ?, ?, ?, ?)Hibernate: insert into user_extra (create_time, create_user, last_update_time, last_update_user, birthday, name, sex) values (?, ?, ?, ?, ?, ?, ?)[11:42:40.635] DEBUG org.hibernate.id.IdentifierGeneratorHelper 78 getGeneratedIdentity - Natively generated identity: 2[11:42:40.636] DEBUG org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl 106 release - HHH000387: ResultSet's statement was not registered[11:42:40.645] DEBUG org.hibernate.engine.spi.ActionQueue 281 addResolvedEntityInsertAction - Executing identity-insert immediately[11:42:40.646] DEBUG org.hibernate.engine.jdbc.spi.SqlStatementLogger 127 logStatement - insert into user (create_time, create_user, last_update_time, last_update_user, email, login_no, nick_name, password, phone, user_extra_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)Hibernate: insert into user (create_time, create_user, last_update_time, last_update_user, email, login_no, nick_name, password, phone, user_extra_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)[11:42:40.648] DEBUG org.hibernate.id.IdentifierGeneratorHelper 78 getGeneratedIdentity - Natively generated identity: 1[11:42:40.649] DEBUG org.hibernate.resource.jdbc.internal.ResourceRegistryStandardImpl 106 release - HHH000387: ResultSet's statement was not registered[11:42:40.650] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl 98 commit - committing[11:42:40.652] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener 139 prepareEntityFlushes - Processing flush-time cascades[11:42:40.654] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener 192 prepareCollectionFlushes - Dirty checking collections[11:42:40.662] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener 113 logFlushResults - Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects[11:42:40.662] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener 120 logFlushResults - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections[11:42:40.664] DEBUG org.hibernate.internal.util.EntityPrinter 110 toString - Listing entities:[11:42:40.669] DEBUG org.hibernate.internal.util.EntityPrinter 117 toString - com.xtoad.ecms.baseinfo.model.UserExtra{birthday=Wed Mar 03 11:42:40 CST 2021, createTime=Wed Mar 03 11:42:40 CST 2021, sex=MALE, name=单元测试用户01, lastUpdateUser=anonymous, createUser=anonymous, id=2, lastUpdateTime=Wed Mar 03 11:42:40 CST 2021}[11:42:40.670] DEBUG org.hibernate.internal.util.EntityPrinter 117 toString - com.xtoad.ecms.baseinfo.model.User{password=123, createTime=Wed Mar 03 11:42:40 CST 2021, phone=13456781234, userExtra=com.xtoad.ecms.baseinfo.model.UserExtra#2, nickName=null, roles=null, lastUpdateUser=anonymous, createUser=anonymous, id=1, loginNo=Junit5_user, email=13456781234@test.com, lastUpdateTime=Wed Mar 03 11:42:40 CST 2021}
会先执行user_extra的插入,再执行user的插入。
二、双向OneToOne
在User类中添加userExtra属性:
/** * 用户扩展信息 */ @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user") private UserExtra userExtra;
在UserExtra中添加user 属性:
/** * 用户信息 */ @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private User user;
我们再看一下生成的表结构:
这种场景一定会生成外键。并且关联的id 会生成在mappedBy 指定的属性所在的实体类的表中。
此时维护端就变成了UserExtra实体类。
标签: #注解onetomany