【问题标题】:Spring boot + hibernate controller春季启动+休眠控制器
【发布时间】:2016-04-17 05:11:05
【问题描述】:

我尝试创建一个迷你论坛,但我被卡住了。应该如何,首先您创建一个帖子并编写主题消息,它重定向到所有帖子并添加您创建的新帖子,用户单击帖子并在下一页显示所有填写的消息。另外我做了一个评论系统,我每个帖子都必须有 cmets,所以问题出在我的代码中cmets 确实存在,所以我改变并失败了。有人可以解释一下,如何用 Hibernate 纠正错误。

PostController 是:注意方法 seeMessage,它通过 id 查找帖子并显示消息。

package com.pandora.controllers;


import com.pandora.domain.Post;
import com.pandora.services.CommentService;
import com.pandora.services.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


@Controller
@RequestMapping("/posts")
public class PostController {

    @Autowired
    private PostService postService;

    @Autowired
    private CommentService commentService;

    @RequestMapping
    public String findAll(Model model) {
        model.addAttribute("posts", postService.findAll());
        return "post/post";
    }

    @RequestMapping(value = "/click", method = RequestMethod.GET)
    public String click() {
        return "post/new";
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addPost(@ModelAttribute Post post) {
        postService.addPost(post);
        return "redirect:/posts";
    }

    @RequestMapping(value = "/{title}/find", method = RequestMethod.GET)
    public String findByName(@PathVariable String title) {
        postService.findByTitle(title);
        return "redirect:/posts";
    }

    @RequestMapping(value = "/{id}/see", method = RequestMethod.GET)
    public String seeMessage(@PathVariable long id, Model model) {
        Post post = postService.findById(id);
        System.out.println("the id is " + id);
        System.out.println("the value of comments are " +post.getComments().size());

        model.addAttribute("post", post);
//        model.addAttribute("postMessage", post.getComments());

        return "post/postmessage";

    }

    @RequestMapping(value = "/{id}/delete")
    public String delete(@PathVariable long id) {
        postService.delete(id);
        return "redirect:/posts";
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(){
        return "login";
    }

}

CommentController 是:这里注意 addComment 方法,首先我从 id 帖子中找到它,然后我必须在创建的帖子中添加评论。

package com.pandora.controllers;

import com.pandora.domain.Comment;

import com.pandora.domain.Post;
import com.pandora.services.CommentService;
import com.pandora.services.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/comments")
public class CommentController {

    @Autowired
    private CommentService commentService;

    @Autowired
    private PostService postService;

    @RequestMapping(value = "/post/{postId}/comment", method = RequestMethod.POST)
    public String addComment(@PathVariable long postId, @ModelAttribute Comment comment){

        Post post = postService.findById(postId);

        System.out.println(post.getId());
        System.out.println(comment.getMessage());

        List comments = new ArrayList();

        comments.add(commentService.addComment(comment));

        post.setComments(comments);

        return "redirect:/posts";
    }

    @RequestMapping(value = "/{id}/delete", method = RequestMethod.GET)
    public String delete(@PathVariable long id){
        commentService.delete(id);
        return "redirect:/posts";
    }

}

帖子实体是:

package com.pandora.domain;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.List;

@Entity
@Setter
@Getter
@NoArgsConstructor
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "post")
    private List comments;

    @Column(length = 10000)
    private String message;

    private String title;
}

邮政服务是:

package com.pandora.services;

import com.pandora.domain.Post;
import com.pandora.domain.repositories.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class PostService {

    @Autowired
    private PostRepository postRepository;

    public Post addPost(Post post){
        return postRepository.saveAndFlush(post);
    }

    public List findAll(){
        return postRepository.findAll();
    }

    public Post findByTitle(String title){
        return postRepository.findByTitle(title);
    }

    public Post findById(long id){
        return postRepository.findOne(id);
    }

    public void delete(long id){
        postRepository.delete(id);
    }

}

评论实体是:

package com.pandora.domain;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Setter
@Getter
@NoArgsConstructor
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ManyToOne(fetch = FetchType.EAGER)
    private Post post;

    private String message;

}

而 CommentService 是:

package com.pandora.services;

import com.pandora.domain.Comment;
import com.pandora.domain.repositories.CommentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CommentService {

    @Autowired
    private CommentRepository commentRepository;

    public Comment addComment(Comment comment){
        return commentRepository.saveAndFlush(comment);
    }

    public List findAll(){
        return commentRepository.findAll();
    }

    public void delete(long id){
        commentRepository.delete(id);
    }

    public Comment findOne(long id){
        return commentRepository.findOne(id);
    }

}

和显示由 id 选择的帖子的 html 是:这里注意 th:each div 容器。我从 PostController cmets 中的列表中检索。但它不起作用,因为当我这样做时,它总是空的。我不知道为什么它是空的。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      layout:decorator="layout">

<div layout:fragment="content">

    <h2 align="center">
        <h2 align="left">
            <div th:text="${post.title}"></div>
        </h2>
    </h2>

    <h4 align="center">
        <div th:text="${post.message}"></div>
    </h4>
    <hr/>
    <h4>Comments:</h4>
    <br/>

    <h4>
        <div th:each="comments : ${post}">
           
            <label for="username"><div th:inline="text">[[${#httpServletRequest.remoteUser}]]: </div> </label>
            <div  th:each="comment : ${comments.comments}">
                <div  id="username" th:text="${comment}"></div>
            </div>
        </div>
    </h4>

    <br/>
    <form method="post" name="comment_form" id="comment_form" th:action="@{'/comments/post/{id}/comment'(id=${post.id}) }" role="form">
        <div class="form-group">
            <label for="message">Comment</label>
            <textarea rows="5" class="form-control" id="message" name="message"/>
        </div>
        <button type="submit" id="submit" class="btn btn-primary">Submit</button>
    </form>

</div>

</html>

【问题讨论】:

    标签: html spring hibernate spring-mvc jpa


    【解决方案1】:

    您还需要更改控制器。想想这样的事情,你现在有一个零 cmets 的帖子。然后用户在 PostController 方法上发表评论说:

     @RequestMapping(value = "/post/{postId}/addComment", method = RequestMethod.POST)
                public String addPost(@PathVariable("postId")long id, @ModelAttribute Comment comment) {
                    postService.addComment(id, comment);
                    return "redirect:/to_whatever";
                }
    

    在您的 PostService 中,您可能需要添加以下功能:

       public Post addComment(long id, Comment comment){
           Post post = postRepository.findOne(id);
           post.getComments().add(comment);
           return postRepository.saveAndFlush(post);
        }
    

    相应地更改您的 UI 发布调用。此外,这也将实现检索部分。假设您想为帖子获取 cmets,您需要做的就是通过 id(或任何其他唯一标识符)找到帖子并执行 post.getComments();

    Embeddable 将在帖子和评论之间建立一种 OneToMany 类型的关系。参考this for more details

    在数据库级别,您将拥有如下内容:

    POST TABLE
    post_id     post_name
      1            A
      2            B
    
    
    
    POST_COMMENTS TABLE
    post_id     message
      1            C
      1            D
      2            E
      2            F
    

    希望这能解决问题。

    【讨论】:

      【解决方案2】:

      根据您的情况,这就是我的理解:您有一个帖子和一些与之关联的 cmets。但是,当您尝试检索特定帖子的 cmets 时,您会看到所有 cmets(也来自其他帖子)。

      假设上述情况,我建议您不要将 cmets 视为一个单独的实体,因为 cmets 只有在有帖子且 cmets 必须与单个帖子关联时才会出现。 @Embeddable 可能会对此有所帮助。

      我的建议是尝试这样的事情:

      将评论设为可嵌入:

      @Embeddable
      public class Comment {
          private String message;
          ...
          ...
          //Any other properties you might need to add
      }
      

      在 Post Entity 中,进行以下更改:

      @Entity
      @Setter
      @Getter
      @NoArgsConstructor
      public class Post {
      
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          private long id;
      
          @ElementCollection(fetch=FetchType.EAGER)
          private List<Comment> comments = new ArrayList<>();
      
          @Column(length = 10000)
          private String message;
      
          private String title;
      }
      

      在此之后,您可能希望释放 CommentService 和 CommentRepository,因为它们将不再需要。让我知道这是否有帮助。

      【讨论】:

      • 但是它将如何工作?如果我嵌入了帖子评论,无论如何我需要通过 id 查找帖子并显示帖子中保存的所有 cmets。即使以这种方式,也有办法解决我的做法,但我无法完全理解,请查看 CommentController 的方法“addComment”,这样你会发现,当我从 html 帖子中单击时,它会转到该控制器并添加评论,但是问题是如何准确保存控制器?这就是为什么我首先通过 ID 找到帖子,然后我必须在此帖子 ID 中准确添加评论。
      • 当我在 PostController 中的“seeMessage”方法中检索所有这些 cmets 时
      猜你喜欢
      • 2015-06-30
      • 2020-05-17
      • 1970-01-01
      • 2018-04-25
      • 2020-10-21
      • 2016-03-24
      • 2018-01-23
      • 1970-01-01
      • 2013-08-29
      相关资源
      最近更新 更多