zoukankan      html  css  js  c++  java
  • Spring Data JPA 实现多表关联查询

    本文地址:https://liuyanzhao.com/6978.html

    最近抽出时间来做博客,数据库操作使用的是 JPA,相对比 Mybatis 而言,JPA 单表操作非常方便,增删改查都已经写好了。但是多表操作就不如 Mybatis 那种直接写 sql 语句来得方便,JPA 的多表操作比较麻烦。

    需求描述

    获得文章列表,文章列表里需要显示每篇文章的分类目录列表,因为一个文章可能有多个分类,一个分类当然也可以对应多篇文章的。

    下面是我用截图软件画的一个图,描述的是三张表和其主要字段。

    Spring Data JPA 实现多表关联查询

    文章表 article 和分类表 category 通过 中间表 article_category 关联

    我们的需求也很简单,从数据库里查询所有文章,并给每篇文章加一个分类列表的属性。

    如图像这样

    Spring Data JPA 实现多表关联查询

    代码实现

    Spring Data JPA 需要的依赖和配置文件这里就不给出了,因为不是本文的重点。

    实体类

    1、实体类 Article.java

     
    1. package com.liuyanzhao.blog.entity;
    2. import javax.persistence.*;
    3. import java.io.Serializable;
    4. import java.util.Date;
    5. import java.util.Set;
    6. /**
    7.  * @author 言曌
    8.  * @date 2017/12/11 下午7:46
    9.  */
    10. @Entity
    11. @Table(name = "article")
    12. public class Article implements Serializable {
    13.     private static final long serialVersionUID = 7419229779731522702L;
    14.     @Id
    15.     @GeneratedValue(strategy = GenerationType.IDENTITY)
    16.     private Integer id;
    17.     @Lob//text
    18.     @Column(columnDefinition="text")
    19.     private String title;
    20.     @Lob //longtext
    21.     @Column(columnDefinition="longtext")
    22.     private String content;
    23.     private Integer userId;
    24.     private Integer likeCount;
    25.     private Date createTime;
    26.     private Date updateTime;
    27.     private Integer status;
    28.     @OneToMany(mappedBy = "article",cascade = CascadeType.ALL, orphanRemoval = true)
    29.     private Set<ArticleCategory> articleCategoryList;
    30.     public Integer getId() {
    31.         return id;
    32.     }
    33.     public void setId(Integer id) {
    34.         this.id = id;
    35.     }
    36.     public String getTitle() {
    37.         return title;
    38.     }
    39.     public void setTitle(String title) {
    40.         this.title = title;
    41.     }
    42.     public String getContent() {
    43.         return content;
    44.     }
    45.     public void setContent(String content) {
    46.         this.content = content;
    47.     }
    48.     public Integer getUserId() {
    49.         return userId;
    50.     }
    51.     public void setUserId(Integer userId) {
    52.         this.userId = userId;
    53.     }
    54.     public Integer getLikeCount() {
    55.         return likeCount;
    56.     }
    57.     public void setLikeCount(Integer likeCount) {
    58.         this.likeCount = likeCount;
    59.     }
    60.     public Date getCreateTime() {
    61.         return createTime;
    62.     }
    63.     public void setCreateTime(Date createTime) {
    64.         this.createTime = createTime;
    65.     }
    66.     public Date getUpdateTime() {
    67.         return updateTime;
    68.     }
    69.     public void setUpdateTime(Date updateTime) {
    70.         this.updateTime = updateTime;
    71.     }
    72.     public Integer getStatus() {
    73.         return status;
    74.     }
    75.     public void setStatus(Integer status) {
    76.         this.status = status;
    77.     }
    78.     public static long getSerialVersionUID() {
    79.         return serialVersionUID;
    80.     }
    81.     public Set<ArticleCategory> getArticleCategoryList() {
    82.         return articleCategoryList;
    83.     }
    84.     public void setArticleCategoryList(Set<ArticleCategory> articleCategoryList) {
    85.         this.articleCategoryList = articleCategoryList;
    86.     }
    87. }

    注意 43-44 行

    2、实体类 Category.java

     
    1. package com.liuyanzhao.blog.entity;
    2. import javax.persistence.*;
    3. import java.io.Serializable;
    4. import java.util.Set;
    5. /**
    6.  * @author 言曌
    7.  * @date 2017/12/11 下午8:16
    8.  */
    9. @Entity
    10. @Table(name = "category")
    11. public class Category implements Serializable {
    12.     private static final long serialVersionUID = 7419229779731522702L;
    13.     @Id
    14.     @GeneratedValue(strategy = GenerationType.IDENTITY)
    15.     private Integer id;
    16.     private String name;
    17.     private String key;
    18.     private Integer status;
    19.     @OneToMany(mappedBy = "category")
    20.     private Set<ArticleCategory> articleCategoryList;
    21.     public Integer getId() {
    22.         return id;
    23.     }
    24.     public void setId(Integer id) {
    25.         this.id = id;
    26.     }
    27.     public String getName() {
    28.         return name;
    29.     }
    30.     public void setName(String name) {
    31.         this.name = name;
    32.     }
    33.     public Integer getStatus() {
    34.         return status;
    35.     }
    36.     public void setStatus(Integer status) {
    37.         this.status = status;
    38.     }
    39.     public String getKey() {
    40.         return key;
    41.     }
    42.     public void setKey(String key) {
    43.         this.key = key;
    44.     }
    45.     public static long getSerialVersionUID() {
    46.         return serialVersionUID;
    47.     }
    48.     public Set<ArticleCategory> getArticleCategoryList() {
    49.         return articleCategoryList;
    50.     }
    51.     public void setArticleCategoryList(Set<ArticleCategory> articleCategoryList) {
    52.         this.articleCategoryList = articleCategoryList;
    53.     }
    54. }

    注意 28-29 行

    3、实体类 ArticleCategory.java

     
    1. package com.liuyanzhao.blog.entity;
    2. import javax.persistence.*;
    3. import java.io.Serializable;
    4. /**
    5.  * @author 言曌
    6.  * @date 2017/12/12 下午4:08
    7.  */
    8. @Entity
    9. @Table(name = "article_category")
    10. public class ArticleCategory implements Serializable {
    11.     private static final long serialVersionUID = 7419229779731522702L;
    12.     @Id
    13.     @ManyToOne
    14.     @JoinColumn(name = "article_id")
    15.     private Article article;
    16.     @Id
    17.     @ManyToOne
    18.     @JoinColumn(name = "category_id")
    19.     private Category category;
    20.     public static long getSerialVersionUID() {
    21.         return serialVersionUID;
    22.     }
    23.     public Article getArticle() {
    24.         return article;
    25.     }
    26.     public void setArticle(Article article) {
    27.         this.article = article;
    28.     }
    29.     public Category getCategory() {
    30.         return category;
    31.     }
    32.     public void setCategory(Category category) {
    33.         this.category = category;
    34.     }
    35. }

    注意 17-25 行

    Dao 层

    1、ArticleDao.java

     
    1. package com.liuyanzhao.blog.dao;
    2. import com.liuyanzhao.blog.entity.Article;
    3. import com.liuyanzhao.blog.vo.ArticleVO;
    4. import org.springframework.data.domain.Page;
    5. import org.springframework.data.domain.Pageable;
    6. import org.springframework.data.jpa.repository.JpaRepository;
    7. /**
    8.  * @author 言曌
    9.  * @date 2017/11/28 下午3:31
    10.  */
    11. public interface ArticleDao extends JpaRepository<Article, Integer> {
    12.     //获取文章列表,按status和id降序
    13.     Page<ArticleVO> findAllByOrderByStatusDescIdDesc(Pageable pageable);
    14. }

    2、CategoryDao.java

     
    1. package com.liuyanzhao.blog.dao;
    2. import com.liuyanzhao.blog.entity.Category;
    3. import org.springframework.data.jpa.repository.JpaRepository;
    4. /**
    5.  * @author 言曌
    6.  * @date 2017/12/12 上午11:16
    7.  */
    8. public interface CategoryDao  extends JpaRepository<Category, Integer> {
    9. }

    Service 层

    1、ArticleService.java

     
    1. package com.liuyanzhao.blog.service;
    2. import com.liuyanzhao.blog.vo.ArticleVO;
    3. import org.springframework.data.domain.Page;
    4. import org.springframework.data.domain.Pageable;
    5. /**
    6.  * @author 言曌
    7.  * @date 2017/12/9 下午4:10
    8.  */
    9. public interface ArticleService {
    10.     //获得文章列表
    11.     Page<ArticleVO> findAll(Pageable pageable);
    12. }

    2、ArticleServiceImpl.java

     
    1. package com.liuyanzhao.blog.service.Impl;
    2. import com.liuyanzhao.blog.dao.ArticleDao;
    3. import com.liuyanzhao.blog.service.ArticleService;
    4. import com.liuyanzhao.blog.vo.ArticleVO;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.data.domain.Page;
    7. import org.springframework.data.domain.Pageable;
    8. import org.springframework.stereotype.Service;
    9. import javax.transaction.Transactional;
    10. /**
    11.  * @author 言曌
    12.  * @date 2017/12/9 下午4:10
    13.  */
    14. @Service("articleService")
    15. @Transactional
    16. public class ArticleServiceImpl implements ArticleService {
    17.     @Autowired
    18.     private ArticleDao articleDao;
    19.     @Override
    20.     public Page<ArticleVO> findAll(Pageable pageable) {
    21.         Page<ArticleVO> articleVOPage = articleDao.findAllByOrderByStatusDescIdDesc(pageable);
    22.         return articleVOPage;
    23.     }
    24. }

    Controller 层

    ArticleController.java

     
    1. package com.liuyanzhao.blog.controller;
    2. import com.liuyanzhao.blog.service.ArticleService;
    3. import com.liuyanzhao.blog.vo.ArticleVO;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.data.domain.Page;
    6. import org.springframework.data.domain.PageRequest;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.web.bind.annotation.*;
    9. import org.springframework.web.servlet.ModelAndView;
    10. /**
    11.  * @author 言曌
    12.  * @date 2017/11/28 下午3:33
    13.  */
    14. @Controller
    15. public class ArticleController {
    16.     @Autowired
    17.     private ArticleService articleService;
    18.     @RequestMapping(value = "/admin/article")
    19.     public ModelAndView listUser(@RequestParam(value = "page",defaultValue = "1") Integer page,
    20.                                  @RequestParam(value = "size",defaultValue = "10") Integer size) {
    21.         ModelAndView modelAndView = new ModelAndView();
    22.         PageRequest request = new PageRequest(page-1,size);
    23.         Page<ArticleVO> articleVOPage = articleService.findAll(request);
    24.         modelAndView.addObject("articleVOPage",articleVOPage);
    25.         modelAndView.setViewName("/admin/article/list");
    26.         return modelAndView;
    27.     }
    28. }

    视图层

    视图层主要看表格的打印吧,分页部分和其他内容就不贴出来了

     
    1. <table class="table table-bordered">
    2.           <tr>
    3.               <th><input type="checkbox" id="allSelect" onclick="DoCheck()"></th>
    4.               <th>ID</th>
    5.               <th>作者</th>
    6.               <th>标题</th>
    7.               <th>分类</th>
    8.               <th>更新时间</th>
    9.               <th>操作</th>
    10.           </tr>
    11.           <c:forEach var="article" items="${articleVOPage.content}">
    12.               <tr>
    13.                   <td><input type="checkbox" name="ids" value="${article.id}"></td>
    14.                   <td>${article.id}</td>
    15.                   <td>${article.userId}</td>
    16.                   <td><href="">${article.title}</a></td>
    17.                   <td>
    18.                       <c:forEach var="c" items="${article.articleCategoryList}">
    19.                           <href="">${c.category.name}</a> &nbsp;
    20.                       </c:forEach>
    21.                   </td>
    22.                   <td>${article.updateTime}</td>
    23.                   <td>
    24.                       <href="${pageContext.request.contextPath}/admin/user/profile/${article.id}">
    25.                           <button type="button" class="btn btn-success btn-xs">查看</button>
    26.                       </a>
    27.                       <button type="button" class="btn btn-danger btn-xs"
    28.                               onclick="deleteUser(${article.id})">删除
    29.                       </button>
    30.                       <href="${pageContext.request.contextPath}/admin/user/edit/${article.id}">
    31.                           <button type="button" class="btn btn-primary btn-xs">编辑</button>
    32.                       </a>
    33.                   </td>
    34.               </tr>
    35.           </c:forEach>
    36.       </table>

    最终效果图就是上面的

    Spring Data JPA 实现多表关联查询

  • 相关阅读:
    strlen和sizeof
    函数值传递和地址传递
    指向函数的指针变量
    for循环scanf赋值刷新缓冲区
    指针
    排序简化
    随机数找到最大值
    上楼梯问题
    分布式系统并发情况下会生成多个token
    Swagger 文档生成工具
  • 原文地址:https://www.cnblogs.com/suizhikuo/p/9544233.html
Copyright © 2011-2022 走看看