使用 thymleaf 和选择对象形式将对象与数据绑定

发布于 2025-01-11 07:58:33 字数 5875 浏览 0 评论 0原文

我开始学习java和spring。 我在使用 thymeleaf 绑定数据时遇到问题。 我的实体看起来我的用户包含多对一关系的 ClassRoom(实体列表)。 我想准备网站来注册用户。用户应该能够选择教室。 在第一步中,我将 html 站点与数据库(课堂表)中的数据绑定,但我在返回所选文件时遇到问题。 我的用户实体看起来:

package Start.Model;


@Entity
@Table
@Getter
@Setter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    public User() {
    }

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<ClassRoom> classRoom;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "user_activity", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "activity_id"))
    private List<Activity> activity;

ClassRoom 实体看起来:

package Start.Model;

@Entity
@Table
@Data
public class ClassRoom {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    @JsonBackReference
    private User user;
}

Dtos 看起来:

package Start.DTOs;
@Data
public class UserDto {
    private String name;
    private String password;
    private AddressDto addressDto;
    private PhoneDto phoneDto;
    private List<ClassRoomDto> classRoomDtoList = new ArrayList<>();
    private List<ActivityDto> activityDtoList = new ArrayList<>();
}

package Start.DTOs;

import lombok.*;

@Data
public class ClassRoomDto {
    private String name;

}

控制器看起来:

package Start.Controller;

@Controller
public class WebController {

    @GetMapping("/registry")
    public String main(Model model) {
        model.addAttribute("userDto", new UserDto());
        model.addAttribute("classRoomListInput", classRoomService.getAllClassRoom());
        model.addAttribute("activityListInput", activityService.getActivityList());
        return "index";
    }

    @PostMapping("/save")
    public String save(@ModelAttribute("userDto") UserDto userDto, Model model) {
        UserDto userDto1 = (UserDto) model.getAttribute("userDto");
        User user = userService.prepareUserDtoToSave(userDto1);
        userRepo.save(user);
        return "display_user";
    }
}

注册表页面看起来:

<div class="container my-3">
    <div class="row">
        <div class="col-md-8 mx-auto">
            <h2>Employee Registration</h2>
            <form th:action="@{/save}" th:object="${userDto}" method="post">
                <div class="form-row">
                    </div>
                    <div class="col-md-6 form-group">
                        <label for="name_label">Name</label>
                        <input type="text" class="form-control" th:field="*{name}" id="name_label">
                    </div>
                <div class="col-md-6 form-group">
                    <label for="password_label">Password</label>
                    <input type="text" class="form-control" th:field="*{password}" id="password_label">
                </div>

                <div class="col-md-6 form-group">
                    <label for="phone_label">Phone</label>
                    <input type="text" class="form-control" th:field="*{phoneDto.number}" id="phone_label">
                </div>
                <div class="col-md-6 form-group">
                    <label for="address_label">Address</label>
                    <input type="text" class="form-control" th:field="*{addressDto.street}" id="address_label">
                    <label for="house_number_label">House Number</label>
                    <input type="text" class="form-control" th:field="*{addressDto.houseNumberDto.number}" id="house_number_label">
                </div>

                <div class="col-md-6 form-group">
                    <label for="classRoom-label">Choose ClassRooms</label>
                    <select class="form-control select picker" id="classRoom-label" multiple="multiple">
                        <option th:each="classRoom, iterstat : ${classRoomListInput}"
                                th:value="${classRoom.name}"
                                th:filed="*{classRoomDtoList}"
                                th:text="${classRoom.name}">
                        </option>
                    </select>
                </div>
                <div class="col-md-6 form-group">
                    <label for="activity-label">Choose Activity</label>
                    <select class="form-control select picker" id="activity-label" multiple="multiple" th:filed="*{activityDtoList}">
                        <option type="checkbox" th:each="activity : ${activityListInput}"
                                th:value="${activity.getId()}"
                                th:text="${activity.getName()}">
                        </option>
                    </select>
                </div>
                <button type="submit" class="btn btn-primary btn-block mt-3">Save</button>
            </form>
        </div>
    </div>
</div>

如您所见,寄存器应该返回 userDto 并归档 classRoomDtoList。 但在大多数情况下,classRoomDtoList 始终为 null 或 0(如果我初始化空 ArrayList)。 我一步步创建我的项目。 当我使用实体将数据发送到注册并保存页面时,它可以工作,但是当我将实体更改为 DTO 时,我坚持了下来。 请帮助我并表明我犯了什么错误。 整个“项目”位于 https://github.com/oizo64/0001

感谢您的帮助。

Im starting to learn java and spring.
I have problem with binding data using thymeleaf.
My entity looks that i have User witch contains ClassRoom (List of entity) in relationship many to one.
I want to prepare site to register user. User should have capability to select classRoom.
In first step I bind html site with data from database (classroom table), but I have problem with return selected files.
My user entity looks:

package Start.Model;


@Entity
@Table
@Getter
@Setter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    public User() {
    }

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<ClassRoom> classRoom;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "user_activity", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "activity_id"))
    private List<Activity> activity;

The ClassRoom entity looks:

package Start.Model;

@Entity
@Table
@Data
public class ClassRoom {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    @JsonBackReference
    private User user;
}

Dtos looks:

package Start.DTOs;
@Data
public class UserDto {
    private String name;
    private String password;
    private AddressDto addressDto;
    private PhoneDto phoneDto;
    private List<ClassRoomDto> classRoomDtoList = new ArrayList<>();
    private List<ActivityDto> activityDtoList = new ArrayList<>();
}

package Start.DTOs;

import lombok.*;

@Data
public class ClassRoomDto {
    private String name;

}

Controller looks:

package Start.Controller;

@Controller
public class WebController {

    @GetMapping("/registry")
    public String main(Model model) {
        model.addAttribute("userDto", new UserDto());
        model.addAttribute("classRoomListInput", classRoomService.getAllClassRoom());
        model.addAttribute("activityListInput", activityService.getActivityList());
        return "index";
    }

    @PostMapping("/save")
    public String save(@ModelAttribute("userDto") UserDto userDto, Model model) {
        UserDto userDto1 = (UserDto) model.getAttribute("userDto");
        User user = userService.prepareUserDtoToSave(userDto1);
        userRepo.save(user);
        return "display_user";
    }
}

And registry page looks:

<div class="container my-3">
    <div class="row">
        <div class="col-md-8 mx-auto">
            <h2>Employee Registration</h2>
            <form th:action="@{/save}" th:object="${userDto}" method="post">
                <div class="form-row">
                    </div>
                    <div class="col-md-6 form-group">
                        <label for="name_label">Name</label>
                        <input type="text" class="form-control" th:field="*{name}" id="name_label">
                    </div>
                <div class="col-md-6 form-group">
                    <label for="password_label">Password</label>
                    <input type="text" class="form-control" th:field="*{password}" id="password_label">
                </div>

                <div class="col-md-6 form-group">
                    <label for="phone_label">Phone</label>
                    <input type="text" class="form-control" th:field="*{phoneDto.number}" id="phone_label">
                </div>
                <div class="col-md-6 form-group">
                    <label for="address_label">Address</label>
                    <input type="text" class="form-control" th:field="*{addressDto.street}" id="address_label">
                    <label for="house_number_label">House Number</label>
                    <input type="text" class="form-control" th:field="*{addressDto.houseNumberDto.number}" id="house_number_label">
                </div>

                <div class="col-md-6 form-group">
                    <label for="classRoom-label">Choose ClassRooms</label>
                    <select class="form-control select picker" id="classRoom-label" multiple="multiple">
                        <option th:each="classRoom, iterstat : ${classRoomListInput}"
                                th:value="${classRoom.name}"
                                th:filed="*{classRoomDtoList}"
                                th:text="${classRoom.name}">
                        </option>
                    </select>
                </div>
                <div class="col-md-6 form-group">
                    <label for="activity-label">Choose Activity</label>
                    <select class="form-control select picker" id="activity-label" multiple="multiple" th:filed="*{activityDtoList}">
                        <option type="checkbox" th:each="activity : ${activityListInput}"
                                th:value="${activity.getId()}"
                                th:text="${activity.getName()}">
                        </option>
                    </select>
                </div>
                <button type="submit" class="btn btn-primary btn-block mt-3">Save</button>
            </form>
        </div>
    </div>
</div>

As you can see register should return userDto with filed classRoomDtoList.
But in ma case classRoomDtoList is always null or 0 (if i initialize empty ArrayList).
I create my project step by step.
When i use entity to send data to registration and save page it works, but when i change entity to DTO I stuck on it.
Please help me and show what mistake i made.
Whole "project" is on https://github.com/oizo64/0001

Thank you for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文