JPA 多对一 @ManyToOne
一个出版者可以发布多本书
@Entity public class Book { @Id String isbn; String title; @ManyToOne // Book 表会增加 publisher_id 与 Publisher 表主键关联 Publisher publisher; } @Entity public class Publisher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增 Long id; String name; }
结果
[Hibernate] create table Book ( isbn varchar(255) not null, title varchar(255), publisher_id bigint, primary key (isbn) ) engine=InnoDB [Hibernate] create table Publisher ( id bigint not null auto_increment, name varchar(255), primary key (id) ) engine=InnoDB [Hibernate] alter table Book add constraint FKrb2njmkvio5mhe42empuaiphu foreign key (publisher_id) references Publisher (id)
使用 @OneToMany 双向关联
@Entity public class Book { @Id String isbn; String title; @ManyToOne // Book 表会增加 publisher_id 与 Publisher 表关联 Publisher publisher; } @Entity public class Publisher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增 Long id; String name; @OneToMany(mappedBy = "publisher") Set<Book> books; }
结果
[Hibernate] create table Book ( isbn varchar(255) not null, title varchar(255), publisher_id bigint, primary key (isbn) ) engine=InnoDB [Hibernate] create table Publisher ( id bigint not null auto_increment, name varchar(255), primary key (id) ) engine=InnoDB [Hibernate] alter table Book add constraint FKrb2njmkvio5mhe42empuaiphu foreign key (publisher_id) references Publisher (id)
使用 @JoinColumn 手动设置关联信息
@Entity public class Book { @Id String isbn; String title; @ManyToOne @JoinColumn(name = "publisher_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "PUBLISHER_ID_FK") ) // Book 表会增加 publisher_id 字段与 Publisher 表 id(不写默认主键) 关联 Publisher publisher; } @Entity public class Publisher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增 Long id; String name; }
结果
[Hibernate] create table Book ( isbn varchar(255) not null, title varchar(255), publisher_id bigint, primary key (isbn) ) engine=InnoDB [Hibernate] create table Publisher ( id bigint not null auto_increment, name varchar(255), primary key (id) ) engine=InnoDB [Hibernate] alter table Book add constraint PUBLISHER_ID_FK foreign key (publisher_id) references Publisher (id)
测试
src/main/resources/META-INF/persistence.xml
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="persistenceUnitName"> <properties><!-- org.hibernate.cfg.JdbcSettings --> <property name="jakarta.persistence.jdbc.user" value="root"/> <property name="jakarta.persistence.jdbc.password" value="root"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/jpa"/> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.highlight_sql" value="true"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
Main
Persistence.createEntityManagerFactory("persistenceUnitName"); // 保存时, 先保存 1 端, 后保存 n 端, 这样不会多出额外的 UPDATE 语句 // 删除时不能直接删除 1 端, 有外键约束 // 查询时使用左外连接获取 n 端和其关联的 1 端, 可使用 @ManyToOne 的 fetch 属性修改加载策略