Springboot整合篇

2023-12-13 08:25:35

一、第三方整合

1.1整合JUnit

简单的junit使用小案例

1.导入测试对应的starter

2.测试类使用@SpringBootTest修饰

3.使用自动装配的形式添加要测试的对象

服务类

package com.yanyu.service;

public interface BookService {
    public void save();
}
package com.yanyu.service;

import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl implements BookService {
    @Override
    public void save() {
        System.out.println("book service is running ...");
    }
}

测试类

package com.yanyu;

import com.yanyu.service.BookService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SpringTest2ApplicationTests {

    //1.注入你要测试的对象
    //2.执行要测试的对象对应的方法
    @Autowired
    private BookService bookDao;

    @Test
    void testSave(){
        bookDao.save();
    }

    @Test
    void contextLoads() {
        System.out.println("test...");
    }

}

名称:@SpringBootTest
类型:测试类注解
位置:测试类定义上方
作用:设置JUnit加载的SpringBoot启动类,它的作用类似于 @RunWith(SpringRunner.class)@SpringBootTest
范例:

@SpringBootTest(classes = Springboot05JUnitApplication.class)
class Springboot07JUnitApplicationTests {

}

相关属性
◆classes:设置SpringBoot.启动类

1.2?整合MyBatis

核心配置:数据库连接相关信息(连什么、连谁、什么权限)

映射配置:SQL映射(XML/注解)?

①整合MyBatis需要在创建模块/工程的时候在SQL中勾选:

  • MySQL Driver
  • MyBatis Framework

②设置数据源参数

#2.配置相关信息
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_springboot
    username: root
    password: root

?③创建实体类

package com.yanyu.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;

}

④创建dao(定义数据层接口与映射配置)

数据库SQL映射需要添加@Mapper被容器识别到

package com.yanyu.dao;

import com.yanyu.domain.Book;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface BookDao {

    @Select("select * from book where id=#{id}")
    public Book getById(Integer id);

}

@mapper注解

@Mapper注解是MyBatis框架中的一个注解,用于标记接口为映射器接口。映射器接口主要用于定义SQL语句和实体类之间的映射关系。

CREATE TABLE `book` (
                        `id` int(11) NOT NULL AUTO_INCREMENT,
                        `type` varchar(255) DEFAULT NULL,
                        `name` varchar(255) DEFAULT NULL,
                        `description` text,
                        PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

?⑤测试

package com.yanyu;

import com.yanyu.dao.BookDao;
import com.yanyu.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringTest3ApplicationTests {
    @Autowired
    private BookDao bookDao;

    @Test
    public void testBookDao(){
        Book book = bookDao.getById(1);
        System.out.println(book);
    }
}

1.3整合Druid

①自行导入Druid的坐标

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

②配置数据源

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://122.9.47.93:3306/
    username: 
    password: 
    type: com.alibaba.druid.pool.DruidDataSource

测试:

同上

二、基于SpringBoot的SSMP整合案例

2.1创建模块

手动添加配置

<dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-launcher</artifactId>
            <scope>test</scope>
        </dependency>
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://122.9.47.93:3306/
    username: 
    password: 
    
    

2.2创建实体类

package com.yanyu.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;

}

2.3数据库开发

CREATE TABLE `book` (
                        `id` int(11) NOT NULL AUTO_INCREMENT,
                        `type` varchar(255) DEFAULT NULL,
                        `name` varchar(255) DEFAULT NULL,
                        `description` text,
                        PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


insert into book(type,name,description) values
    ('计算机理论','Spring实战 第五版','Spring入门经典教程,深入理解Spring原理技术内幕');

insert into book(type,name,description) values
    ('计算机理论','Spring实战 核心原理','Spring入门经典教程,深入理解Spring原理技术内幕');

insert into book(type,name,description) values
    ('计算机理论','Spring实战 设计模式','Spring入门经典教程,深入理解Spring原理技术内幕');

insert into book(type,name,description) values
    ('计算机理论','Spring实战 入门到开发','Spring入门经典教程,深入理解Spring原理技术内幕');

insert into book(type,name,description) values
    ('计算机理论','Java核心技术卷','Spring入门经典教程,深入理解Spring原理技术内幕');

2.4业务层开发

?定义业务层接口
package com.yanyu.service;

import com.yanyu.domain.Book;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * BookService接口,提供对书籍的增删改查操作。
 */
@Transactional
public interface BookService {

    /**
     * 保存书籍信息
     * @param book 要保存的书籍对象
     * @return 保存成功返回true,否则返回false
     */
    public boolean save(Book book);

    /**
     * 修改书籍信息
     * @param book 要修改的书籍对象
     * @return 修改成功返回true,否则返回false
     */
    public boolean update(Book book);

    /**
     * 根据ID删除书籍信息
     * @param id 要删除的书籍ID
     * @return 删除成功返回true,否则返回false
     */
    public boolean delete(Integer id);

    /**
     * 根据ID查询书籍信息
     * @param id 要查询的书籍ID
     * @return 查询到的书籍对象,如果没有找到则返回null
     */
    public Book getById(Integer id);

    /**
     * 查询所有书籍信息
     * @return 包含所有书籍对象的列表,如果没有书籍则返回空列表
     */
    public List<Book> getAll();
}
??@Transactional注解

?@Transactional注解是Spring框架中的一个注解,用于声明一个方法需要进行事务管理。当在一个类中使用了@Transactional注解的方法发生异常时,Spring会自动回滚事务,保证数据的一致性。

package com.yanyu.dao;


import com.yanyu.domain.Book;
import org.apache.ibatis.annotations.*;

import java.util.List;

// TODO 添加@Mapper
@Mapper
public interface BookDao {
    @Insert("insert into book (type,name,description) values(#{type},#{name},#{description})")
    public int save(Book book);

    @Update("update book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
    public int update(Book book);

    @Delete("delete from book where id = #{id}")
    public int delete(Integer id);

    @Select("select * from book where id = #{id}")
    public Book getById(Integer id);

    @Select("select * from book")
    public List<Book> getAll();
}
定义业务层实现类
package com.yanyu.service.impl;


import com.yanyu.controller.Code;
import com.yanyu.dao.BookDao;
import com.yanyu.domain.Book;
import com.yanyu.exception.BusinessException;
import com.yanyu.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    public boolean save(Book book) {
        return bookDao.save(book) > 0;
    }

    public boolean update(Book book) {
        return bookDao.update(book) > 0;
    }

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

    public Book getById(Integer id) {
        if(id == 1){
            throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
        }
        return bookDao.getById(id);
    }

    public List<Book> getAll() {
        return bookDao.getAll();
    }
}
业务层测试
package com.yanyu.service;

import com.yanyu.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class BookServiceTest {

    @Autowired
    private BookService bookService;

    @Test
    void testSave() {
        Book book = new Book(null, "游戏", "全职高手", "人生有梦,各自精彩");
        bookService.save(book);
    }

    @Test
    public void testUpdate() {
        Book book = new Book(1, "小说", "红楼梦", "世事如梦,人生如戏");
        bookService.update(book);
    }

    @Test
    public void testDelete() {
        bookService.delete(1);
    }

    @Test
    public void testGetById() {
        Book book = bookService.getById(2);
        System.out.println(book);
    }

    @Test
    public void testGetAll() {
        List<Book> all = bookService.getAll();
        System.out.println(all);
    }
}

2.5表现层开发

表现层数据封装

package com.yanyu.controller;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 结果类,用于封装返回给前端的数据
 */
@Data
@NoArgsConstructor
public class Result {
    private Object data; // 数据对象
    private Integer code; // 状态码
    private String msg; // 消息提示

    /**
     * 带参数的构造方法
     * @param code 状态码
     * @param data 数据对象
     */
    public Result(Integer code, Object data) {
        this.data = data;
        this.code = code;
    }

    /**
     * 带参数和消息提示的构造方法
     * @param code 状态码
     * @param data 数据对象
     * @param msg 消息提示
     */
    public Result(Integer code, Object data, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }

}
package com.yanyu.controller;

// 定义一个名为Code的类
public class Code {
    // 定义一些常量,表示不同的状态码
    public static final Integer SAVE_OK = 20011; // 保存成功的状态码
    public static final Integer DELETE_OK = 20021; // 删除成功的状态码
    public static final Integer UPDATE_OK = 20031; // 更新成功的状态码
    public static final Integer GET_OK = 20041; // 获取成功的状态码

    public static final Integer SAVE_ERR = 20010; // 保存失败的状态码
    public static final Integer DELETE_ERR = 20020; // 删除失败的状态码
    public static final Integer UPDATE_ERR = 20030; // 更新失败的状态码
    public static final Integer GET_ERR = 20040; // 获取失败的状态码

    public static final Integer SYSTEM_ERR = 50001; // 系统错误的状态码
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002; // 系统超时的错误状态码
    public static final Integer SYSTEM_UNKNOW_ERR = 59999; // 未知系统错误的状态码

    public static final Integer BUSINESS_ERR = 60002; // 业务错误的状态码
}

2.6异常处理

异常种类

异常解决方案?

业务异常(BusinessException
  • 发送对应消息传递给用户,提醒规范操作
  • 大家常见的就是提示用户名已存在或密码格式不正确等
系统异常(SystemException
  • 发送固定消息传递给用户,安抚用户
    • 系统繁忙,请稍后再试
    • 系统正在维护升级,请稍后再试
    • 系统出问题,请联系系统管理员等
  • 发送特定消息给运维人员,提醒维护
    • 可以发送短信、邮箱或者是公司内部通信软件
  • 记录日志
    • 发消息和记录日志对用户来说是不可见的,属于后台程序

其他异常(Exception

  • 发送固定消息传递给用户,安抚用户
  • 发送特定消息给编程人员,提醒维护(纳入预期范围内)
    • 一般是程序没有考虑全,比如未做非空校验等
  • 记录日志

异常解决方案的具体实现?

步骤1:自定义异常类
package com.yanyu.exception;

import lombok.Getter;
import lombok.Setter;

/**
 * BusinessException类,继承自RuntimeException
 */
@Getter
@Setter
public class BusinessException extends RuntimeException {
    private Integer code;

    /**
     * 构造方法1:接收错误码和错误信息
     * @param code 错误码
     * @param message 错误信息
     */
    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    /**
     * 构造方法2:接收错误码、错误信息和异常原因
     * @param code 错误码
     * @param message 错误信息
     * @param cause 异常原因
     */
    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
}
package com.yanyu.exception;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class SystemException extends RuntimeException{
    private Integer code;

    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public SystemException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

}
步骤2:将其他异常包成自定义异常
步骤3:处理器类中处理自定义异常
package com.yanyu.controller;

import com.yanyu.exception.BusinessException;
import com.yanyu.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice // 使用@RestControllerAdvice注解,表示这是一个全局异常处理类
public class ProjectExceptionAdvice {
    // 处理SystemException异常
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        // 记录日志
        // 发送消息给运维
        // 发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    // 处理BusinessException异常
    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    // 处理其他异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        // 记录日志
        // 发送消息给运维
        // 发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}
@RestControllerAdvice注解?

@RestControllerAdvice注解是Spring框架中的一个注解,用于创建一个全局的异常处理类。这个类可以处理所有的控制器抛出的异常,而不需要为每个控制器单独定义一个异常处理器。

@RestControllerAdvice注解相当于以下几个注解的组合:

  1. @ControllerAdvice注解:用于定义一个全局的异常处理类。
  2. @ExceptionHandler注解:用于指定处理方法,可以处理控制器抛出的异常。
  3. @ResponseBody注解:用于将方法返回值转换为JSON格式响应体。
  4. @ResponseStatus注解:用于设置HTTP状态码。
?@ExceptionHandler注解

@ExceptionHandler注解用于指定处理方法,可以处理控制器抛出的异常。它通常与@ControllerAdvice注解一起使用,以定义全局的异常处理类。

@ControllerAdvice注解

????????@ControllerAdvice是一个注解,用于定义一个全局的异常处理器。它可以用于捕获控制器中抛出的异常,并统一处理这些异常。@ControllerAdvice注解可以用于类级别或方法级别。

????????在类级别上使用@ControllerAdvice注解,可以让它成为一个全局的异常处理器,可以处理所有控制器中抛出的异常。在方法级别上使用@ControllerAdvice注解,可以将它应用于特定的控制器方法,只处理该方法抛出的异常。

????????@ControllerAdvice注解可以定义一个或多个@ExceptionHandler方法,用于处理特定类型的异常。@ExceptionHandler方法可以接收一个异常对象作为参数,并返回一个包含错误信息的ModelAndView对象或一个响应对象。

?2.7前后端协议联调

前后端分离结构设计中页面归属前端服务器

单体工程中页面放置在resources目录下的static目录中(建议执行clean)

?

文章来源:https://blog.csdn.net/qq_62377885/article/details/134940982
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。