SpringBoot基础篇3(SpringBoot+Mybatis-plus案例)

news2025/1/11 0:30:55

环境搭建:配置起步依赖pom.xml和配置文件application.yml

1.创建模块时,勾选的依赖有springMVC和MySQL驱动

2.手动添加的依赖有:MyBatis-plus、Druid、lombok

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

3.设置数据源、端口、框架技术相关配置等

将数据库连接和数据源连接池配置在一起,注意密码是0开头的话要加""。
配置mybatis-plus的表前缀(取决于你自己的表名)、配置自增的方式为表中默认自增,设置为auto(mybatis-plus默认的是雪花算法)、再配置mybatis-plus的日志。

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: "0630"

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

一、实体类快速开发(lombok)(pojo或domain)

一个标准的bean应该有成员变量、构造器、get/set、toString等方法。
使用lombok组件,使用@Data注解直接标注一个bean为实体类。(该注解没有构造器方法,需要自己添加)

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

二、数据访问层(Dao或Mapper)

数据访问层只管理数据库的连接和操作。数据访问层和持久层有撒子区别,俺也不知道,有木有小伙伴回答一下。。。

1.Dao层

Dao层直接使用mybatis-plus提供的方法。Mapper接口继承BaseMapper<实体类>、并注解@Mapper

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

2.对mybatis-plus提供的访问数据库的方法进行测试

@SpringBootTest
public class BookDaoTestCase {
    @Autowired
    private BookDao bookDao;

    /**
     * 根据id查询
     */
    @Test
    void testGetById() {
        Book book = bookDao.selectById(1);
        System.out.println(book);
    }

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

    @Test
    void testUpdate() {
        Book book=new Book();
        book.setId(21);
        book.setType("测试数据abc");
        book.setName("测试数据abc");
        book.setDescription("测试数据abc");
        bookDao.updateById(book);
    }
    @Test
    void testDelete() {
        bookDao.deleteById(21);
    }

    @Test
    void testGetAll() {
        bookDao.selectList(null);
    }

    /**
     * 分页的两个基本数据:这是哪一页数据,这一页有多少条数据
     * 第一页数据,显示5条
     */
    @Test
    void testGetPage() {
        IPage page=new Page(2,5);
        //qw在什么地方都能加  加到这里就是连条件带分页查询
        bookDao.selectPage(page,null);
        System.out.println(page.getCurrent());
        System.out.println(page.getRecords());
    }

    @Test
    void testBy1() {
        QueryWrapper<Book> qw=new QueryWrapper<>();
        qw.like("name",2);
        bookDao.selectList(qw);
    }

    @Test
    void testBy2() {
        String name=null;
        LambdaQueryWrapper<Book> lqw=new LambdaQueryWrapper<>();
        //name不为空就连数据
        lqw.like(name!=null,Book::getName,name);
        bookDao.selectList(lqw);
    }
}

分页方法:

需要两个基本数据:第几页,一页显示几条数据。
分页方法返回的是IPage对象

条件查询:

QueryWrapper和LambdaQueryWrapper可以实现按条件查询。
拼接后的效果:
SELECT id,type,name,description FROM tbl_book WHERE (name LIKE ?)
qw对象可以放在任意地方,放在分页功能里就是带条件查询的分页功能。

三、业务层

业务层的方法名称关注的是业务名称,数据层方法名称关注的是数据库的操作。
调用数据层接口(自己写)或MyBatis-plus提供的接口快速开发。

1.service接口中

继承Iservice<Book>方法,就可以使用mybatis-plus提供的业务层方法。当然页可以自己定义。后两个方法是定义的两个重载的分页方法,一个是普通的分页方法,有两个参数(哪一页,一页有几条数据)。
一个是带条件查询的分页方法,浏览器将条件传到后端,后端再拼接sql查出来。
为什么要用Book接收?
浏览器发送过来的值刚好是Book的属性
请求参数是如何传到后台的? springMVC的知识
请求参数和形参同名,自动注入。或者直接模型类中的属性和请求参数相同,也会直接注入到模型类中(参数绑定 自动注入)

public interface IBookService extends IService<Book> {
    boolean saveBook(Book book);
    boolean modify(Book book);
    boolean delete(Integer id);

    IPage<Book> getPage(int currentPage,int pageSize);
    IPage<Book> getPage(int currentPage,int pageSize,Book book);
}

2.service的实现类

实现类中要extends ServiceImpl<BookDao, Book>
分页就把IPage对象return出去就行,IPage里有记录,大小,总数,当前页等信息。

@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;
    @Override
    public boolean saveBook(Book book) {
        return bookDao.insert(book)>0;
    }

    @Override
    public boolean modify(Book book) {
        return bookDao.updateById(book)>0;
    }

    @Override
    public boolean delete(Integer id) {
        return bookDao.deleteById(id)>0;
    }

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage page=new Page(currentPage,pageSize);
        bookDao.selectPage(page,null);
        return page;
    }

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize, Book book) {
        LambdaQueryWrapper<Book> lqw=new LambdaQueryWrapper<>();
        //不是空,就选择这个条件
        lqw.like(Strings.isNotEmpty(book.getType()),Book::getType,book.getType());
        lqw.like(Strings.isNotEmpty(book.getName()),Book::getName,book.getName());
        lqw.like(Strings.isNotEmpty(book.getDescription()),Book::getDescription,book.getDescription());
        IPage page=new Page(currentPage,pageSize);
        bookDao.selectPage(page,lqw);
        return page;
    }
}

测试分页功能:

@Test
    void testGetPage(){
        IPage<Book> page = new Page<Book>(2,5);
        bookService.page(page);
        System.out.println(page.getCurrent());//2
        System.out.println(page.getSize());//5
        System.out.println(page.getTotal());//总数
        System.out.println(page.getPages());//总共有几页
        System.out.println(page.getRecords());//记录
    }

四、表现层(表述层:页面到servlet)

基于Restful进行表现层接口开发;使用Postman测试表现层接口功能

  • 新增:POST
  • 删除:DELETE
  • 修改:PUT
  • 查询:GET

controller中写上测试方法,在postman中进行测试
接收参数总体分为两类:(服务器接收参数,浏览器发送请求参数)

  • 请求体操作(传的是json数据)。实体数据@RequestBody
  • 路径变量:@PathVariable
@RestController
@RequestMapping("/books")
public class BookController2 {
    @Autowired
    private IBookService bookService;

    /**
     * 查询全部 发送的是get请求
     * @return
     */
    @GetMapping
    public List<Book> getAll(){
        //通用工具类提供的方法
        return bookService.list();
    }

    /**
     * 新增一个book 发送的是post请求
     * 新增:异步提交发送,通过请求体传json数据过来。传json数据就不能跳转页面了
     * @param book
     * @return
     */
    @PostMapping
    public Boolean save(@RequestBody Book book){
        return bookService.save(book);
    }

    /**
     * 修改book  发送put
     * 修改:传json数据
     * @param book
     * @return
     */
    @PutMapping
    public Boolean update(@RequestBody Book book){
        return bookService.modify(book);
    }

    /**
     * 使用路径参数来传参
     * @PathVariable 从路径中获取的变量 传给形参
     * @param id
     * @return
     */
    @DeleteMapping("{id}")
    public Boolean delete(@PathVariable Integer id){
        return bookService.delete(id);
    }

    @GetMapping("{id}")
    public Book getById(@PathVariable Integer id){
        return bookService.getById(id);
    }

    /**
     * 几乎所有的查询都是get请求
     * @return
     */
    @GetMapping("{currentPage}/{pageSize}")
    public IPage<Book> getPage(@PathVariable int currentPage,@PathVariable int pageSize){
        return bookService.getPage(currentPage,pageSize);
    }
}

在postman中测试一下:发现从后台得到的数据有的是true,有的是json数据,有的是json数组,不方便前端开发。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因此需要有一个固定的格式:一个flag和一个data的形式,(后面根据情况携带了一个信息,后面再说)
在这里插入图片描述
将这些数据封装成上述类型的对象:

@Data
public class R {
    private Boolean flag;
    private Object data;
    private String msg;
    public R(){

    }
    public R(Boolean flag){
        this.flag=flag;
    }

    public R(Boolean flag, Object data) {
        this.flag = flag;
        this.data = data;
    }

    public R(Boolean flag, String msg) {
        this.flag = flag;
        this.msg = msg;
    }

    public R(String msg) {
        this.flag = false;
        this.msg = msg;
    }
}

将控制层的返回值都改成统一的格式R:

@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private IBookService bookService;

    /**
     * 查询全部 发送的是get请求
     * @return
     */
    @GetMapping
    public R getAll(){
        //通用工具类提供的方法
        return new R(true,bookService.list());
    }

    /**
     * 新增一个book 发送的是post请求
     * 新增:异步提交发送,通过请求体传json数据过来。传json数据就不能跳转页面了
     * @param book
     * @return
     */
    @PostMapping
    public R save(@RequestBody Book book){
        boolean flag=bookService.saveBook(book);
        return new R(flag,flag?"添加成功^_^":"添加失败-_-!");
    }

    /**
     * 修改book  发送put
     * 修改:传json数据
     * @param book
     * @return
     */
    @PutMapping
    public R update(@RequestBody Book book){
        return new R(bookService.modify(book));
    }

    /**
     * 使用路径参数来传参
     * @PathVariable 从路径中获取的变量 传给形参
     * @param id
     * @return
     */
    @DeleteMapping("{id}")
    public R delete(@PathVariable Integer id){
        return new R(bookService.delete(id));
    }

    @GetMapping("{id}")
    public R getById(@PathVariable Integer id){
        return new R(true,bookService.getById(id));
    }

    /**
     * 几乎所有的查询都是get请求
     * 对查询结果进行校验,如果当前页码值大于最大页码值,使用最大页码值作为当前页码值重新查询
     * 基于业务需求维护删除功能
     * @return
     */
//    @GetMapping("{currentPage}/{pageSize}")
//    public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){
//        IPage<Book> page=bookService.getPage(currentPage,pageSize);
//        //如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
//        if(currentPage>page.getPages()){
//            //不使用当前页查了,使用最大的页查
//            page=bookService.getPage((int)page.getPages(),pageSize);
//        }
//        return new R(true,page);
//    }

    /**
     * book里面有从浏览器发送的信息
     * 请求参数和形参同名,自动注入。或者直接模型类中的属性和请求参数相同,也会直接注入到模型类中(参数绑定 自动注入)
     * @param currentPage
     * @param pageSize
     * @param book
     * @return
     * 把条件查询当成分页的一部分值
     */
    @GetMapping("{currentPage}/{pageSize}")
    public R getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){
        IPage<Book> page=bookService.getPage(currentPage,pageSize,book);
        //如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
        if(currentPage>page.getPages()){
            //不使用当前页查了,使用最大的页查
            page=bookService.getPage((int)page.getPages(),pageSize,book);
        }
        return new R(true,page);
    }
}

在postman中测试一下:可以看到数据格式已经变了
在这里插入图片描述
扩展:前端发给后端的数据格式、协议就是json
后端到这里就结束了~~

五、前后端调用

单体项目中页面放置在resources/static目录下;
created钩子函数用于初始化页面时发起调用;
页面使用axios发送异步请求,获取数据后确认前后端是否联通。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/515038.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java笔记_20(多线程JUC)

一、多线程 1.1、多线程概述 进程 进程是程序的基本执行实体 线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。简单理解:应用软件中互相独立&#xff0c;可以同时运行的功能 什么是多线程? 有了多线程&#xf…

SpringBoot整合JPA

JPA、Hibernate、Spring Data JPA的关系 JPA是Java Persistence API的简称&#xff0c;中文名Java持久层API&#xff0c;是JDK 5.0注解或XML描述对象&#xff0d;关系表的映射关系&#xff0c;并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因&…

从零入门激光SLAM(九)——三维点云基础

大家好呀&#xff0c;我是一个SLAM方向的在读博士&#xff0c;深知SLAM学习过程一路走来的坎坷&#xff0c;也十分感谢各位大佬的优质文章和源码。随着知识的越来越多&#xff0c;越来越细&#xff0c;我准备整理一个自己的激光SLAM学习笔记专栏&#xff0c;从0带大家快速上手激…

新品发布全线添员,九号全力奔向“红海”深处?

5月10日&#xff0c;九号公司2023新品发布会声势达到顶峰。此次发布会的看点为九号电动2023产品线的更新&#xff0c;电动家族再添多员大将。 随着人们出行选择的多样化&#xff0c;国内短途出行工具发展迎来井喷期。在传统的电动两轮车市场上&#xff0c;雅迪、爱玛等品牌仍然…

基于java(springboot)和go-cqhttp实现QQ机器人

目录 yh-qqrobot机器人简介go-cqhttp搭建1.下载应用2.生成bat文件3. 初始化项目4. 配置5. 运行项目 yh-qqrobot搭建搭建后端1. 导入sql文件2. 配置文件3. 导入到idea 搭建前端 yh-qqrobot机器人简介 yh-qqrobot是一个基于若依框和go-cqhttp集成的系统&#xff0c;一开始我只是揣…

生成一个简版导游地图

目录 1 简版导游地图功能简介 2 注册并登录 3 设置景区&#xff08;商圈&#xff09;地图 3.1 新增景区 3.2 增加一个景点介绍 3.3 地图中增加一个景点 3.4 增加几个其他类型的点&#xff0c;如“美食”、“购物”、“停车” 4 申请审核 5 欣赏一下 1 简版导游地图功能…

【python 异常处理】零基础也能轻松掌握的学习路线与参考资料

Python 异常处理是编写高质量、功能稳定程序的关键之一&#xff0c;它可以帮助开发者优化程序的稳定性和可读性&#xff0c;更好地管理代码的错误和异常情况。 本文将介绍 Python 异常处理的学习路线、参考资料和优秀实践&#xff0c;以帮助 Python 开发者提高应对程序中错误和…

华为OD机试真题 Java 实现【微服务的集成测试】【2023Q1 100分】

一、题目描述 现在有n个容器服务&#xff0c;服务的启动可能有一定的依赖性&#xff08;有些服务启动没有依赖&#xff09;&#xff0c;其次服务自身启动加载会消耗一些时间。 给你一个 nxn 的二维矩阵 useTime&#xff0c;其中 useTime[i][i]10 表示服务 i 自身启动加载需要消…

十大排序算法

1.冒泡排序 步骤:从头元素开始比较每一对相邻元素&#xff0c;如果第1个比第2个大&#xff0c;就交换它们的位置&#xff0c;执行完一轮&#xff0c;最末尾的那个元素就是最大的元素 1.1冒泡算法 void BubbleSort(int arr[], size_t length) {for (int end length-1; end &…

.netcore3.1+jenkins+Docker

一.git安装 1.下载 https://github.com/git/git/releases/tag/v2.40.1 2.将本地的安装包上传到 linux 服务器上&#xff0c;我这里放在 /opt/git/ 目录下 3.解压压缩包&#xff0c;得到目录 git-2.40.1&#xff0c;位置在 /opt/git/git-2.40.1 tar -zxvf git-2.40.1.tar.gz 4.…

AIGC产业研究报告2023——视频生成篇

易观&#xff1a;今年以来&#xff0c;随着人工智能技术不断实现突破迭代&#xff0c;生成式AI的话题多次成为热门&#xff0c;而人工智能内容生成&#xff08;AIGC&#xff09;的产业发展、市场反应与相应监管要求也受到了广泛关注。为了更好地探寻其在各行业落地应用的可行性…

【1++的C++初阶】之类与对象

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的C初阶】 文章目录 一&#xff0c;面向对象与面向过程二&#xff0c;类2.1 类的定义2.2 类的访问限定符2.3 封装2.3.1 什么是封装2.3.2 封装的作用 2.4 类与对象 三&#xff0c;this指针3.1 什…

Docker 应用部署-MySQL

一、安装MySQL 1搜索mysql镜像 docker search mysql 2拉取mysql镜像 docker pull mysql:8.0.20 3创建容器 通过下面的命令&#xff0c;创建容器并设置端口映射、目录映射 #在用户名目录下创建mysql目录用于存储mysql数据信息 mkdir /home/mysql cd /home/mysql #创建docker容…

【数据结构】[LeetCode138. 复制带随机指针的链表]

一.问题描述 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值…

5。STM32裸机开发(1)

嵌入式软件开发学习过程记录&#xff0c;本部分结合本人的学习经验撰写&#xff0c;系统描述各类基础例程的程序撰写逻辑。构建裸机开发的思维&#xff0c;为RTOS做铺垫&#xff08;本部分基于库函数版实现&#xff09;&#xff0c;如有不足之处&#xff0c;敬请批评指正。 &a…

ssm框架之SpringMVC:域共享数据

本篇主要聊的是在springmvc中的共享域传递数据的使用。如果对共享域可能不了解的话&#xff0c;可以看下前面聊servlet的时候&#xff0c;对共享域的详细描述&#xff0c;以及其作用和方法。传送阵 至于如何构建SpringMVC的环境&#xff0c;以及如何构建一个项目&#xff0c;可…

一款基于 Python+flask 的态势感知系统(附完整源码)

一、开发 一个基于linux的态势感知系统&#xff0c;基于python和flask框架开发&#xff0c;项目文件目录如下&#xff1a; admin -核心算法 charts -图表生成 model -类 app.py -主文件 config.py -配置文件 install.py -安装文件 项目文件在文章结尾处~ 二、安装 1、…

矩池云搭建DeepLabV3Plus网络,预测无人机遥感语义分割数据集

先上效果图&#xff0c;效果是真不错呀&#xff01; 带大家复现这个过程 一、下载源码 代码下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1MkW7DOgNHD5h5sfXQ6L1HA 提取码&#xff1a;ynev 权重下载地址&#xff1a; 链接&#xff1a;https://pan.bai…

Java - 欢迎使用spring中的Base64Utils!

&#x1f335;如果项目技术栈中包含spring&#xff0c;同时又有Base64编码的需求&#xff0c;那么Base64Utils工具类将会是你的最好选择&#xff01;⤵️ 什么是Base64编码&#xff1f;⤵️ 基本转换针对URL的转换 &#xff08;/替换为-_&#xff09; Base64Utils公开的AP…

工业软件上云:有“数据之根”方能向阳生长

有人说&#xff0c;数字化时代&#xff0c;所有的事情都值得用云的方式重新做一遍。 深以为然。作为拥有全球工业门类最为齐全的国家&#xff0c;中国近年来正在从制造大国向制造强国迈进。随着《中国制造2025》国家战略的稳步推进&#xff0c;制造业的数字化转型和智能化升级…