ManyToMany單向、雙向:@JoinTable的使用
ManyToMany單向、雙向:@JoinTable使用
一、manytomany單向
單向是指類層面,在下面例子中老師類可以知道要教哪些學(xué)生,學(xué)生不知被哪些老師教
**需要用到連接表**@JoinTable(name="t_s", joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")} )
也可以不用連接表,但是若不用連接表,表名、列名規(guī)則:
- 在student表中沒(méi)有寫(xiě)外鍵則會(huì)用對(duì)方的表名_主鍵名
- 在teacher表中有外鍵,則會(huì)s_id(也是student的主鍵名)
- 表名是student_teacher
student類
@Entity public class student { private int id; private String name; @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; } }
Teacher類
@Entity public class teacher { private int id; private String name; private Set<student> s=new HashSet<student>(); @Id //必須加在getId上面 @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } @ManyToMany @JoinTable(name="t_s", joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")} )//將會(huì)以上兩個(gè)字段為聯(lián)合主鍵 //定義中間表的名稱,列名:joinColumns,inverseJoinColumns是預(yù)防組合主鍵的時(shí)候。 public Set<student> getS() { return s; } public void setS(Set<student> s) { this.s = s; } }
二、manytomany雙向
也可以用@JoinTable對(duì)連接表字段名進(jìn)行修改
@Entity public class student { private int id; private String name; private Set<teacher> ts=new HashSet<teacher>(); @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; } @ManyToMany @JoinTable(name="t_s", joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")} ) public Set<teacher> getTs() { return ts; } public void setTs(Set<teacher> ts) { this.ts = ts; } }
@Entity public class teacher { private int id; private String name; private Set<student> s=new HashSet<student>(); @Id //必須加在getId上面 @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; } @ManyToMany(mappedBy="ts") //定義中間表的名稱,列名:joinColumns,inverseJoinColumns是預(yù)防組合主鍵的時(shí)候。 public Set<student> getS() { return s; } public void setS(Set<student> s) { this.s = s; } }
@ManyToMany(多對(duì)多關(guān)系)使用小結(jié)
DeviceGroup類
package com.sunwave.grouping.domain; import javax.persistence.*; import java.io.Serializable; import java.util.List; @Entity @Table(name = "device_group") public class DeviceGroup implements Serializable{ /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) /* @Column(name="group_id")*/ private long groupId; @Column(name="group_name") private String groupName; @Column(name="description") private String description;//自動(dòng)在數(shù)據(jù)庫(kù)里生成了group_has_element表,該表包括group_id和element_id兩個(gè)字段,該表主要是用于存儲(chǔ)device_group表和ne_element表的對(duì)應(yīng)關(guān)系。 @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)//表的關(guān)聯(lián),生成一個(gè)group_has_element中間表。 @JoinTable(name = "group_has_element",joinColumns = {@JoinColumn(name = "group_id",referencedColumnName = "groupId")} ,inverseJoinColumns = {@JoinColumn(name = "element_id",referencedColumnName = "neNeid")}) private List<NeElement> elementList; public List<NeElement> getElementList() { return elementList; } public void setElementList(List<NeElement> elementList) { this.elementList = elementList; } public long getGroupId() { return groupId; } public void setGroupId(long groupId) { this.groupId = groupId; } public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "DeviceGroup [groupId=" + groupId + ", groupName=" + groupName + ", description=" + description + ", elementList=" + elementList + "]"; } }
NeElement 類
package com.sunwave.grouping.domain; import javax.persistence.*; import java.io.Serializable; import java.util.Date; import java.util.List; /** * @author lfw * @date 2020年8月3日 * @time 下午6:44:54 * */ @Entity @Table(name = "ne_element") public class NeElement implements Serializable{ /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long neNeid; //設(shè)備唯一標(biāo)識(shí) private String coonReqUrl; //設(shè)備連接URL private String serialNumber; //設(shè)備序列號(hào) private String deviceIp; //設(shè)備IP private Long modelId;//modelName對(duì)應(yīng)的id private String description;//描述 private String manufacturer;//制造商 private String softwareVersion;//軟件版本 private Date creationTime;//創(chuàng)建時(shí)間 private Date lastBootstrapTime; private Date lastConnTime;//最后連接時(shí)間 private Date updateTime;//更新時(shí)間 private String oui;//oui private String product; private Boolean authRequirement;//是否需要認(rèn)證 private String dialectIP; private String updateUser;//更新用戶 private String macAddress;//mac地址 private Integer onlineStatus;//在線狀態(tài) private Integer sessionStatus;//會(huì)話狀態(tài) @ManyToMany(mappedBy = "elementList") private List<DeviceGroup> deviceGroupList; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getManufacturer() { return manufacturer; } public void setManufacturer(String manufacturer) { this.manufacturer = manufacturer; } public String getSoftwareVersion() { return softwareVersion; } public void setSoftwareVersion(String softwareVersion) { this.softwareVersion = softwareVersion; } public Date getLastConnTime() { return lastConnTime; } public void setLastConnTime(Date lastConnTime) { this.lastConnTime = lastConnTime; } public Long getModelId() { return modelId; } public void setModelId(Long modelId) { this.modelId = modelId; } public Long getNeNeid() { return neNeid; } public void setNeNeid(Long neNeid) { this.neNeid = neNeid; } public String getCoonReqUrl() { return coonReqUrl; } public void setCoonReqUrl(String coonReqUrl) { this.coonReqUrl = coonReqUrl; } public String getDeviceIp() { return deviceIp; } public void setDeviceIp(String deviceIp) { this.deviceIp = deviceIp; } public String getSerialNumber() { return serialNumber; } public void setSerialNumber(String serialNumber) { this.serialNumber = serialNumber; } public Date getCreationTime() { return creationTime; } public void setCreationTime(Date creationTime) { this.creationTime = creationTime; } public Date getLastBootstrapTime() { return lastBootstrapTime; } public void setLastBootstrapTime(Date lastBootstrapTime) { this.lastBootstrapTime = lastBootstrapTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getOui() { return oui; } public void setOui(String oui) { this.oui = oui; } public String getProduct() { return product; } public void setProduct(String product) { this.product = product; } public Boolean getAuthRequirement() { return authRequirement; } public void setAuthRequirement(Boolean authRequirement) { this.authRequirement = authRequirement; } public String getDialectIP() { return dialectIP; } public void setDialectIP(String dialectIP) { this.dialectIP = dialectIP; } public String getUpdateUser() { return updateUser; } public void setUpdateUser(String updateUser) { this.updateUser = updateUser; } public String getMacAddress() { return macAddress; } public void setMacAddress(String macAddress) { this.macAddress = macAddress; } public Integer getOnlineStatus() { return onlineStatus; } public void setOnlineStatus(Integer onlineStatus) { this.onlineStatus = onlineStatus; } public Integer getSessionStatus() { return sessionStatus; } public void setSessionStatus(Integer sessionStatus) { this.sessionStatus = sessionStatus; } }
以上為多對(duì)多關(guān)系的使用,大家可以參考,本人在使用過(guò)程中遇到以下報(bào)錯(cuò)信息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to map collection com.sunwave.grouping.domain.DeviceGroup.elementList
?at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1694) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1087) ~[spring-context-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) ~[spring-context-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548) ~[spring-context-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
?at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
?at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
?at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
?at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
?at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
?at com.sunwave.Application.main(Application.java:26) [classes/:na]
?at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
?at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
?at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
?at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
?at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.8.RELEASE.jar:2.0.8.RELEASE]
Caused by: org.hibernate.AnnotationException: Unable to map collection com.sunwave.grouping.domain.DeviceGroup.elementList
?at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1621) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1352) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:810) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:735) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1640) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1608) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1753) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1690) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
?... 21 common frames omitted
Caused by: org.hibernate.cfg.RecoverableException: Unable to find column with logical name: groupId in org.hibernate.mapping.Table(device_group) and its related supertables and secondary tables
?at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:837) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:244) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1611) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?... 37 common frames omitted
Caused by: org.hibernate.MappingException: Unable to find column with logical name: groupId in org.hibernate.mapping.Table(device_group) and its related supertables and secondary tables
?at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:832) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
?... 39 common frames omitted
檢查了實(shí)體類和數(shù)據(jù)庫(kù)發(fā)現(xiàn)沒(méi)有什么錯(cuò),原來(lái)是因?yàn)槲业膶?shí)體類里的groupId上用了/*@Column(name=“group_id”)注解,如下把該注解注釋掉或者刪除掉就可以了。
/* @Column(name="group_id")*/ private long groupId;
其他關(guān)于@ManyToMany(多對(duì)多關(guān)系)的使用可以去百度再看看,本人就不多說(shuō)了。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java?設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解單例模式
單例模式(Singleton?Pattern)是?Java?中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式2022-03-03Java如何實(shí)現(xiàn)簡(jiǎn)單的RPC框架
這篇文章主要介紹了Java如何實(shí)現(xiàn)簡(jiǎn)單的RPC框架,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07spring boot使用自定義的線程池執(zhí)行Async任務(wù)
這篇文章主要介紹了spring boot使用自定義的線程池執(zhí)行Async任務(wù)的相關(guān)資料,需要的朋友可以參考下2018-02-02SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)的方法
這篇文章主要介紹了SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11最新IDEA?2022基于JVM極致優(yōu)化?IDEA啟動(dòng)速度的方法
這篇文章主要介紹了IDEA?2022最新版?基于?JVM極致優(yōu)化?IDEA?啟動(dòng)速度,需要的朋友可以參考下2022-08-08Java使用HttpClient實(shí)現(xiàn)文件下載
這篇文章主要為大家詳細(xì)介紹了Java使用HttpClient實(shí)現(xiàn)文件下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08SpringBoot淺析緩存機(jī)制之Ehcache?2.x應(yīng)用
EhCache?是一個(gè)純Java的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn)。它是Hibernate中的默認(rèn)緩存框架。Ehcache已經(jīng)發(fā)布了3.1版本。但是本文的講解基于2.x版本2022-08-08