一、理论
Spring Boot 框架分为四层,分别为 model 层、mapper 层、service 层和controller 层
model 层
- 数据模型层,相当于 MVC 中的 M层,又称 entity 层
- model 层存放实体类,数据库中的每一张表对应一个实体类,属性与表中的属性值基本保持一致
mapper 层
- 数据持久层,相当于 DAO 层(date access object)
- mapper 层直接与数据库进行交互,访问数据库,发送 SQL 语句,完成数据的增删改查操作,并提供接口给 service 层
service 层
- 业务逻辑层,分为接口和实现类
- 负责进行逻辑业务处理,并提供接口给 controller 层
controller 层
- 控制层,相当于 MVC 中的 C 层
- 负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
二、demo
最近也是做了一个小demo,熟悉了 Spring Boot 的整个结构

1、后端及数据库部分
整个项目后端部分的目录结构如下所示

1.1代码设计及实现
- 数据库设计
主要关注了 id、name、author、price

连接到数据库及端口配置
1 2 3 4 5 6 7 8 9 10 11 12 13
| spring: datasource: url: jdbc:mysql://localhost:3306/library?useUnicode&encodeing=UTF-8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver jpa: show-sql: true properties: hibernate: format_sql: true server: port: 8081
|
- entity 层
建立数据表 book 对应的实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.kang.springbootbook.entity;
import lombok.Data; import org.hibernate.annotations.Table;
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;
@Table(appliesTo = "book") @Entity @Data public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String author; private Integer price; }
|
- mapper 层
使用 JPA(Java Persistence API),提供了持久层的实现
JPA 可以为持久层提供基本的数据库操作,如基本的 CRUD 和排序、分页等
BookRepository.java
1 2 3 4 5 6 7 8
| package com.kang.springbootbook.repository;
import com.kang.springbootbook.entity.Book; import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Integer> {
}
|
- service 层
接口 BookService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.kang.springbootbook.service;
import com.kang.springbootbook.entity.Book; import org.springframework.data.domain.Page;
public interface BookService { public Page<Book> findAll(Integer page, Integer size);
public Book findById(Integer id);
public String save(Book book);
public String update(Book book);
public void delete(Integer id); }
|
实现类 BookServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.kang.springbootbook.service.impl;
import com.kang.springbootbook.entity.Book; import com.kang.springbootbook.repository.BookRepository; import com.kang.springbootbook.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service;
@Service public class BookServiceImpl implements BookService {
@Autowired private BookRepository bookRepository; @Override public Page<Book> findAll(Integer page, Integer size) { Pageable pageable = PageRequest.of(page-1, size); return bookRepository.findAll(pageable); }
@Override public Book findById(Integer id) { return bookRepository.findById(id).get(); }
@Override public String save(Book book) { if (bookRepository.save(book) != null) { return "success"; } else { return "error"; } }
@Override public String update(Book book) { if (bookRepository.save(book) != null) { return "success"; } else { return "error"; } }
@Override public void delete(Integer id) { bookRepository.deleteById(id); } }
|
- controller 层
BookHandler.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.kang.springbootbook.controller;
import com.kang.springbootbook.entity.Book; import com.kang.springbootbook.repository.BookRepository; import com.kang.springbootbook.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController @RequestMapping("/book") public class BookHandler { @Autowired private BookService bookService;
@GetMapping("findAll/{page}/{size}") public Page<Book> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size) { return bookService.findAll(page, size); }
@PostMapping("/save") public String save(@RequestBody Book book) { return bookService.save(book); }
@GetMapping("/findById/{id}") public Book findById(@PathVariable Integer id) { return bookService.findById(id); }
@PutMapping("/update") public String update(@RequestBody Book book) { return bookService.save(book); }
@DeleteMapping("/delete/{id}") public void delete(@PathVariable Integer id) { bookService.delete(id); } }
|
1.2 运行结果展示
findAll/1/6 查询,查询第一页的六个内容

findById/1 查询 id = 1 的内容

2、前端部分
前端使用了 vue + element UI 框架
整个项目前端部分的目录结构如下所示

2.1 运行结果展示
BookManage 界面,可以分页查询所有的 book

添加 book,通过 书名和作者 添加

更改 book 的内容,目前可以更改 书名和作者

删除 book

三、All in all
总之,这是自己跟着视频敲得一个练手的小 Demo,相比于原视频,添加了 Service 层,更改了 Vue 的部分显示
下面打算换掉 JPA,使用 MyBatis 实现 持久层