如何使用spring boot将数据从一个html表单传递到多个表
Posted
技术标签:
【中文标题】如何使用spring boot将数据从一个html表单传递到多个表【英文标题】:How to pass data from one html form to multiple tables using spring boot 【发布时间】:2019-02-14 20:22:36 【问题描述】:我编写了三个类(User
、UserCredential
、Address
),我想使用映射将数据存储到表中。我正在使用 JSON 将数据存储到表中。
当我存储数据时,数据存储在所有表中,但在用户 ID 中显示 1
,在 UserCredential id 中显示 3
,在地址 ID 中显示 2
,而在第一个条目中,所有 id 应为 @ 987654327@.
类是
package com.spring.demo.model;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name="user")
public class User
@Id
@Column(name="user_id")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String fName;
private String lName;
@Column(unique=true,nullable=true)
private String email;
@Column(unique=true,nullable=true)
private long mobile;
private Date dob;
@Lob
private byte[] image;
@Transient
private String base64Image;
@OneToOne(cascade=CascadeType.ALL,fetch =FetchType.EAGER)
@JoinColumn(name="userCredential_id")
private UserCredential userCredential;
@OneToOne(cascade=CascadeType.ALL,fetch =FetchType.EAGER)
@JoinColumn(name="add_id")
private Address address;
public Address getAddress()
return address;
public void setAddress(Address address)
this.address = address;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getfName()
return fName;
public void setfName(String fName)
this.fName = fName;
public String getlName()
return lName;
public void setlName(String lName)
this.lName = lName;
public String getEmail()
return email;
public void setEmail(String email)
this.email = email;
public long getMobile()
return mobile;
public void setMobile(long mobile)
this.mobile = mobile;
public Date getDob()
return dob;
public void setDob(Date dob)
this.dob = dob;
public byte[] getImage()
return image;
public void setImage(byte[] image)
this.image = image;
public UserCredential getUserCredential()
return userCredential;
public void setUserCredential(UserCredential userCredential)
this.userCreenter code heredential = userCredential;
UserCredential.java
package com.spring.demo.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
public class UserCredential
@Id
@Column(name="credential_id")
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(unique=true,nullable=true)
private String username;
private String password;
private String cnfrmpassword;
@JsonIgnore
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="user_id")
private User user;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public String getCnfrmpassword()
return cnfrmpassword;
public void setCnfrmpassword(String cnfrmpassword)
this.cnfrmpassword = cnfrmpassword;
public User getUser()
return user;
public void setUser(User user)
this.user = user;
Address.java
package com.spring.demo.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="address")
public class Address
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="add_id")
private int id;
@Column(name="city")
private String city;
@Column(name="state")
private String state;
@Column(name="house_no")
private String h_no;
@ManyToOne
@JoinColumn(name="user_id", nullable=true)
private User user;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getCity()
return city;
public void setCity(String city)
this.city = city;
public String getState()
return state;
public void setState(String state)
this.state = state;
public String getH_no()
return h_no;
public void setH_no(String h_no)
this.h_no = h_no;
public User getUser()
return user;
public void setUser(User user)
this.user = user;
我真的不明白如何克服这个问题。
JSON
格式存储数据
"fName":"suresh kumst",
"lName":"dingh",
"mobile":4595498366,
"email":"ksuraj1sd00@gmail.com",
"dob":"2012-04-23T18:25:43.511Z",
"address":
"city":"noida",
"state":"up",
"h_no":"123"
,
"userCredential":
"username":"ksuraj1asd002",
"password":"12345",
"cnfrmpassword":"12345"
和不同id的响应,虽然它们在第一个条目中应该是1并且用户id应该有值
"id": 1,
"fName": "suresh kumst",
"lName": "dingh",
"email": "ksuraj1sd00@gmail.com",
"mobile": 4595498366,
"dob": "2012-04-23T18:25:43.511+0000",
"image": null,
"userCredential":
"id": 3,
"username": "ksuraj1asd002",
"password": "12345",
"cnfrmpassword": "12345"
,
"address":
"id": 2,
"city": "noida",
"state": "up",
"h_no": "123",
"user": null
【问题讨论】:
定义实际使用什么类型的值生成? IDENTITY (AUTO_INCREMENT) 列?数据库序列?一个单独的表保存每个表的ID?因为只指定“AUTO”就表示“我不在乎你选择哪个,就去做吧”,JPA 提供者会做它想做的事 【参考方案1】:在这里,您使用的是@GeneratedValue(strategy=GenerationType.AUTO)
。
一些数据库将使用一个通用序列来生成和分配序列号。 Hibernate会创建一个表hibernate_sequence
,所有的实体表都会引用这个表来获取下一个序列号。因此,主键将分散在实体之间。
要使每个实体的主键从 1 开始,请对每个实体使用 @GeneratedValue(strategy=GenerationType.IDENTITY)
。
【讨论】:
是的,它完成了你提到的。但是还有另一个问题外键(user_id)始终保持为零,而它应该等于用户表的主键。请帮我解决这个问题。 这个问题在哪个表中?你能提供那个表的列名吗?【参考方案2】:当您使用@GeneratedValue(strategy=GenerationType.AUTO)
时,底层 ORM 框架将使用标识列、序列或表,具体取决于底层数据库。在您的情况下,我猜它正在使用一个序列(用于为所有表生成 ID 的单个序列)。如果是这种情况,为了实现每个表 ID 独立于其他表,您必须为每个实体赋予不同的序列名称。
如果您使用的是 Hibernate,请考虑使用 @GenericGenerator
。来自其他SO answer的示例:
@GenericGenerator(
name = "wikiSequenceGenerator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters =
@Parameter(name = "sequence_name", value = "WIKI_SEQUENCE"),
@Parameter(name = "initial_value", value = "1000"),
@Parameter(name = "increment_size", value = "1")
)
@Id
@GeneratedValue(generator = "wikiSequenceGenerator")
【讨论】:
并将自己绑定到一个特定的 JPA 提供者,没有特别的原因......在 OP 的情况下,甚至没有关于是否支持序列的信息(他提到了数据库吗?)跨度> 【参考方案3】:请使用 DB 序列,以便更好地控制生成的 ID,这里我只是分享一个假设后端 DB 为 Oracle/mysql
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator = "employee_sequence")
@SequenceGenerator(name = "employee_sequence", sequenceName = "EMP_SN")
private Long empNo;
这里EMP_SN
是数据库序列。
希望这能解决您的问题。
【讨论】:
在数据库不支持序列的情况下如何使用序列?他们不能。当 JPA 提供者决定使用 TABLE 时,“AUTO”会忽略您的 SequenceGenerator 规范。以上是关于如何使用spring boot将数据从一个html表单传递到多个表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Boot 应用程序从 Rest API 返回 html
如何从 Spring Boot 项目创建 jar,这个 jar 我们想在另一个 Spring Boot 应用程序中使用?