向实体添加动态列而不将其保存到 table
add a dynamic column to an entity without saving it to the table
我有一个模型 class 如下所示:
package com.example.model;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.example.helpers.StringMapConverter;
@Entity
@Table(name = "buildingcompanies")
public class Buildcompanies {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "shortname")
private String shortname;
@Column(name = "fullname")
private String fullname;
@Column(name = "address")
private String address;
@Column(name = "telephone")
private String telephone;
@Column(name = "website")
private String website;
@Column(name = "sociallinks")
@Convert(converter = StringMapConverter.class)
private Map<String, String> sociallinks;
@Column(name = "foundationyear")
private String foundationyear;
public Buildcompanies() {
}
public Buildcompanies(String shortname, String fullname, String address, String telephone, String website,
Map<String, String> map, String foundationyear) {
this.shortname = shortname;
this.fullname = fullname;
this.address = address;
this.telephone = telephone;
this.website = website;
this.sociallinks = map;
this.foundationyear = foundationyear;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public Map<String, String> getSociallinks() {
return sociallinks;
}
public void setSociallinks(Map<String, String> sociallinks) {
this.sociallinks = sociallinks;
}
public String getFoundationyear() {
return foundationyear;
}
public void setFoundationyear(String foundationyear) {
this.foundationyear = foundationyear;
}
}
以及控制器中显示输出的方法:
public ResponseEntity<List<Buildcompanies>> getAllCompanies(@RequestParam(required = false) String name) {
try {
List<Buildcompanies> companies = new ArrayList<Buildcompanies>();
int test=0;
if (name == null)
{
buildcompaniesRepository.findAll().forEach(companies::add);
}
else
buildcompaniesRepository.findByShortnameContaining(name).forEach(companies::add);
if (companies.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(companies, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
它确实显示输出一切正常:
[
{
"id": 81,
"shortname": "testing",
"fullname": "test",
"address": "addrtest",
"telephone": "380979379992",
"website": "www.site.com",
"sociallinks": {
"facebook": "fb.com"
},
"foundationyear": "1991"
}
]
我想在向最终用户显示数据的同时计算每个公司的评级。所以输出应该如下:
[
{
"id": 81,
"shortname": "testing",
"fullname": "test",
"address": "addrtest",
"telephone": "380979379992",
"website": "www.site.com",
"sociallinks": {
"facebook": "fb.com"
},
"foundationyear": "1991",
"rating": "1.5"
}
]
是否可以将评级列动态添加到公司列表中,或者我应该在数据库中创建评级列,在控制器中更新它的方法,迭代 findAll() 结果并在每次用户尝试时调用它访问 /list 端点?
你有两个选择:
您可以为此目的在 Buildcompanies class 中引入一个新属性并用@Transient 对其进行注释。
这将表示该属性不需要保留在数据库中,并且 JPA 不会尝试在 table.
中创建列
推荐的方法是不使用实体 class 作为响应对象。理想情况下,您应该有一个域对象,并且数据库响应应该映射到该对象。在映射时,您可以应用要添加的任何自定义详细信息。
只需将 @Transient
注释添加到您的动态字段。数据库中不需要相应的列。 transient 列的值只存在于运行时。
一般来说,出于多种原因,将实体作为 JSON 与外部系统共享是个坏主意。请改用中间 DTO。有很多库允许从实体到 DTO 的可配置自动映射(ModelMapper 对我来说非常好)。
我有一个模型 class 如下所示:
package com.example.model;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.example.helpers.StringMapConverter;
@Entity
@Table(name = "buildingcompanies")
public class Buildcompanies {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "shortname")
private String shortname;
@Column(name = "fullname")
private String fullname;
@Column(name = "address")
private String address;
@Column(name = "telephone")
private String telephone;
@Column(name = "website")
private String website;
@Column(name = "sociallinks")
@Convert(converter = StringMapConverter.class)
private Map<String, String> sociallinks;
@Column(name = "foundationyear")
private String foundationyear;
public Buildcompanies() {
}
public Buildcompanies(String shortname, String fullname, String address, String telephone, String website,
Map<String, String> map, String foundationyear) {
this.shortname = shortname;
this.fullname = fullname;
this.address = address;
this.telephone = telephone;
this.website = website;
this.sociallinks = map;
this.foundationyear = foundationyear;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public Map<String, String> getSociallinks() {
return sociallinks;
}
public void setSociallinks(Map<String, String> sociallinks) {
this.sociallinks = sociallinks;
}
public String getFoundationyear() {
return foundationyear;
}
public void setFoundationyear(String foundationyear) {
this.foundationyear = foundationyear;
}
}
以及控制器中显示输出的方法:
public ResponseEntity<List<Buildcompanies>> getAllCompanies(@RequestParam(required = false) String name) {
try {
List<Buildcompanies> companies = new ArrayList<Buildcompanies>();
int test=0;
if (name == null)
{
buildcompaniesRepository.findAll().forEach(companies::add);
}
else
buildcompaniesRepository.findByShortnameContaining(name).forEach(companies::add);
if (companies.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(companies, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
它确实显示输出一切正常:
[
{
"id": 81,
"shortname": "testing",
"fullname": "test",
"address": "addrtest",
"telephone": "380979379992",
"website": "www.site.com",
"sociallinks": {
"facebook": "fb.com"
},
"foundationyear": "1991"
}
]
我想在向最终用户显示数据的同时计算每个公司的评级。所以输出应该如下:
[
{
"id": 81,
"shortname": "testing",
"fullname": "test",
"address": "addrtest",
"telephone": "380979379992",
"website": "www.site.com",
"sociallinks": {
"facebook": "fb.com"
},
"foundationyear": "1991",
"rating": "1.5"
}
]
是否可以将评级列动态添加到公司列表中,或者我应该在数据库中创建评级列,在控制器中更新它的方法,迭代 findAll() 结果并在每次用户尝试时调用它访问 /list 端点?
你有两个选择:
您可以为此目的在 Buildcompanies class 中引入一个新属性并用@Transient 对其进行注释。 这将表示该属性不需要保留在数据库中,并且 JPA 不会尝试在 table.
中创建列推荐的方法是不使用实体 class 作为响应对象。理想情况下,您应该有一个域对象,并且数据库响应应该映射到该对象。在映射时,您可以应用要添加的任何自定义详细信息。
只需将 @Transient
注释添加到您的动态字段。数据库中不需要相应的列。 transient 列的值只存在于运行时。
一般来说,出于多种原因,将实体作为 JSON 与外部系统共享是个坏主意。请改用中间 DTO。有很多库允许从实体到 DTO 的可配置自动映射(ModelMapper 对我来说非常好)。