如何使用 Hibernate 和 JPA 处理填充下拉列表?

Posted

技术标签:

【中文标题】如何使用 Hibernate 和 JPA 处理填充下拉列表?【英文标题】:How to handle populating dropdown with Hibernate and JPA? 【发布时间】:2021-06-07 10:18:56 【问题描述】:

大家好,我正在通过一个简单的项目学习 Hibernate 和 JPA,该项目允许用户编辑 mysql 数据库中的学生信息字段。有两张桌子 - 一张给学生,一张给他/她的Favorite Movie学生只能从下拉列表中选择一部电影,但是我想不出如何用 中的数据(电影名称)填充下拉列表>最喜欢的电影

Student.java

@Entity
@Table(name = "student")
@NamedQueries(
    @NamedQuery(name = "Student.findAll", query = "SELECT s FROM Student s"))
public class Student implements Serializable     
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_student")
    private Integer idStudent;

    @Column(name = "name")
    private String name;
    
    @JoinColumn(name = "id_movie", referencedColumnName = "id_movie")
    @ManyToOne(cascade = CascadeType.ALL)
    private FavoriteMovie favoriteMovie;
    
    /* Getters/Setters */
    
    @Override
    public int hashCode() 
        int hash = 0;
        hash += (idStudent != null ? idStudent.hashCode() : 0);
        return hash;
    

    @Override
    public boolean equals(Object object) 
        if (!(object instanceof Student)) 
            return false;
        
        Student other = (Student) object;
        if ((this.idStudent == null && other.idStudent != null) || (this.idStudent != null && !this.idStudent.equals(other.idStudent))) 
            return false;
        
        return true;
    

    @Override
    public String toString() 
        return "Student" + "idStudent=" + idStudent + 
                ", name=" + name + 
                ", favoriteMovie=" + favoriteMovie + '';
    
   

FavoriteMovie.java

@Entity
@Table(name = "favorite_movie")
@NamedQueries(
    @NamedQuery(name = "FavoriteMovie.findAll", query = "SELECT m FROM FavoriteMovie m"))
public class FavoriteMovie implements Serializable 
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_movie")
    private Integer idFavoriteMovie;

    @Column(name = "movie_name")
    private String favoriteMovieName;

    @Column(name = "movie_year")
    private int favoriteMovieYear;

    @OneToMany(mappedBy = "favoriteMovie")
    private List<Student> studentList;
    
    public FavoriteMovie() 
        
    
    public FavoriteMovie(Integer idFavoriteMovie) 
        this.idFavoriteMovie = idFavoriteMovie;
    

    public FavoriteMovie(Integer idFavoriteMovie, String favoriteMovieName) 
        this.idFavoriteMovie = idFavoriteMovie;
        this.favoriteMovieName = favoriteMovieName;
       
    /* Getters/Setters */

EditServlet.java

@WebServlet("/EditServlet")
public class EditServlet extends HttpServlet 

    private static final long serialVersionUID = 1L;

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException 

        String idStudent = request.getParameter("idStudent");

        StudentService studentService = new StudentService();

        Student student = studentService.findStudent(Integer.parseInt(idStudent));
        
        HttpSession session = request.getSession();
        session.setAttribute("student", student);
        
        request.getRequestDispatcher("/WEB-INF/editStudent.jsp").forward(request, response);
    

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException 

        
        String action = request.getParameter("modify");
        if ("modify".equals(action)) 
        
            String name = request.getParameter("name");
            
            HttpSession session = request.getSession();
            Student student = (Student) session.getAttribute("student");            
            
            student.setName(name);
            
            String favoriteMovieName = request.getParameter("favoriteMovieName");

            student.getFavoriteMovie().setFavoriteMovieName(favoriteMovieName);     
            
            
            StudentService studentService = new StudentService();
            studentService.saveStudent(student);
            
            session.removeAttribute("student");

        
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    

editStudent.jsp

<body>
        Modify Student
        <br/>
        <form name ="form1" action="$pageContext.request.contextPath/EditServlet" method="post">
            Id Student: <input type="text" name="idStudent" value="$student.idStudent" readonly="readonly"><br/>
            Name: <input type="text" name="name" value="$student.name"><br/>

            Favorite Movie: <select name="selectedFavoriteMovie" id="selectedFavoriteMovie"> 
                <c:forEach var="favoriteMovie" items="" >
                    <option value="">
                        
                    </option>
                </c:forEach>
            </select><br/><br/>
            
            <input type="submit" name="edit" value="edit">
            
        </form>
    </body>

必须使用 FavoriteMovies 表中的所有 电影名称 填充下拉列表。

【问题讨论】:

【参考方案1】:

我认为它非常适合您当前的解决方案,无需进行太多修改 :) 我想 - 因为你有一个 StudentService - 你也有一个可以做的 FavoriteMovieService:

List<FavoriteMovie> movies = new FavoriteMovieService().getAll();

如果是这样 - 您可以在 GET 请求上为 servlet 添加一个附加属性,如下所示:

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException 

    String idStudent = request.getParameter("idStudent");

    StudentService studentService = new StudentService();

    Student student = studentService.findStudent(Integer.parseInt(idStudent));

    List<FavoriteMovie> movies = new FavoriteMovieService().getAll();
    
    HttpSession session = request.getSession();
    session.setAttribute("student", student);
    session.setAttribute("movies", movies);
    
    request.getRequestDispatcher("/WEB-INF/editStudent.jsp").forward(request, response);

之后,您将能够在 JSP 中遍历该列表:

<c:forEach items="$movies" var="movie">
  <option value="$movie.getFavoriteMovieName()">$movie.getFavoriteMovieName()</option>
</c:forEach>

这应该对你有用:)

UPD:

    如何在下拉列表中显示所选电影:
    <c:forEach items="$movies" var="movie">
      <option value="$movie" selected="$movie.getFavoriteMovieName() == student.getFavouriteMovie().getFavouriteMovieName()">$movie.getFavoriteMovieName()</option>
    </c:forEach>
    如何更新电影:
 @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException 

        
        String action = request.getParameter("modify");
        if ("modify".equals(action)) 
        
            String name = request.getParameter("name");
            
            HttpSession session = request.getSession();
            Student student = (Student) session.getAttribute("student");            
            
            student.setName(name);
            
            FavoriteMovie favoriteMovie = request.getParameter("favoriteMovieName");

            student.setFavoriteMovie(favoriteMovie);     
            
            StudentService studentService = new StudentService();
            studentService.saveStudent(student);
            
            session.removeAttribute("student");

        
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    

【讨论】:

嘿,这非常适合列出所有可用的电影。但是有两个问题我无法解决。尝试更改学生最喜欢的电影时,表单不会提交新的最喜欢的电影。当学生有喜欢的电影时,它不会在下拉列表中选择。你能再推我一次吗:) 当然!我会尽快为您更新问题) 当试图更改电影标题时,它会更改 FavoriteMovie 表中的值,这是不受欢迎的行为,因为我只是学生在电影之间切换而不修改最喜欢的电影表。 嗨!请坚持:&lt;c:forEach items="$movies" var="movie"&gt; &lt;option value="$movie" selected="$movie.getFavoriteMovieName() == student.getFavouriteMovie().getFavouriteMovieName()"&gt;$movie.getFavoriteMovieName()&lt;/option&gt; &lt;/c:forEach&gt; 在哪里使用传递整个 FavoriteMovie 类作为值,而不仅仅是电影名称。并将其保存如下:FavoriteMovie favoriteMovie = request.getParameter("favoriteMovieName"); student.setFavoriteMovie(favoriteMovie);这将更新对学生记录的FavoriteMovie的引用,并且不会重写电影`【参考方案2】:

你有

<select name="selectedFavoriteMovie" id="selectedFavoriteMovie">

所以你也应该这样做:

request.getParameter("selectedFavoriteMovie");

也代替

<option value="$movie.getFavoriteMovieName()">$movie.getFavoriteMovieName()</option>

你可以这样做:

<option value="$movie">$movie.getFavoriteMovieName()</option>

在这种情况下,变量 selectedFavoriteMovie 将输入 FavoriteMovie 而不是 String,您将能够执行 student.setFavoriteMovie(selectedFavoriteMovie);

要选择实际选择的FavoriteMovie,您需要将selected 添加到option 。它可以通过几种方式完成,例如

<option value="$movie" $movie.getId() == student.getFavoriteMovie().getId() ? "selected" : "">$movie.getFavoriteMovieName()</option>

【讨论】:

以上是关于如何使用 Hibernate 和 JPA 处理填充下拉列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在pojo中用jpa或hibernate映射json字段?

JPA/Hibernate - 不需要的部分回滚和会话处理

Hibernate 和 Spring Data JPA 无法处理带有特殊字符的 Oracle 表名?

如何使用 JPA 和 Hibernate 设置默认查询超时?

如何将继承策略与 JPA 注释和 Hibernate 混合使用?

如何使用 JPA 和 Hibernate 防止 SQL 注入?