基于 JPA 开发的文章管理系统(CRUD)
- 1.实现文章实体
- 2.实现数据持久层
- 3.实现服务接口和服务接口的实现类
- 3.1 创建服务接口
- 3.2 编写服务接口的实现
- 4.实现增、删、改、查的控制层 API 功能
- 4.1 获取文章列表
- 4.2 根据 id 获取文章对象
- 4.3 新增
- 4.4 保存
- 4.5 删除
- 4.6 编辑
- 4.7 修改
- 5.实现增、删、改、查功能的视图层
1.实现文章实体
新建 Spring Boot 项目,然后在项目的业务代码入口下(入口类同级目录下)新建 entity
、repository
、service
、controller
文件夹,并在 service
文件夹中新建 impl
文件夹。
用鼠标右键单击 entity
文件夹,新建 Article 类。
package com.example.demo.entity;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@Entity
@Data
public class Article extends BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false, unique = true)
@NotEmpty(message = "标题不能为空")
private String title;
@Column(nullable = false)
private String body;
}
- @Entity:声明它是个实体,然后加入了注解 @Data,@Data 是 Lombok 插件提供的注解,以简化代码,自动生成 Getter、Setter 方法。文章的属性字段一般包含
id
、title
、keyword
、body
,以及发布时间、更新时间、处理人。这里只简化设置文章id
、关键词、标题和内容。 - @GeneratedValue:将 id 作为主键。GenerationType 为
identity
,代表由数据库统一控制id
的自增。如果属性为auto
,则是 Spring Boot 控制id
的自增。使用identity
的好处是,通过数据库来管理表的主键的自增,不会影响到其他表。 nullable = false, unique = true
:建立唯一索引,避免重复。@NotEmpty(message ="标题不能为空")
:作为提示和验证消息。
2.实现数据持久层
鼠标右键单击 repository
文件夹,然后新建接口。在 Kind 类型处选择接口 interface
,将名字设为 ArticleRepository。完成后的代码如下:
package com.example.demo.repository;
import com.example.demo.entity.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ArticleRepository extends JpaRepository<Article, Long>, JpaSpecificationExecutor<Article> {
Article findById(long id);
}
这里继承 JpaRepository 来实现对数据库的接口操作。
3.实现服务接口和服务接口的实现类
通过创建服务接口和服务接口的实现类来完成业务逻辑功能。
3.1 创建服务接口
package com.example.demo.service;
import com.example.demo.entity.Article;
import java.util.List;
public interface ArticleService {
public List<Article> getArticleList();
public Article findArticleById(long id);
}
3.2 编写服务接口的实现
在 impl
包下,新建 article
的 impl
实现 Service,并标注这个类为 Service 服务类。
通过 implements
声明使用 ArticleService 接口,并重写其方法,见以下代码:
package com.example.demo.service.impl;
import com.example.demo.entity.Article;
import com.example.demo.repository.ArticleRepository;
import com.example.demo.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Description: 标注为服务类
*/
@Service
public class ArticleServiceImpl implements ArticleService {
@Autowired
private ArticleRepository articleRepository;
/**
* Description: 重写service接口的实现,实现列表功能
*/
@Override
public List<Article> getArticleList() {
return articleRepository.findAll();
}
/**
* Description: 重写service接口的实现,实现根据id查询对象功能。
*/
@Override
public Article findArticleById(long id) {
return articleRepository.findById(id);
}
}
4.实现增、删、改、查的控制层 API 功能
接下来,实现增加、删除、修改和查询的控制层 API 功能。
package com.example.demo.controller;
import com.example.demo.entity.Article;
import com.example.demo.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
@Controller
@RequestMapping("article")
public class ArticleController {
@Autowired
private ArticleRepository articleRepository;
/**
* Description: 文章列表
*/
@RequestMapping("")
public ModelAndView articlelist(@RequestParam(value = "start", defaultValue = "0") Integer start,
@RequestParam(value = "limit", defaultValue = "5") Integer limit) {
start = start < 0 ? 0 : start;
Sort sort = Sort.by(Sort.Direction.DESC, "id");
Pageable pageable = PageRequest.of(start, limit, sort);
Page<Article> page = articleRepository.findAll(pageable);
ModelAndView mav = new ModelAndView("article/list");
mav.addObject("page", page);
return mav;
}
/**
* Description: 根据id获取文章对象
*/
@GetMapping("/{id}")
public ModelAndView getArticle(@PathVariable("id") Integer id) throws Exception {
Article articles = articleRepository.findById(id);
ModelAndView mav = new ModelAndView("article/show");
mav.addObject("article", articles);
return mav;
}
/**
* Description: 新增操作视图
*/
@GetMapping("/add")
public String addArticle() throws Exception {
return "article/add";
}
/**
* Description: 新增保存方法
*/
@PostMapping("")
public String saveArticle(Article model) throws Exception {
articleRepository.save(model);
return "redirect:/article/";
}
/**
* Description: 删除
*/
@DeleteMapping("/{id}")
public String del(@PathVariable("id") long id) throws Exception {
articleRepository.deleteById(id);
return "redirect:";
}
/**
* Description: 编辑视图
*/
@GetMapping("/edit/{id}")
public ModelAndView editArticle(@PathVariable("id") long id) throws Exception {
Article model = articleRepository.findById(id);
ModelAndView mav = new ModelAndView("article/edit");
mav.addObject("article", model);
return mav;
}
/**
* Description: 修改方法
*/
@PutMapping("/{id}")
public String editArticleSave(Article model, long id) throws Exception {
model.setId(id);
articleRepository.save(model);
return "redirect:";
}
}
- @Autowired:即自动装配。Spring 会自动将标记为 @Autowired 的元素装配好。这个注解可以用到构造器、变量域、方法、注解类型上,该注解用于自动装配。视图从 Bean 工厂中获取一个 Bean 时,Spring 会自动装配该 Bean 中标记为 @Autowired 的元素,而无须手动完成。
@RequestMapping("/article")
:用户访问网页的 URL。这个注解不限于 GET 方法。- ModelAndView:分为 Model 和 View。Model 负责从后台处理参数。View 就是视图,用于指定视图渲染的模板。
ModelAndView mav = new ModelAndView("article/list")
:指定视图和视图路径。mav.addObject("page", page)
:指定传递page
参数。
4.1 获取文章列表
/**
* Description: 文章列表
*/
@RequestMapping("")
public ModelAndView articlelist(@RequestParam(value = "start", defaultValue = "0") Integer start,
@RequestParam(value = "limit", defaultValue = "5") Integer limit) {
start = start < 0 ? 0 : start;
Sort sort = Sort.by(Sort.Direction.DESC, "id");
Pageable pageable = PageRequest.of(start, limit, sort);
Page<Article> page = articleRepository.findAll(pageable);
ModelAndView mav = new ModelAndView("article/list");
mav.addObject("page", page);
return mav;
}
4.2 根据 id 获取文章对象
/**
* Description: 根据id获取文章对象
*/
@GetMapping("/{id}")
public ModelAndView getArticle(@PathVariable("id") Integer id) throws Exception {
Article articles = articleRepository.findById(id);
ModelAndView mav = new ModelAndView("article/show");
mav.addObject("article", articles);
return mav;
}
4.3 新增
/**
* Description: 新增操作视图
*/
@GetMapping("/add")
public String addArticle() throws Exception {
return "article/add";
}
4.4 保存
/**
* Description: 新增保存方法
*/
@PostMapping("")
public String saveArticle(Article model) throws Exception {
articleRepository.save(model);
return "redirect:/article/";
}
4.5 删除
/**
* Description: 删除
*/
@DeleteMapping("/{id}")
public String del(@PathVariable("id") long id) throws Exception {
articleRepository.deleteById(id);
return "redirect:";
}
4.6 编辑
/**
* Description: 编辑视图
*/
@GetMapping("/edit/{id}")
public ModelAndView editArticle(@PathVariable("id") long id) throws Exception {
Article model = articleRepository.findById(id);
ModelAndView mav = new ModelAndView("article/edit");
mav.addObject("article", model);
return mav;
}
4.7 修改
/**
* Description: 修改方法
*/
@PutMapping("/{id}")
public String editArticleSave(Article model, long id) throws Exception {
model.setId(id);
articleRepository.save(model);
return "redirect:";
}
5.实现增、删、改、查功能的视图层
- 实现文章增加视图
- 实现文章显示视图
- 实现文章删除视图
- 编辑视图
- 实现分页视图
具体实现的前端代码不在此处展开。