java – Spring JPA Repository查询过滤关系表
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Spring JPA Repository查询过滤关系表,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7424字,纯文字阅读大概需要11分钟。
内容图文
![java – Spring JPA Repository查询过滤关系表](/upload/InfoBanner/zyjiaocheng/795/079aa694f39b443b8053826f3130b081.jpg)
如果我在JPA实体之间存在多对多关系,如何检索特定公司员工的Person列表(我对person属性感兴趣)?
人与公司之间的关系是多对多的.关系表Employee具有FK到Person和Company,以及start_date和end_date,用于指示工作何时开始和结束.
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
}
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
}
@Entity
public class CompanyEmployee {
//note this is to model a relationship table. Am I doing this wrong?
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "start_date", nullable = false)
private LocalDate startDate;
@Column(name = "end_date", nullable = false)
private LocalDate endDate;
@ManyToOne
private Company company;
@ManyToOne
private Person person;
}
我是否在CompanyEmployeeJPARepository上使用@Query?我应该如何解决这个问题?
public interface CompanyEmployeeRepository extends JpaRepository<CompanyEmployee,Long> {
//
}
解决方法:
巴勃罗
我们公司正在将现有的Spring / MyBatis代码转换为Spring Data JPA,因此我已经学习了几周的Spring Data JPA.我显然不是专家,但我找到了一个类似于你的例子,可以帮到你.
我有与您类似的Person和Company类,但(正如Jens所提到的),您需要使用OneToMany注释的列表.我使用了一个单独的连接表(名为company_person),它只有companyId,personId列来维护多对多关系.请参阅下面的代码.
我没有看到将开始/结束日期放在company_person连接表中的方法,所以我为此做了一个单独的(第4个表).我用Java类实体EmploymentRecord称它为employment_record.它具有组合主键(companyId,personId)和开始/结束日期.
您需要Person,Company和EmploymentRecord的存储库.我扩展了CrudRepository而不是JpaRepository.但是,您不需要连接表(company_record)的实体或存储库.
我做了一个Spring Boot Application类来测试它.我在Person的OneToMany上使用了CascadeType.ALL.在我的应用程序测试中,我测试过我可以更改分配给某人的公司,Spring Data会传播公司实体和联接表所需的所有更改.
但是,我不得不通过其存储库手动更新EmploymentRecord实体.例如,每次我向一个人添加公司时,我都必须添加一个start_date.然后,当我从该人那里删除该公司时添加end_date.可能有一些方法可以实现自动化. Spring / JPA审核功能是可能的,所以检查一下.
你的问题的答案:
how can I retrieve a list of Person (I am interested in the person
attributes) that are employees of a specific company?
您只需使用companyRepository的findOne(Long id)方法,然后使用getPersonList()方法.
Application.java的代码片段:
PersonRepository pRep = context.getBean(PersonRepository.class);
CompanyRepository cRep = context.getBean(CompanyRepository.class);
EmploymentRecordRepository emplRep = context.getBean(EmploymentRecordRepository.class);
...
// fetch a Company by Id and get its list of employees
Company comp = cRep.findOne(5L);
System.out.println("Found a company using findOne(5L), company= " + comp.getName());
System.out.println("People who work at " + comp.getName());
for (Person p : comp.getPersonList()) {
System.out.println(p);
}
以下是我发现有用的一些参考资料:
Spring Data JPA tutorial
Join Table example
Person.java:
@Entity
public class Person {
// no-arg constructor
Person() { }
// normal use constructor
public Person(String name, String address) {
this.name = name;
this.address = address;
}
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Version
private int versionId;
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name="company_person",
joinColumns={@JoinColumn(name="person_id", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="company_id", referencedColumnName="id")})
private List<Company> companyList;
// Getters / setters
}
Company.java:
@Entity
public class Company {
// no-arg constructor
Company() { }
// normal use constructor
public Company(String name, String address) {
this.name = name;
this.address = address;
}
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
@Version
private int versionId;
//@OneToMany(cascade=CascadeType.ALL)
@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name="company_person",
joinColumns={@JoinColumn(name="company_id", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="person_id", referencedColumnName="id")})
private List<Person> personList;
// Getters / Setters
}
EmploymentRecord.java:
@Entity
@IdClass(EmploymentRecordKey.class)
public class EmploymentRecord {
// no-arg constructor
EmploymentRecord() { }
// normal use constructor
public EmploymentRecord(Long personId, Long companyId, Date startDate, Date endDate) {
this.startDate = startDate;
this.endDate = endDate;
this.companyId = companyId;
this.personId = personId;
}
// composite key
@Id
@Column(name = "company_id", nullable = false)
private Long companyId;
@Id
@Column(name = "person_id", nullable = false)
private Long personId;
@Column(name = "start_date")
private Date startDate;
@Column(name = "end_date")
private Date endDate;
@Version
private int versionId;
@Override
public String toString() {
return
" companyId=" + companyId +
" personId=" + personId +
" startDate=" + startDate +
" endDate=" + endDate +
" versionId=" + versionId;
}
// Getters/Setters
}
// Class to wrap the composite key
class EmploymentRecordKey implements Serializable {
private long companyId;
private long personId;
// no arg constructor
EmploymentRecordKey() { }
@Override
public int hashCode() {
return (int) ((int) companyId + personId);
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj == this) return true;
if (!(obj instanceof EmploymentRecordKey)) return false;
EmploymentRecordKey pk = (EmploymentRecordKey) obj;
return pk.companyId == companyId && pk.personId == personId;
}
// Getters/Setters
}
MySql脚本,createTables.sql:
DROP TABLE IF EXISTS `test`.`company_person`;
DROP TABLE IF EXISTS `test`.`employment_record`;
DROP TABLE IF EXISTS `test`.`company`;
DROP TABLE IF EXISTS `test`.`person`;
CREATE TABLE `company` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL DEFAULT '',
`address` varchar(500) DEFAULT '',
`version_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `person` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL DEFAULT '',
`address` varchar(500) DEFAULT '',
`version_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/* Join table */
CREATE TABLE `company_person` (
`company_id` int NOT NULL,
`person_id` int NOT NULL,
PRIMARY KEY (`person_id`,`company_id`),
KEY `company_idx` (`company_id`),
KEY `person_idx` (`person_id`),
CONSTRAINT `fk_person` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_company` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/* Employment records */
CREATE TABLE `employment_record` (
`company_id` int NOT NULL,
`person_id` int NOT NULL,
`start_date` datetime,
`end_date` datetime,
`version_id` int NOT NULL,
PRIMARY KEY (`person_id`,`company_id`),
KEY `empl_company_idx` (`company_id`),
KEY `empl_person_idx` (`person_id`),
CONSTRAINT `fk_empl_person` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_empl_company` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
内容总结
以上是互联网集市为您收集整理的java – Spring JPA Repository查询过滤关系表全部内容,希望文章能够帮你解决java – Spring JPA Repository查询过滤关系表所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。