如何使用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 【问题描述】:

我编写了三个类(UserUserCredentialAddress),我想使用映射将数据存储到表中。我正在使用 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在多个数据库之间进行数据迁移

如何从 Spring Boot 项目创建 jar,这个 jar 我们想在另一个 Spring Boot 应用程序中使用?

将 CSV 读入 Spring Boot 应用程序时,如何将数据表列从累积转换为差异?

如何从 Spring Boot 提供静态 html?

使用spring boot将大量数据从一个集合复制到Mongodb中的另一个集合