从零开始springboot3+Mybatis实现增删改查

1,206 阅读7分钟

1. 项目搭建

  1. 新建项目

image.png 2. 配置

image.png

  1. 选择对应的配置

image.png

  1. 删除无用的文件

image.png

image.png

image.png

5.改名字,然后清空application.properties->application.yml

image.png

  1. 文件说明

image.png

image.png

image.png

6.设置编码

image.png

  1. 配置依赖架包

image.png 配置maven image.png

image.png

可以修改包名:(也可以不修改,避免出现问题,直接跳到第8步数据库配置)

image.png 如果启动出现报红,需要修改一下

image.png 改了包名,也需要跟着修改成对应的路径

image.png

若没用,采用一下方法

image.png 8. 数据库配置,修改端口号 如果密码以0开头,要加单引号,否则项目会自动去除

#数据库配置
server:
  port: 9090
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/spring+vue3?   useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

image.png

2. 创建第一个接口

  1. 新建一个controller的包

image.png 2. 在controller里面new 一个WebController

image.png

  1. 写一个测试代码如下:
package org.example.back_spring.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

//添加注解,RestController 对外提供数据接口的类 标注该类是一个接口,返回json数据,
@RestController
public class WebController {
    //    标注是get请求
    @GetMapping("/hello")
//    一个方法
    public String hello() {
        return "hello world";

    }
}

image.png

结果如下:

image.png

2.1 封装统一的类,返回给前端

包装类的作用:统一返回给后端的数据类型

  1. 新建软件包 image.png 2.新建result类 image.png

代码内容如下:

package org.example.back_spring.common;

//统一返回的包装类,统一后端返回的数据类型
public class Result {
    private String code;
    private String msg;
    private Object data;

    public static Result success() {
        Result result = new Result();
        result.setCode("200");
        result.setMsg("请求成功");
        return result;
    }

    public static Result success(Object data) {
        Result result = success();
        result.setData(data);
        return result;
    }
//    错误捕获

    public static Result error() {
        Result result = new Result();
        result.setCode("500");
        result.setMsg("系统错误");
        return result;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

使用方法

image.png

image.png

2.2 全局统一异常处理

  1. 新建全局的错误处理类

image.png

package org.example.back_spring.exception;

import org.example.back_spring.common.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

//统一的异常处理
@ControllerAdvice("org.example.back_spring.controller")//表示捕获 controller  里面的异常
public class GlobalExceptionHander {
    @ExceptionHandler(Exception.class)//Exception.class是所有异常的基类
    @ResponseBody//返回json串
    public Result error(Exception e) {
        e.printStackTrace();//打印错误
        return Result.error();
    }

}

image.png

2.3 自定义异常

主动抛出异常 image.png 新建CustomException类 image.png

image.png

image.png 思路讲解:

image.png

3. springboot3集成Mybatis

简介:

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  1. 项目创建时安装Mybatis依赖,然后在application.yml进行如下配置

 # 配置 mybatis实体和xml映射
mybatis:
   ## mapper映射文件位置,映射所有的xml,写sql在xml文件里面写,一般认为classpath对应的路径就是resources
  mapper-locations: classpath:mapper/*.xml
  #    type-aliases-package: com.gouggou.shardingtable.entity    # 实体类所在的位置
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   #用于控制台打印sql语句
    map-underscore-to-camel-case: true #将数据库里面的的下划线数据属性,转成驼峰的

2.在resource下创建mapper文件夹,并创建一个EmployeeMapper.xml文件 文件格式如下

<?xml version="1.0" encoding="UTF-8" ?>
<!--标准的 XML 文件声明,指定版本为 1.0 和字符编码为 UTF-8-->

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定文档类型为 MyBatis 的 Mapper 配置使用 MyBatis 3 的 DTD(文档类型定义)进行 XML 验证-->
<!--namespace 表示所映射的接口-->
<!--<mapper> 根元素:定义 SQL 映射的容器
namespace 属性(关键):
指定映射器接口的全限定名(包名+接口名)
值 com.example.mapper.EmployeeMapper 必须与对应的 Java 接口完全一致
作用:将 XML 文件与 Java 接口绑定-->
<mapper namespace="com.example.mapper.EmployeeMapper">

</mapper>

image.png

告诉springboot如何扫描mapper包,注册为容器里面的某一个Bean(bean 就是对象)

image.png

3.1 实现查询数据的总体逻辑

image.png

具体逻辑如下:

  1. 创建service

image.png

@Service注解是Spring框架中用于标识服务层组件的一种特殊注解。它继承自@Component注解,意味着所有@Service注解的类都会被Spring容器自动检测并注册为Bean,实现依赖注入。

  1. 新建实体类

image.png 查询数据

image.png

xml和mappery一一对应

image.png

结果如下:(数据请求流程)

image.png

整个的流程思路:

image.png

3.2 接口传参的方式,实现单个查询

  1. @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过

image.png

@PathVariable image.png

  1. 通过 @RequestParam ,可以使用 @RequestParam 从请求中提取查询参数、表单参数甚至是多个参数。

image.png image.png

  1. 对象参数查询

image.png

<select id="selectList" resultType="com.example.entity.Employee">
    SELECT * FROM employee
    <where>
        <if test="id != null">AND id = #{id}</if>
        <if test="name != null and name != ''">
             AND name LIKE CONCAT('%', #{name}, '%')
             </if>
        <if test="sex != null">AND sex = #{sex}</if>
        <if test="no != null">AND no = #{no}</if>
        <if test="age != null">AND age = #{age}</if>
        <if test="description != null and description != ''">
             AND description LIKE CONCAT('%', #{description}, '%')
             </if>
        <!-- 修正为 departmentId -->
        <if test="departmentId != null">AND department_id = #{departmentId}</if>
    

结果如下:

image.png

3.3 分页查询

  1. 引入插件,pagehelper

pom.xml

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.6</version>
    <exclusions>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </exclusion>
    </exclusions>
</dependency>

image.png

  1. 在service里面实现分页方法

public PageInfo<Employee> selectPage(Integer pageNum,Integer pageSize) {
    //通过插件实现分页的查询,不需要自己计算.插件会自动的添加分页查询的参数
    PageHelper.startPage(pageNum,pageSize);
    List<Employee> list=employeeMapper.selectAll();
    return  PageInfo.of(list);

}
  • 调用 PageHelper 的 startPage 方法时,会创建一个 Page 对象,将分页参数(如当前页码 pageNum 和每页显示条数 pageSize)设置到这个 Page 对象中。
  • • 这个 Page 对象会被存储到当前线程的 ThreadLocal 变量中,以确保分页参数的安全性和准确性。
  1. 在controller里实现
/**
 * 分页查询
 * pageNum:当前页
 * pageSize:每页的个数
 */

@GetMapping("/selectPage")
public Result selectPage(@RequestParam(defaultValue = "1") Integer pageNum,
                         @RequestParam(defaultValue = "10") Integer pageSize) {
    PageInfo<Employee> pageInfo = employeeService.selectPage(pageNum, pageSize);
    return Result.success(pageInfo);
}

image.png

结果如下:

image.png

4. 使用Mybatis实现增删改

  • get:对应的是查询操作
  • post:对应的是新增操作
  • put:对应的修改操作
  • delete:对应的是删除操作

4.1 新增数据

流程如下说明: image.png

代码如下: controller中,

/**
 * 新增数据
 */
@PostMapping("/add")
// @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)
public Result add(@RequestBody Employee employee) {
    employeeService.add(employee);
    return Result.success();
}

@RequestBody主要用来接收前端传递给后端的json字符串映射出来的java对象、或者数组

service中

//新增数据
public void add(Employee employee) {
    employeeMapper.insert(employee);
}

mapper中

//插入数据
void insert(Employee employee);

resource下的xml中

<insert id="insert" parameterType="com.example.entity.Employee">
    insert into `employee` (name, sex, no, age, description, department_id)
    values (#{name}, #{sex}, #{no}, #{age}, #{description}, #{departmentId})
</insert>

mybatis 里面写sql使用下划线,涉及到绑定java对象值,就写驼峰

image.png

发送请求注意点

image.png

4.2 更新数据

更新是一个put请求

思路如下:

image.png

代码如下: controller中,


/**
 * 更新数据
 */
@PutMapping("/update")
// @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)
public Result update(@RequestBody Employee employee) {
    employeeService.update(employee);
    return Result.success();
}

service中

//更新数据
void updateById(Employee employee);

mapper中

//插入数据
void insert(Employee employee);

resource下的xml中

<!--    更新数据-->
    <update id="updateById" parameterType="com.example.entity.Employee">
        update `employee`
        set name=#{name},
            sex=#{sex},
            no= #{no},
            age=#{age},
            description=#{description},
            department_id=#{departmentId}
        where id = #{id}
    </update>

4.3 删除数据

image.png

5. 处理跨域

报错如下:

image.png 在springboot 里面设置统一的跨域处理

新建一个类CorsConfig

package com.example.common;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

// 跨域配置
@Configuration
public class CorsConfig {  // 修复1: 类名不能有括号

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        // 修复2: 修正方法名拼写错误
        corsConfiguration.addAllowedOrigin("*");      // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*");      // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*");      // 3 设置访问源请求方法
        //corsConfiguration.setAllowCredentials(true);  // 允许携带凭证

        source.registerCorsConfiguration("/**", corsConfiguration);  // 修复3: 变量名大小写修正
        return new CorsFilter(source);  // 修复4: 移除错误的类型转换
    }
}

处理结果。请求成功

image.png

6. 实现登录功能

  1. 先配置字段 image.png 实体中也要同步添加

  2. 登录的总体逻辑如下 image.png

  3. 登录的主要代码如下:

  • controller中

@Resource
private  EmployeeService employeeService;

@PostMapping("/login")

public Result login(@RequestBody Employee  employee) {
  //  请求数据库的数据进行返回
  Employee dbEmployee=  employeeService.login(employee);
    return  Result.success(dbEmployee);
}
  • service中
//登录方法
public Employee login(Employee employee) {
    String username = employee.getUsername();
    //1. 先判断有没有账号
    Employee dbEmployee = employeeMapper.selectByUsername(username);
    if (dbEmployee == null) {//如果为null,sm说明没有查询刀片任何账号
        throw new CustomException("500", "账号不存在");
    }
    //2.数据库存在这个用户,再去校验密码
    String password = employee.getPassword();
    if(!dbEmployee.getPassword().equals(password)){//用户输入的密码跟数据账号的密码不匹配
        throw new CustomException("500", "账号或者密码错误");
    }
    //3. 账号和密码校验通过后,返回用户信息
    return dbEmployee;

}
  • mapper 中
@Select("select * from employee where username = #{username} ")
Employee selectByUsername(String username);

7. 实现注册功能

引入插件包hutool

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本

在项目的pom.xml的dependencies中加入以下内容:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.38</version>
</dependency>

注册整体逻辑 image.png

8.总结

在实现相关功能时,先做entity->contoller->service->mapper->mapper.xml