第六篇:基于SpringBoot的SSMP整合案例 -- 后端开发篇

简介: 第六篇:基于SpringBoot的SSMP整合案例 -- 后端开发篇

案例实现方案分析


实体类开发————使用Lombok快速制作实体类


Dao开发————整合MyBatisPlus,制作数据层测试类


Service开发————基于MyBatisPlus进行增量开发,制作业务层测试类


Controller开发————基于Restful开发,使用PostMan测试接口功能,前后端开发协议制作


页面开发————基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理


列表、新增、修改、删除、分页、查询


项目异常处理


按条件查询————页面功能调整、Controller修正功能、Service修正功能


数据库创建


1.png


实体类开发


@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}


数据层开发


基本开发


@Mapper
public interface BookDao extends BaseMapper<Book> {
}


MyBatisPlus


Druid – 默认使用的是日本的一个叫做 光 的数据库


手工导入两个坐标


<!--        使用mp-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
<!--        使用druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>


配置文件


server:
  port: 80
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
      username: root
      password: 123456
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto


继承BaseMapper并指定泛型


@Mapper就可以不用写实体类,编译运行的时候就会自动生成
继承 extends BaseMapper 里面要写对应实体类 就是要操作哪一个bean对象。
@Repository   // 这个注释就是将bean对象存放到Spring容器中
@Mapper  // 这个注解就是编译的时候会自动生成实体类
public interface BookDao extends BaseMapper<Book> {
}


开发流程


手工导入starter坐标(2个) 一个是mp坐标,一个是druid

配置数据源与MyBatisPlus对应的配置 – 配置坐标不知道的信息,比如哪一个数据库,数据库账号和密码


开发Dao接口(继承BaseMapper)-- 继承这个类之后,就相当于产生了很多种已经写好的方法了。直接调用即可。


制作测试类测试Dao功能是否有效


为方便调试可以开启MyBatisPlus的日志


mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


分页功能


分页操作需要设定分页对象IPage


@Test
void testGetPage(){
IPage page = new Page(1,5);
bookDao.selectPage(page,null);
}


bookDao中有一个方法叫做selectPage的方法,就可以实现分页效果,一个参数是Ipage对象,一个参数对象是null;


Ipage对象的参数是 第一个参数指的是显示第几页信息,第二个参数指的是一页展示几条数据。


selectPage返回对象就是上面定义的page对象。


System.out.println(page.getRecords());


还需要注意的是,需要再写一个拦截器。分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现。


package com.itheima.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MPConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}


查询功能


推荐使用LambdaQueryWrapper对象,所有查询操作封装成方法调用


//    条件查询功能
    @Test
    void testGetByCondition() {
        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper();
        String name = "Spring";
        lqw.like(name != null ,Book::getName , name);
        bookDao.selectList(lqw);
    }


还有一个方法就是可以通过id直接查询到对象信息。


//    测试通过id进行查询
    @Test
    void contextLoads() {
        System.out.println(bookDao.selectById(1));
    }


还有一个获取全部信息的功能。


//    获取数据库的全部资料
    @Test
    void testGetAll() {
        System.out.println(bookDao.selectList(null));
    }


增删改



//    测试增加数据
    @Test
    void testSave() {
        Book book = new Book();
        book.setType("测试");
        book.setName("测试");
        book.setDescription("测试");
        bookDao.insert(book);
    }


删除 – 通过id进行数据删除


//    通过id删除数据
    @Test
    void testDelete() {
        bookDao.deleteById(10);
    }


更新 – 通过id修改数据信息,参数是Book对象,但是修改是通过id索引的。所以必须要写出id。


//    测试修改数据
    @Test
    void testUpdate() {
        Book book = new Book();
        book.setId(10);
        book.setType("测试");
        book.setName("测试");
        book.setDescription("测试");
        bookDao.updateById(book);
    }


业务层开发


使用MyBatisPlus提供有业务层通用接口(ISerivce)与业务层通用实现类(ServiceImpl,在通用类基础上做功能重载或功能追加。


接口


public interface IBookService extends IService<Book> {
//    自己写的方法
    Book findById(Integer id);
//    自己写的分页方法
    IPage<Book> getPage(int currentPage , int pageSize);
}


实体类


@Service
public class BookServlceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;
    @Override
    public Book findById(Integer id) {
        return  bookDao.selectById(id);
    }
    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage page = new Page(currentPage,pageSize);
        bookDao.selectPage(page,null);
        return page;
    }
}


增删改



//    测试增加数据
    @Test
    void testSave() {
        Book book = new Book();
        book.setType("测试");
        book.setName("测试");
        book.setDescription("测试");
        iBookService.save(book);
    }



//    通过id删除数据
    @Test
    void testDelete() {
        iBookService.removeById(8);
    }



//    测试修改数据
    @Test
    void testUpdate() {
        Book book = new Book();
        book.setId(11);
        book.setType("测试");
        book.setName("测试");
        book.setDescription("测试");
        boolean b = iBookService.updateById(book);
    }



查询所有信息


//    获取数据库的全部资料
    @Test
    void testGetAll() {
        System.out.println(iBookService.list());
    }


通过id进行查询


@Test
    void testGetById() {
        System.out.println(iBookService.getById(1));
    }


分页


//    分页效果
    @Test
    void testGetPage() {
        IPage page = new Page(1,5);
        iBookService.page(page);
    }


业务层总结


  1. 使用通用接口**(ISerivce)**快速开发Service
  2. 使用通用实现类**(ServiceImpl)**快速开发ServiceImpl
  3. 可以在通用接口基础上做功能重载或功能追加
  4. 注意重载时不要覆盖原始操作,避免原始提供的功能丢失


表现层开发


表现层消息一致性处理


2.png


设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议


@Data
public class R {
    private Boolean flag;
    private Object data;
    public R() {
    }
    public R(Boolean flag) {
        this.flag = flag;
    }
    public R(Boolean flag, Object data) {
        this.flag = flag;
        this.data = data;
    }
}


增加信息


post提交方式,前端传送的是json数据,需要使用@RequestBody


@PostMapping
    public R save(@RequestBody Book book) {
        return new R(bookService.save(book));
    }


删除信息


Delete提交方式,只需要提交一个参数id给后端,需要url有一个占位符。


//    删除操作
    @DeleteMapping("{id}")
    public R delete(@PathVariable Integer id) {
        return new R(bookService.removeById(id));
//        return bookService.removeById(id);
    }


使用Put提交数据,前端需要传入json格式给后端,


//    更新数据操作
    @PutMapping
    public R update(@RequestBody Book book) {
//        return bookService.update(book,null);
        return new R(bookService.updateById(book));
    }



不需要添加任何东西


查询所有信息


//    查询所有的信息
    @GetMapping
    public R getAll() {
        return new R(true,bookService.list());
//        return bookService.list();
    }


根据id进行查询


//    根据id进行查询
    @GetMapping("{id}")
    public R getById(@PathVariable Integer id) {
        return new R(true,bookService.getById(id));
//        return bookService.getById(id);
    }


分页查询时自己写的


public interface IBookService extends IService<Book> {
//    自己写的方法
    Book findById(Integer id);
//    自己写的分页方法
    IPage<Book> getPage(int currentPage , int pageSize);


@Service
public class BookServlceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;
    @Override
    public Book findById(Integer id) {
        return  bookDao.selectById(id);
    }
    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage page = new Page(currentPage,pageSize);
        bookDao.selectPage(page,null);
        return page;
    }
}


//    分页查询
    @GetMapping("{currentPage}/{pageSize}")
    public R getPage(@PathVariable int currentPage ,@PathVariable int pageSize) {
//        return bookService.getPage(currentPage,pageSize);
        return new R(true,bookService.getPage(currentPage,pageSize));
    }


需要注意的是,增删改返回结果都是布尔值,所以只需要使用一个参数的构造器,但是查询需要使用两个参数的构造器,这两个参数第一个参数都是true,第二个参数是获取的数据。


前端请求分为两种,一种是参数多的时候需要采用json格式,第二种是参数较少的时候采用url占位符书写。



相关文章
|
3天前
|
存储 缓存 负载均衡
后端开发中的性能优化策略
本文将探讨几种常见的后端性能优化策略,包括代码层面的优化、数据库查询优化、缓存机制的应用以及负载均衡的实现。通过这些方法,开发者可以显著提升系统的响应速度和处理能力,从而提供更好的用户体验。
22 4
|
10天前
|
XML druid Java
基于SpringBoot的SSMP整合
本文介绍了如何使用Spring Boot结合Lombok、MyBatisPlus等技术快速搭建一个简单的Web应用。从创建项目、数据库表设计到实体类、Mapper、Service、Controller各层的开发,最后通过PostMan测试接口功能,详细记录了每一步的实现过程。
基于SpringBoot的SSMP整合
|
9天前
|
存储 前端开发 Java
深入理解后端开发:从基础到高级
本文将带你走进后端开发的神秘世界,从基础概念到高级应用,一步步揭示后端开发的全貌。我们将通过代码示例,让你更好地理解和掌握后端开发的核心技能。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的信息和启示。
|
12天前
|
存储 缓存 监控
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####
|
8天前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
6天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
7天前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
23 1
|
8天前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
25 1
|
9天前
|
负载均衡 监控 API
后端开发中的微服务架构实践与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势和面临的挑战,并通过案例分析提出了相应的解决策略。微服务架构以其高度的可扩展性和灵活性,成为现代软件开发的重要趋势。然而,它同时也带来了服务间通信、数据一致性等问题。通过实际案例的剖析,本文旨在为开发者提供有效的微服务实施指导,以优化系统性能和用户体验。
|
12天前
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
本文将带你领略Node.js的魅力,从基础概念到实践应用,一步步深入理解并掌握Node.js在后端开发中的运用。我们将通过实例学习如何搭建一个基本的Web服务,探讨Node.js的事件驱动和非阻塞I/O模型,以及如何利用其强大的生态系统进行高效的后端开发。无论你是前端开发者还是后端新手,这篇文章都会为你打开一扇通往全栈开发的大门。