SpringBoot2 Jpa具有關聯關係的表單提交

前言

在使用Jpa的時候,對幾個實體類做了關聯關係,在進行update操作時候,需要提交表單,除了封裝一個相關屬性的DTO之外,我們也可以這樣子操作:

首先,對於jpa來時底層使用的hibernate的ORM框架,實體類和數據庫中的表是做了映射的,那麼在我們提交表單的時候,如果做了關聯關係,我們提交具有外鍵的數據是無法提交的,如果我們相擁需要在實體類中定義一個只具有關聯表的主鍵的構造函數。具體看代碼:

實體類

// 這個是我們需要更新的實體,他關聯了Teacher和Collections兩張表, 並且屬性中並沒有teacherId和coll_id的屬性,所以按照正常提交時無法提交的
@Entity
@Table(name = "students")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler", "fieldHandler"})
public class Students {

    private Integer stuId;
    private String stuName;
    private Integer stuAge;
    private Integer stuSex;
    private Date stuBirth;
    private Collections collections;
    private Teacher teacher;

    @Id
    @Column(name = "stu_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getStuId() {
        return stuId;
    }

    public void setStuId(Integer stuId) {
        this.stuId = stuId;
    }

    @Column(name = "stu_name", length = 15)
    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    @Column(name = "stu_age", length = 3)
    public Integer getStuAge() {
        return stuAge;
    }

    public void setStuAge(Integer stuAge) {
        this.stuAge = stuAge;
    }

    @Column(name = "stu_sex", length = 1)
    public Integer getStuSex() {
        return stuSex;
    }

    public void setStuSex(Integer stuSex) {
        this.stuSex = stuSex;
    }

    @Column(name = "stu_birth")
    @Temporal(TemporalType.DATE)
    public Date getStuBirth() {
        return stuBirth;
    }

    public void setStuBirth(Date stuBirth) {
        this.stuBirth = stuBirth;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "coll_id")
    public Collections getCollections() {
        return collections;
    }

    public void setCollections(Collections collections) {
        this.collections = collections;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "teacher_id")
    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Students => [" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                ", stuSex=" + stuSex +
                ", stuBirth=" + stuBirth +
                ", collections=" + collections +
                ", teacher=" + teacher +
                ']';
    }
}

// 關聯表Teacher, 
// 我們在這個實體類中添加 默認構造函數和包含主鍵屬性的一個構造函數
@Entity
@Table(name = "teacher")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler", "fieldHandler"})
public class Teacher {


    private Integer teacherId;

    private String teacherName;

    private Integer teacherSex;

    private Set<Students> students;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "teacher_id")
    public Integer getTeacherId() {
        return teacherId;
    }

    public void setTeacherId(Integer teacherId) {
        this.teacherId = teacherId;
    }

    @Column(name ="teacher_name", length = 15)
    public String getTeacherName() {
        return teacherName;
    }

    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }

    @Column(name = "teacher_sex", length = 1)
    public Integer getTeacherSex() {
        return teacherSex;
    }

    public void setTeacherSex(Integer teacherSex) {
        this.teacherSex = teacherSex;
    }

    // 雙向一對多的關聯
    @JsonIgnore
    @OneToMany(targetEntity = Students.class)
    @JoinColumn(name = "teacher_id")
    public Set<Students> getStudents() {
        return students;
    }


    public void setStudents(Set<Students> students) {
        this.students = students;
    }

    // 默認
    public Teacher() {
    }
    // 只包含teacherId
    public Teacher(Integer teacherId) {
        this.teacherId = teacherId;
    }
    // 包含全部
    public Teacher(Integer teacherId, String teacherName, Integer teacherSex) {
        this.teacherId = teacherId;
        this.teacherName = teacherName;
        this.teacherSex = teacherSex;
    }

    @Override
    public String toString() {
        return "Teacher => [" +
                "teacherId=" + teacherId +
                ", teacherName='" + teacherName + '\'' +
                ", teacherSex=" + teacherSex +
                ']';
    }
}

// Collections實體類
@Entity
@Table(name = "collections")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler", "fieldHandler"})
public class Collections {


    private Integer collId;

    private String collName;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "coll_id")
    public Integer getCollId() {
        return collId;
    }

    public void setCollId(Integer collId) {
        this.collId = collId;
    }

    @Column(name = "coll_name", length = 25)
    public String getCollName() {
        return collName;
    }

    public void setCollName(String collName) {
        this.collName = collName;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Collections)) return false;
        Collections that = (Collections) o;
        return Objects.equals(getCollId(), that.getCollId()) &&
                Objects.equals(getCollName(), that.getCollName());
    }

    @Override
    public int hashCode() {

        return Objects.hash(getCollId(), getCollName());
    }


    public Collections() {
    }

    public Collections(Integer collId) {
        this.collId = collId;
    }

    public Collections(Integer collId, String collName) {
        this.collId = collId;
        this.collName = collName;
    }

    @Override
    public String toString() {
        return "Collections => [" +
                "collId=" + collId +
                ", collName='" + collName + '\'' +
                ']';
    }
}

前段的Ajax提交操作

// 編輯表單提交
    function edit_sub(){
        // 我們要提交的數據按如下格式封裝
        var data = {
            "stuId": $("input[name='stuId']").val(),
            "stuName": $("input[name='stuName']").val(),
            "stuAge": $("input[name='stuAge']").val(),
            "stuSex": $("input[name='stuSex']").val(),
            "stuBirth": $("input[name='stuBirth']").val(),
            "collections":{
                "collId": $("#inputClass").val()
            },
            "teacher":{
                "teacherId": $("#inputTeacher").val()
            }
        };
        // 修改post請求頭部
        $.ajaxSettings.contentType = "application/json;charset=UTF-8";
        $.post("/crud/stu/", JSON.stringify(data), function(res){
            console.log(res);
            if(res.code == 100){
                $('#edit_model').modal('hide');
                window.location.reload();
            }
        })
    }

控制器

    /**
     * @function 編輯頁面表單提交
     * @param students
     * @return
     */
    @PostMapping("/stu")
    @ResponseBody
    // 在參數中需要加 @RequestBody 否則這或報錯
    public Msg edit_sub(@RequestBody Students students){
        System.out.println("students : " + students);
        studentsService.updateById(students);
        return Msg.success();
    }

Service層

@Override
public void updateById(Students students) {
    // 調用JpaRepository中的save方法去更新
    studentsRepository.save(students);
}

Repository

public interface StudentsRepository extends Repository<Students, Integer>, JpaRepository<Students, Integer> {
}

附加

CrudRepository中也有save方法,但是和JpaRepository中的save方法是實現是不一樣的

CrudRepository中的save()
@Transactional
public <S extends T> S save(S entity) {
    if (entityInformation.isNew(entity)) {
        em.persist(entity);//是新的就插入
        return entity;
    } else {
        return em.merge(entity); //不是新的merge
    }
}
// CrudRepository 中的save方法是相當於merge+save ,它會先判斷記錄是否存在,如果存在則更新,不存在則插入記錄
JpaRepository中的save()
@Transactional
public <S extends T> List<S> save(Iterable<S> entities) {
    List<S> result = new ArrayList<S>();
    if (entities == null) {
        return result;
    }
    for (S entity : entities) {
        result.add(save(entity));
    }
    return result;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章