【问题标题】:How to get specific id from database using jpa?如何使用 jpa 从数据库中获取特定的 ID?
【发布时间】:2016-05-18 19:21:40
【问题描述】:

基本上我现在的工作是我有几个不同的.jsp 用于一所学校。 我可以添加课程,我可以添加学生,也可以将学生添加到特定课程。我想了解的是,我将如何只向学生展示用户(我)点击的任何特定课程。

        <form action="http://localhost:8080/School/add" method="POST">
        Kurs:
        <select name="coursedrop">
            <c:forEach items="${allCourses}" var="course">
                <option value="${course.id}">${course.id}: ${course.coursename}</option>
            </c:forEach>
        </select>
        Student:
        <select name="studentdrop">
            <c:forEach items="${allStudents}" var="student">
                <option value="${student.id}">${student.id}: ${student.studentname}</option>
            </c:forEach>
        </select>
        <input type="submit" value="Add"/>
    </form>

上面显示的表格是两个下拉列表,一个用于课程,另一个用于学生。例如,我可以将学生 nr.3 添加到课程 nr.5 到我的数据库中。所以至少这行得通..

我的下一步是向特定学生展示他们的特定课程。 我拥有的是一个将所有课程列为可点击链接的 .jsp 页面。像这样:

<tbody>
    <c:forEach items="${allCourses}" var="course">
       <tr>
          <td><a href="http://localhost:8080/School/course?id=${course.id}">${course.coursename}</a></td>
       </tr>
     </c:forEach>
 </tbody>

当我点击其中一个链接(即课程名称)时,我会进入另一个 .jsp 页面,该页面当前列出了所有学生,即使他们不在我点击的特定课程中。

这就是我的 servlet 的样子。 (如果很糟糕,我很抱歉)

    @Inject
SchoolBoundary sb;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    String path = request.getServletPath();
    String redirect = "/home.jsp";
    String forward = null;
    switch(path) {
        case "/student":
            request.setAttribute("allStudents", sb.getAllStudents());
            forward = "/student.jsp";
            break;
        case "/course":
            request.setAttribute("allStudents", sb.getAllStudents());
            forward = "/course.jsp";
            break;
        case "/add":
            request.setAttribute("allCourses", sb.getAllCourses());
            request.setAttribute("allStudents", sb.getAllStudents());
            forward = "/add.jsp";
            break;
        case "/home":
            request.setAttribute("allCourses", sb.getAllCourses());
            forward = "/home.jsp";
            break;
        default:
            request.setAttribute("allCourses", sb.getAllCourses());
            forward = "/home.jsp";
    }
    request.getRequestDispatcher(forward).forward(request, response);

我可以看到我的“getAllStudents”将显示所有学生,而不是按 id 显示(这是我认为我需要的,但我不知道如何..)。 还有我的“getAllStudents”:

    public Set<Student> getAllStudenter() {
    return new HashSet(studentFacade.findAll());
}

回顾一下。我希望能够只显示每门特定课程的学生,而不是所有课程的所有学生。感谢您的帮助:(

【问题讨论】:

  • 听起来您需要实现自己的.findAllByCourseId(Long courseId) 方法 - 将其添加到接口并编写您自己的查询(或从findAll() 列表中过滤结果)
  • @ochi 这就是我认为需要的。我只是不知道如何写它..这个后端的东西对我来说是全新的,所以我在这里在黑暗中拍摄以完成这项工作。我想我可以使用外观中的 .find(id) 方法,但我不确定如何使用:( 有什么帮助吗?
  • find(id) 会根据 id 找到一名学生 - 这不是你想要的。我不一定会为你写,但我可以在答案中给你提示
  • @ochi 我确实有一个查询,我可以通过它得到我想要的,只有每个特定课程的学生。我不知道在哪里/如何使用我自己的查询。我是在我的边界类还是在我的 servlet 中这样做?也许两者兼而有之。

标签: java jsp jpa jakarta-ee


【解决方案1】:

首先,我建议不要使用嵌入式 PK(除非您确实必须高度优化数据库模型,或者您无法更改现有模型,因为它超出了您的职责)。如果您添加一个简单的 ID(例如 tyoe Long)并在课程 ID 和学生 ID 的字段上添加唯一约束,您将具有几乎相同的行为。它将需要数据库中的更多内存,但除非我们不是在这个“连接表”中谈论很多行,否则这个额外的内存是可以忽略不计的。但是你得到的回报是一个更容易处理的实体模型。

如果您想获取所有正在参加特定课程的学生,您可以为此编写一个简单的 JPQL 查询。

首先获取课程的参考资料。在查询Kursinfo 中的所有学生之后,该课程与您感兴趣的课程相同。基本上像这样(它未经测试,可能包含小错误,但我想向您展示总体思路):

String query = "SELECT k.student FROM Kursinfo k WHERE k.kurs = :kurs";
TypedQuery<Student> q = entityManager.createQuery(query, Student.class);
q.setParameter("kurs", entityManager.getReference(kursId, Kurs.class));
return q.getResultList();

【讨论】:

    【解决方案2】:

    您需要在后端(而不是 servlet)中实现一个名为 findAllByCourseId(Long courseId) 的方法 - 类似于以下内容:

    public Set<Student> findAllByCourseId(Long courseId) {
        return new HashSet(studentFacade.findAllByCourseId(courseId));
    }
    

    然后你需要打开StudentFacade(我不确定,但它可能是一个接口并为这个方法添加一个定义。像:

    Set<Student> findAllByCourseId(Long courseId);
    

    最后,添加接口的实现(如果有的话)并实现新方法。大致如下:

    // filter the all list or use your own query
    public Set<Student> findAllByCourseId(Long courseId) {
        // this is filtering
        List<Student> allStudents = findAll();
        List<Student> filteredList = new ArrayList<Student>();
    
        for(Student student : allStudents ){
            if( student.getCourseId() == courseId ){
               filteredList.add(student);
            }
        }
    
        return new HashSet(filteredList);
    }
    

    【讨论】:

    • 您不应查询所有学生,然后在后端进行过滤。已经使用 JPA 在数据库级别进行过滤。想想一所大学可能有 30,000 名学生,但在特定课程中可能只有 20 名学生。
    • 这是一个真实、公平的评论。这不是解决问题的最佳方式
    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多