spring boot + hibernate 如何实现前后端交互的。如果前台提交一个表单进行保存
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot + hibernate 如何实现前后端交互的。如果前台提交一个表单进行保存相关的知识,希望对你有一定的参考价值。
后台如何进行响应接收数据并存到数据库中,需要具体实现过程,有大神可以知道么?
要代码吗? ajax返回后台 后台用@ResponseBody接收 保存到数据如果不用回传参数信息到前台就返回String 如果有数据你可以用List<JavaBean>返回 参考技术A 通过IP地址:端口号传递数据的使用 Spring Boot、Jackson 和 Hibernate 的多对多关系
【中文标题】使用 Spring Boot、Jackson 和 Hibernate 的多对多关系【英文标题】:Many to Many relationships using Spring Boot, Jackson and Hibernate 【发布时间】:2017-11-02 14:54:54 【问题描述】:我正在使用 Spring Boot 和 Hibernate 进行一个休息项目,目前正在尝试弄清楚如何处理我的 json 序列化。
上面 ERD 中显示的架构由 Hibernate 映射并且工作正常。
当我向控制器发出 get 请求时,问题就出现了。我的理解是 Spring 现在尝试使用 Jackson 序列化对象链。因为父对象和子对象都有一个属性,所以我们发现自己遇到了一个无限递归循环。
现在我研究了@JsonIgnore、@JsonView、@JsonManagedReference 和@JsonBackReference,但这些似乎只适用于一对多关系。
我正在寻找一种情况,例如,当我向/users/id
发出 GET 请求时,我得到的用户对象包括它的所有关系属性(我们称之为完整对象),但关系属性本身不要显示他们的关系属性(最小化对象)。这适用于上面提到的注释,但我如何使这个工作也以另一种方式工作?
希望回复:/users/id
// full user object
id: 1,
username: 'foo',
// password can be JsonIgnored because of obvious reasons
role: // minimized role object
id: 1,
name: 'bar'
// NO USERS LIST
area: //minimized area object
id: 2,
name: 'some val'
// NO USERS LIST
// NO TABLES LIST
/userrole/id
的期望回复
// full role object
id: 1,
name: 'waiter'
users: [
// minmized user object
id: 1,
username: 'foo'
// password can be JsonIgnored because of obvious reasons
// NO ROLE OBJECT
// NO AREA OBJECT
,
// minmized user object
id: 1,
username: 'foo'
// password can be JsonIgnored because of obvious reasons
// NO ROLE OBJECT
// NO AREA OBJECT
]
一般来说:当直接向实体发出请求时,我想要一个完整的对象,而当间接请求时,我想要一个最小化的对象。
有什么想法吗?我希望我的解释足够清楚。
更新
评论部分中要求的区域、用户和用户角色 POJO。
用户
@Entity
@Table(name = "users", schema = "public", catalog = "PocketOrder")
public class User
private int id;
private String username;
private String psswrd;
private List<Area> areas;
private UserRole Role;
@Id
@Column(name = "id", nullable = false)
public int getId()
return id;
public void setId(int id)
this.id = id;
@Basic
@Column(name = "username", nullable = false, length = 20)
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
@Basic
@JsonIgnore
@Column(name = "psswrd", nullable = true, length = 40)
public String getPsswrd()
return psswrd;
public void setPsswrd(String psswrd)
this.psswrd = psswrd;
@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != user.id) return false;
if (username != null ? !username.equals(user.username) : user.username != null) return false;
if (psswrd != null ? !psswrd.equals(user.psswrd) : user.psswrd != null) return false;
return true;
@Override
public int hashCode()
int result = id;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (psswrd != null ? psswrd.hashCode() : 0);
return result;
@ManyToMany(mappedBy = "users")
public List<Area> getAreas()
return areas;
public void setAreas(List<Area> areas)
this.areas = areas;
@ManyToOne
@JoinColumn(name = "role_fk", referencedColumnName = "id", nullable = false)
public UserRole getRole()
return Role;
public void setRole(UserRole role)
Role = role;
用户角色
@Entity
@javax.persistence.Table(name = "userroles", schema = "public", catalog = "PocketOrder")
public class UserRole
private int id;
private String name;
private List<User> users;
@Id
@Column(name = "id", nullable = false)
public int getId()
return id;
public void setId(int id)
this.id = id;
@Basic
@Column(name = "name", nullable = false, length = 20)
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserRole userRole = (UserRole) o;
if (id != userRole.id) return false;
if (name != null ? !name.equals(userRole.name) : userRole.name != null) return false;
return true;
@Override
public int hashCode()
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
@OneToMany(mappedBy = "role")
public List<User> getUsers()
return users;
public void setUsers(List<User> users)
users = users;
区域
@Entity
@javax.persistence.Table(name = "areas", schema = "public", catalog = "PocketOrder")
public class Area
private int id;
private String name;
private List<User> users;
private List<Table> tables;
@Id
@Column(name = "id", nullable = false)
public int getId()
return id;
public void setId(int id)
this.id = id;
@Basic
@Column(name = "name", nullable = false, length = 20)
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Area area = (Area) o;
if (id != area.id) return false;
if (name != null ? !name.equals(area.name) : area.name != null) return false;
return true;
@Override
public int hashCode()
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
@ManyToMany
@JoinTable(name = "areas_users", catalog = "PocketOrder", schema = "public", joinColumns = @JoinColumn(name = "area_fk", referencedColumnName = "id", nullable = false), inverseJoinColumns = @JoinColumn(name = "user_fk", referencedColumnName = "id", nullable = false))
public List<User> getUsers()
return users;
public void setUsers(List<User> users)
this.users = users;
@OneToMany(mappedBy = "area")
public List<Table> getTables()
return tables;
public void setTables(List<Table> tables)
this.tables = tables;
【问题讨论】:
请发布您的 POJO。 @hallaksec 感谢您的快速回复,我已将提到的 POJO 添加到问题中。 【参考方案1】:尝试在特定点上使用 @JsonSerialize:
示例:
1 - 映射您的领域
@JsonSerialize(using = ExampleSampleSerializer.class)
@ManyToOne
private Example example;
2 - 创建自定义jackson序列化器(这里可以控制序列化)
public class ExampleSampleSerializer extends JsonSerializer<Example>
@Override
public void serialize(Example value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException, JsonProcessingException
jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("first");
jsonGenerator.writeNumber(value.getFirstValue());
jsonGenerator.writeFieldName("second");
jsonGenerator.writeNumber(value.getSecondValue());
jsonGenerator.writeFieldName("third");
jsonGenerator.writeNumber(value.getAnyAnotherClass().getThirdValue());
jsonGenerator.writeEndObject();
【讨论】:
这看起来不错,所以我在上面的 POJO 上进行了尝试(我的数据库中没有与任何区域相关的表记录,因此它不会尝试序列化这些记录)。这将返回以下错误:Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: org.hibernate.collection.internal.PersistentBag cannot be cast to com.entity.Area (through reference chain: java.util.ArrayList[0]->com.entity.User["areas"]);
这与我之前尝试使用 @JsonIdentityInfo 进行注释时遇到的错误相同。知道发生了什么吗?
发生这种情况是因为 Hibernate 开销了与 Proxies(PersistenseBag 类)的@OneToMany 关系。我找到了this post。您可以尝试使用 post + @JsonSerializer 中的 PersistentCollectionSerializer 或 HibernateProxySerializer。例如:@JsonSerializer(using = PersistentCollectionSerializer.class) 有任何问题在这里评论,我们会达成解决方案。
您好!昨晚我使用@JsonIdintityInfo 注释修复了它(相当丑陋)。这给了我一个 json 片段,其中对象仅完全表示一次。对同一对象的剩余引用仅由它们的 id 表示。它可以工作并且是确保没有发送不必要的数据的一种非常好的方法,但它需要在客户端进行相当多的解码。您的解决方案会产生相同的输出还是不同的结果?我很好奇:)。
不,我的解决方案导致另一个输出。这只会序列化特定字段,避免循环引用。【参考方案2】:
我在多对多关系上解决这个问题的方法是使用
@JsonIgnore
在其中一个实体上。
例如,我们有 Person 和 Child 实体。一个人可以有多个孩子,反之亦然。
在Person
我们有:
public class Person
//Other fields ommited
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
@JoinTable(name = "person_child",
joinColumns =
@JoinColumn(name = "person_id", referencedColumnName = "id", nullable = false,
updatable = false)
,
inverseJoinColumns =
@JoinColumn(name = "child_id", referencedColumnName = "id", nullable =
false, updatable = false)
)
private Set<Child> children = new HashSet<>() ;
在Child
我们有:
public class Child
@JsonIgnore
@ManyToMany(mappedBy = "children", fetch = FetchType.LAZY)
private Set<Person> people = new HashSet<>() ;
现在,当我们得到一个 Person 时,我们也会得到他所有连接的孩子。但是当我们得到一个 Child 时,我们不会得到所有 People,因为我们有 @JsonIgnore 注释。 这解决了无限递归问题,并提出了这个问题。
我的解决方法是编写一个查询,让我所有的人都连接到特定的child_id
。
下面你可能会看到我的代码:
public interface PersonDAO extends JpaRepository<Person, Long>
@Query(value = "SELECT * " +
" FROM person p INNER JOIN person_child j " +
"ON p.id = j.person_id WHERE j.child_id = ?1 ", nativeQuery = true)
public List<Person> getPeopleViaChildId(long id);
每当我想从一个孩子那里得到所有的人时,我都会使用它。
【讨论】:
以上是关于spring boot + hibernate 如何实现前后端交互的。如果前台提交一个表单进行保存的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot:在单元测试中使用 Hibernate Session
使用 Spring Boot、Jackson 和 Hibernate 的多对多关系
Spring Boot2 系列教程 | 使用 Spring Data JPA 访问 Mysql
SCD (slowly changed dimension) Type 4/6 - 如何在spring boot app, hibernate envers中实现