当前位置: 首页 > article >正文

SpringBoot 基础学习

     对于SpringBoot的了解,在初学者的角度看来,它是一种工具,用于简化一个Spring项目的初始搭建和开发过程。

1 入门案例

   1.1 项目的创建

  有四种方法创建,可以通过idea快捷创建,Spring的官网创建,阿里云创建,以及手动创建。(这里以idea的方式来创建)

(1)文件 -> 新建项目

         输入项目名称,选择Spring initializr的生成器。项目类型选择Maven类型。 

(2)勾选所需要的依赖和配置

         选择好点击创建,成功创建一个Spring Boot的项目 

       项目创建好以后的结构和部分xml配置信息


1.2 Controller 的书写

package com.example.studaydemo_1.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.Controller;

@Controller
@RequestMapping("/Users")
public class UserController {

    @GetMapping
    public String getUser(){
        System.out.println("helloWord");
        return "Hello World";
    }
}

1.3 运行项目

项目成功运行界面 发现启动了Tomcat服务器并提供了端口8080以供访问

                                                      网页显示访问信息

 入门案例

package com.example.studaydemo_1.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/Users")
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("save running...");
        return "save running...";
    }

    @RequestMapping("/update")
    @ResponseBody
    public String update(){
        System.out.println("update running...");
        return "update running...";
    }

    @RequestMapping("/delete")
    @ResponseBody
    public String delete(){
        System.out.println("delete running...");
        return "delete running...";
    }

    @RequestMapping("/findAll")
    @ResponseBody
    public String findAll(){
        System.out.println("findAll running...");
        return "findAll running...";
    }

    @RequestMapping("/findById")
    @ResponseBody
    public String findById(){
        System.out.println("findById running...");
        return "findById running...";
    }

}

2 REST风格

表现形式状态转换 对于资源的描述形式

传统资源描述形式

http:/localhost/user/getById?id=1

http://localhost/user/saveUser

Rest风格描述形式

http://localhost/users/1

http://localhost/user

根据rest风格进行访问称作Restful

优点:

  1.  书写简洁
  2. 隐藏资源的访问形式

2.1 Rest风格转换 

  设定http请求动作(动词)

  设定请求参数(路径变量)

package com.example.studaydemo_1.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMethod;



@Controller
public class UserController_2 {

    @RequestMapping(value = "/users",method = RequestMethod.POST)
    @ResponseBody
    public String save(){
        System.out.println("save running...");
        return "save running...";
    }

    @RequestMapping(value = "/users",method = RequestMethod.PUT)
    @ResponseBody
    public String update(){
        System.out.println("update running...");
        return "update running...";
    }

    @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable String id){
        System.out.println("delete"+ id +" running...");
        return "delete running...";
    }

    @RequestMapping(value = "/users",method = RequestMethod.GET)
    @ResponseBody
    public String findAll(){
        System.out.println("findAll running...");
        return "findAll running...";
    }
}

 @RequestMapping 

类型: 方法注解

位置:SpringMVC控制器定义上方

作用:设置当前控制器方法的请求访问路径

范例:

 @RequestMapping(value = "/users",method = RequestMethod.POST)
    @ResponseBody
    public String save(){
        System.out.println("save running...");
        return "save running...";
    }

属性:

value:方法请求访问路径

method:http请求动作,标准动作(GET PUT DELETE)

@PathVariable

类型:形参注解

位置:SpringMVC形参定义的前面

作用:绑定路径参数和方法形参间的关系,要求路径参数名和形参名一一对应

范例:

  @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable String id){
        System.out.println("delete"+ id +" running...");
        return "delete running...";
    }


2.2 RESTful快速开发

  继续简化上述的内容,提取共同的部分来简化代码,以实现快速开发

package com.example.studaydemo_1.controller;


import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/user")
public class UserController {

    // @RequestMapping(method = RequestMethod.POST)
    @PostMapping
    public String save(){
        System.out.println("save running...");
        return "save running...";
    }

   // @RequestMapping(method = RequestMethod.PUT)
    @PutMapping
    public String update(){
        System.out.println("update running...");
        return "update running...";
    }

    // @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    @DeleteMapping("/id")
    public String delete(@PathVariable String id){
        System.out.println("delete"+ id +" running...");
        return "delete running...";
    }

    //@RequestMapping(method = RequestMethod.GET)
    @GetMapping
    public String findAll(){
        System.out.println("findAll running...");
        return "findAll running...";
    }
}

3 属性配置

     不同配置文件中相同配置按照加载优先级相互覆盖,不同文件中不同配置全部保留 

3.1 properpties配置

SpringBoot的默认配置文件,使用键值对配置对应属性

# 服务器配置
server.port = 80

# 修改banner
# 自动分析图片
spring.banner.location =  text.png

# 配置日志级别
# debug info(信息)[默认] error(错误) warn
logging.level.root = info

3.2 yml配置

配置文件的主流形式

# 服务器器配置
server:
  port: 8080

3.3 yaml配置

一种数据序列化格式 

优点:容易阅读 容易与脚本语言交互 以数据为核心 重数据轻格式

文件扩展名:.yml  .yaml

yaml语法规则

  • 大小写敏感
  • 属性缩进表示层级关系,每行结束使用冒号结束
  • 用层级左侧对齐,只允许使用空格
  • 属性值前面加空格(属性名和属性值之间使用冒号+空格作为分隔)
  • #表示注释
country : china
city: taiyuan
name: zhangsan
age: 18

user:
  name: zhangsan
  age: 18

class_id:
  - class1
  - class2
  - class3

class_2: [class1,class2,class3]

class_1:
  -
      name: 1
      number: 50
  -
      name: 2
      number: 60

class_3: [{name: 3, number: 70},{name: 4, number: 80},class3]

yaml配置文件属性 数组 对象的书写形式

 数据读取

package com.example.studaydemo_1.controller;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/users")
public class UserController_2 {

    // 读取yaml配置文件
    @Value("${country}")
    private String country;

    @Value("${user.age}")
    private String age;

    @Value("${class_id[0]}")
    private String class1;

    @Value("${class_1[0].number}")
    private String number;

    @GetMapping
   public String getInfo(){

       System.out.println("country===>"+country);
       System.out.println("number===>"+age);
       System.out.println("class===>"+class1);
       System.out.println("number===>"+number);

       return "INFO:" + country + ":" + age + ":" + class1;
   }


}

 1. 可以使用${属性名}的方式来调用数据

# 以使用${属性名}的方式来调用数据
baseDir: D:\test
tempDir: ${baseDir}\temp

# 字符中的转义字符可以正常使用
testDir: "${baseDir} \t1\t2\t3}"

2. 自动装配

// 自动装配对象  数据全部封装到env对象中
    @Autowired
    private Environment env;

    @GetMapping
   public String getInfo(){

       System.out.println("country===>"+env.getProperty("country"));
       String class_id = env.getProperty("class_id[0]");
       System.out.println("class_id===>"+class_id);

       return country;
   }

3. 使用类封装数据

    @Autowired
    private student student;

    @GetMapping
   public String getInfo(){
        System.out.println(student.toString());
        return student.toString();
   }
package com.example.studaydemo_1.controller;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

// 定义数据模型封装数据
// 声明为Spring管控的Bean
@Component
// 指定加载的数据
@ConfigurationProperties(prefix = "student")
public class student {

    private String name;
    private int age;
    private String class_id;
    private String address;

    public student() {
    }

    public student(String name, int age, String class_id, String address) {
        this.name = name;
        this.age = age;
        this.class_id = class_id;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getClass_id() {
        return class_id;
    }

    public void setClass_id(String class_id) {
        this.class_id = class_id;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", class_id='" + class_id + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

}

4 整合第三方技术

4.1 整合JUnit

对于项目测试的技术整合

 测试类

package com.studydemo_2;

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

@SpringBootTest
class StudyDemo2ApplicationTests {

    // 1. 注入要测试的对象
    @Autowired
    private BookDao bookDao;

    @Test
    void contextLoads() {
        // 2.执行要测试的方法
        bookDao.save();
    }

}

dao层

package com.studydemo_2.dao.impl;

import com.studydemo_2.dao.BookDao;
import org.springframework.stereotype.Repository;

@Repository
public class BookDaoImpl implements BookDao {

    @Override
    public void save() {
        System.out.println("BookDao is running");
    }
}
package com.studydemo_2.dao;

public interface BookDao {
    public void save();
}

@SpringBootTest

  •  类型:测试类注解
  • 位置:测试类定义的上方
  • 作用:设置JUnit加载的SpringBoot启动类
  • 范例:
@SpringBootTest
class StudyDemo2ApplicationTests {

    // 1. 注入要测试的对象
    @Autowired
    private BookDao bookDao;

    @Test
    void contextLoads() {
        // 2.执行要测试的方法
        bookDao.save();
    }
  • 属性:classes SpringBoot的启动类 启动文件 

4.2 整合MyBatis

数据库连接和配置 

数据库配置

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

数据接口

@Mapper
public interface BookDao {
    @Select("select * from book where name = #{name}")
    public Book findBookByName(String name);
}

测试类

@SpringBootTest
class StudyDemo3ApplicationTests {

	@Autowired
	private BookDao bookDao;

	@Test
	void contextLoads() {
		System.out.println(bookDao.findBookByName("百年孤独"));
	}

}

4.3 整合MyBatis-Plus

与MyBatis的区别:导入坐标不同 实现数据层的简化

国人开发 在idea界面找不到 可以使用aliyun镜像导入或者手动导入Plus坐标

<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
</dependency>

 数据库配置和分层一致 使用增删改查的时候实现BaseMapper<泛型>即可

@Mapper
public interface BookDao extends BaseMpper<Book>{

}

需要进行Mp配置 


4.4 整合Druid

数据库配置 需要手动导入坐标

<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.24</version>
</dependency>

配置方式

# Druid常规配置数据库
#spring:
#  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql:// localhost:3306/test
#    username: root
#    password: 367343
#    type: com.alibaba.druid.pool.DruidDataSource

# Druid连接池配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      test-on-borrow: true
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 367343
    driver-class-name: com.mysql.cj.jdbc.Driver

导入任何第三方库

  • 导入对应的starter
  • 进行相关配置和默认设置

5 整合案例

 完成一个基于SpringBoot的SSMP整合案例-图书管理系统 实现增删改查和分页展示的功能

5.1 实现目标 


5.2 具体实现

 5.2.1 配置文件

 正常创建项目,然后导入数据库驱动,MyBatis-Plus,Druid的坐标

server:
  port: 80

# 配置数据库相关信息
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      test-on-borrow: true
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 367343
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  global-config:
    db-config:
      id-type: auto # 主键生成策略
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启sql日志打印

 5.2.2 数据层与其测试类

//lombok
//一个Java类库,提供了一组注解,简化POJO实体类开发

@Data // 生成getter/setter/toString/equals/hashCode等方法 是Getter和Setter的合并
public class Book {
    private Integer id;
    private String name;
    private String author;
    private String description;
}

书籍实体类 使用@Data注解自动生成getter和setter方法以及相关构造器 

@Mapper
public interface BookDao extends BaseMapper<Book>{

}

使用快速开发的接口 

 5.2.3 服务层与其测试类

public interface BookService{

    boolean save(Book book);
    boolean update(Book book);
    boolean delete(Book book);

    Book getById(int id);
    List<Book> getAll();

常规服务层接口

public interface IBookService extends IService<Book> {

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

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

 快速开发服务层接口和扩展方法

// 快速开发方案
@Service
public class BookServiceImpl extends ServiceImpl<BookDao,Book> implements IBookService {

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

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize, Book book) {

        IPage<Book> page = new Page<>(currentPage,pageSize);
        QueryWrapper<Book> lqw = new QueryWrapper<Book>();

        if (StringUtils.isNotBlank(book.getName())) {
            lqw.like("name", book.getName());
        }
        if (StringUtils.isNotBlank(book.getAuthor())) {
            lqw.like("author", book.getAuthor());
        }
        if (StringUtils.isNotBlank(book.getDescription())) {
            lqw.like("description", book.getDescription());
        }

        bookDao.selectPage(page, lqw);
        return page;
    }

    // 可以继续追加其他业务方法 不要重载
}

快速开发接口实现类 

 5.2.4 控制层与其测试类

@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private IBookService bookService;

    @GetMapping
    public R getAll() {
        return new R(true,bookService.list());
    }

    @PostMapping
    public R save(@RequestBody Book book) {
//         R r = new R();
//         Boolean flag = bookService.save(book);
//         r.setFlag(flag);
//         r.setData(null);
//         return r;
        boolean flag = bookService.save(book);
        return new R(flag, flag ?"添加成功^_^":"添加失败-_-");
    }

    @PutMapping
    public R update(@RequestBody Book book) {
        return new R(bookService.updateById(book));
    }

    @DeleteMapping("/{id}")
    public R delete(@PathVariable String id) {
        return new R(bookService.removeById(id));
    }

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

//    @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);
//    }

    @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);
    }
}

对于增删改查操作的实现,以及向模型中注入分页后的数据 

前后端信息传递

// 模型类 用于前后端数据的统一 前后端数据协议
@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(String msg) {
        this.flag = false;
        this.msg = msg;
    }
}

异常处理类

@Configuration
public class MPConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        // MP定义拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 添加具体拦截器 分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

 5.2.5 视图层与效果

这里使用的是黑马直接提供好的前端代码,这里展示一下HYML页面和一些相关设计,由于数据库设计的不同,这里对于表格模型进行了修改。

<!DOCTYPE html>

<html>

<head>

    <!-- 页面meta -->

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title>基于SpringBoot整合SSM案例</title>

    <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">

    <!-- 引入样式 -->

    <link rel="stylesheet" href="../plugins/elementui/index.css">

    <link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css">

    <link rel="stylesheet" href="../css/style.css">

</head>

<body class="hold-transition">

<div id="app">

    <div class="content-header">

        <h1>图书管理</h1>

    </div>

    <div class="app-container">

        <div class="box">

            <div class="filter-container">
                <el-input placeholder="图书作者" v-model= pagination.author style="width: 200px;" class="filter-item"></el-input>
                <el-input placeholder="图书名称" v-model= pagination.name style="width: 200px;" class="filter-item"></el-input>
                <el-input placeholder="图书描述" v-model= pagination.description style="width: 200px;" class="filter-item"></el-input>
                <el-button @click="getAll()" class="dalfBut">查询</el-button>
                <el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
            </div>

            <el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>

                <el-table-column type="index" align="center" label="序号"></el-table-column>

                <el-table-column prop="name" label="书名" align="center"></el-table-column>

                <el-table-column prop="author" label="作者" align="center"></el-table-column>

                <el-table-column prop="description" label="描述" align="center"></el-table-column>

                <el-table-column label="操作" align="center">

                    <template slot-scope="scope">

                        <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>

                        <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>

                    </template>

                </el-table-column>

            </el-table>

            <!--分页组件-->
            <div class="pagination-container">

                <el-pagination
                        class="pagiantion"

                        @current-change="handleCurrentChange"

                        :current-page="pagination.currentPage"

                        :page-size="pagination.pageSize"

                        layout="total, prev, pager, next, jumper"

                        :total="pagination.total">

                </el-pagination>

            </div>

            <!-- 新增标签弹层 -->

            <div class="add-form">

                <el-dialog title="新增图书" :visible.sync="dialogFormVisible">

                    <el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px">

                        <el-row>

                            <el-col :span="12">

                                <el-form-item label="书名" prop="name">

                                    <el-input v-model="formData.name"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="12">

                                <el-form-item label="作者" prop="author">

                                    <el-input v-model="formData.author"/>

                                </el-form-item>

                            </el-col>

                        </el-row>


                        <el-row>

                            <el-col :span="24">

                                <el-form-item label="描述">

                                    <el-input v-model="formData.description" type="textarea"></el-input>

                                </el-form-item>

                            </el-col>

                        </el-row>

                    </el-form>

                    <div slot="footer" class="dialog-footer">

                        <el-button @click="cancel()">取消</el-button>

                        <el-button type="primary" @click="handleAdd()">确定</el-button>

                    </div>

                </el-dialog>

            </div>

            <!-- 编辑标签弹层 -->

            <div class="add-form">

                <el-dialog title="编辑检查项" :visible.sync="dialogFormVisible4Edit">

                    <el-form ref="dataEditForm" :model="formData" :rules="rules" label-position="right" label-width="100px">

                        <el-row>

                            <el-col :span="12">

                                <el-form-item label="书名" prop="name">

                                    <el-input v-model="formData.name"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="12">

                                <el-form-item label="作者" prop="author">

                                    <el-input v-model="formData.author"/>

                                </el-form-item>

                            </el-col>

                        </el-row>

                        <el-row>

                            <el-col :span="24">

                                <el-form-item label="描述">

                                    <el-input v-model="formData.description" type="textarea"></el-input>

                                </el-form-item>

                            </el-col>

                        </el-row>

                    </el-form>

                    <div slot="footer" class="dialog-footer">

                        <el-button @click="cancel()">取消</el-button>

                        <el-button type="primary" @click="handleEdit()">确定</el-button>

                    </div>

                </el-dialog>

            </div>

        </div>

    </div>

</div>

</body>

<!-- 引入组件库 -->

<script src="../js/vue.js"></script>

<script src="../plugins/elementui/index.js"></script>

<script type="text/javascript" src="../js/jquery.min.js"></script>

<script src="../js/axios-0.18.0.js"></script>

<script>
    var vue = new Vue({
        el: '#app',
        data:{
            dataList: [],//当前页要展示的列表数据
            dialogFormVisible: false,//添加表单是否可见
            dialogFormVisible4Edit:false,//编辑表单是否可见
            formData: {},//表单数据
            rules: {//校验规则
                type: [{ required: true, message: '图书类别为必填项', trigger: 'blur' }],
                name: [{ required: true, message: '图书名称为必填项', trigger: 'blur' }]
            },
            pagination: {//分页相关模型数据
                currentPage: 1,//当前页码
                pageSize:10,//每页显示的记录数
                total:0,//总记录数
                name:"",
                author:"",
                description:""
            }
        },

        //钩子函数,VUE对象初始化完成后自动执行
        created() {
            this.getAll();
        },

        methods: {
            //列表
            // getAll() {
            //     // 异步请求
            //     axios.get("/books").then(response => {
            //         this.dataList = response.data.data;
            //     });
            //
            // },

            //分页查询 在全部查询的基础上进行分页查询的编辑
            getAll() {

                param  = "?temp" + "&name="+this.pagination.name+"&author="+this.pagination.author+"&description="+this.pagination.description;

                // 异步请求
                axios.get("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize + param).then(response => {
                    this.pagination.pageSize = response.data.data.size;
                    this.pagination.currentPage = response.data.data.current;
                    this.pagination.total = response.data.data.total;
                    this.dataList = response.data.data.records;
                });

            },

            //切换页码
            handleCurrentChange(currentPage) {
                this.pagination.currentPage = currentPage;
                this.getAll();
            },

            //条件查询
            handleSearch() {
                axios.get("/books", {
                    params: {
                        page: this.pagination.currentPage,
                        size: this.pagination.pageSize,
                        type: this.formData.type,
                        name: this.formData.name
                    }
                }).then(response => {
                    this.dataList = response.data.data;
                });
            },

            //弹出添加窗口
            handleCreate() {
                this.dialogFormVisible = true;
                this.resetForm();
            },

            //重置表单
            resetForm() {
                this.formData = {};
            },

            //添加
            handleAdd () {
                axios.post("/books", this.formData).then(response => {
                    // 判断是否成功
                    if(response.data.flag){
                        // 1. 关闭弹层
                        this.dialogFormVisible = false;
                        this.$message.success("添加成功!");
                    }
                    else{
                        this.$message.error("添加失败!");
                    }
                }).finally(()=>{
                    // 2. 刷新数据
                    this.getAll();
                });
            },

            //取消
            cancel(){
                this.dialogFormVisible = false;
                this.dialogFormVisible4Edit = false;
                this.resetForm();
                // 提示
                this.$message({
                    type: 'info',
                    message: '取消成功'
                });
            },

            // 删除
            handleDelete(row) {
                this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.delete("/books/" + row.id).then(res => {
                        // 判断是否成功
                        if(res.data.flag){
                            this.$message({
                                type: 'success',
                                message: '删除成功!'
                            })
                              this.getAll();
                        }
                        else{
                            this.$message.error("同步失败! 自动刷新");
                        }
                    })
                }).finally(() => {
                    // 加载数据
                    this.getAll();
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                })
            },

            //弹出编辑窗口
            handleUpdate(row) {
                    axios.get("/books/"+row.id).then(response => {
                        if(response.data.flag && response.data.data != null) {
                            this.dialogFormVisible4Edit = true;
                            this.formData = response.data.data;
                        }else{
                            this.$message.error("同步失败! 自动刷新");
                        }
                    }).finally(()=>{
                        this.getAll();
                    });
                    if(response.data.flag){
                        // 1. 关闭弹层
                        this.dialogFormVisible4Edit = false;
                        this.dialogFormVisible4Edit = false;
                        this.$message.success("修改成功!");
                    }
                    else{
                        this.$message.error("修改失败!");
                    }
                },

            //修改
            handleEdit() {
                axios.put("/books", this.formData).then(response => {
                    // 判断是否成功
                    if(response.data.flag){
                        // 1. 关闭弹层
                        this.dialogFormVisible4Edit = false;
                        this.$message.success(res.data.msg);
                    }
                    else{
                        this.$message.error(res.data.msg);

                        /**
                         his.$message.success("修改成功!");
                         this.$message.error(res.data.msg);

                         这里出现了前后端都要传递数据的情况
                         可以全部交给前端处理 这里使用全部使用后端处理的方式

                        */
                    }
                }).finally(()=>{
                    // 2. 刷新数据
                    this.getAll();
                });

            },

    }
    })

</script>

</html>

 


6 常用注解

Spring Boot注解主要用于简化配置、自动装配组件和实现声明式服务。

文章位置:springboot常用注解大全(超详细, 30个)-CSDN博客 

注解分类注解名位置作用
核心注解@SpringBootApplicationSpring Boot 的主类上Spring Boot 最核心的注解,是 @Configuration、@EnableAutoConfiguration、@ComponentScan 三个注解的组合,用来开启 Spring Boot 的各项能力
自动配置相关@EnableAutoConfiguration类上允许 Spring Boot 自动配置注解,能根据当前类路径下的包或类来配置 Spring Bean。关键在于引入 AutoConfigurationImportSelector,其 selectImports 方法会从配置文件 META-INF/spring.factories 加载所有可能用到的自动配置类,去重并排除 exclude 和 excludeName 属性携带的类,过滤并返回满足 @Conditional 条件的自动配置类
配置相关@Configuration类上用于定义配置类,是 Bean 配置的信息源,相当于传统的 xml 配置文件,可加在主类上;若第三方库需用 xml 文件,可使用 @ImportResource 注解通过该类加载 xml 配置文件
组件扫描相关@ComponentScan类上让 Spring Boot 扫描到 Configuration 类并将其加入到程序上下文,默认会装配标识了 @Controller、@Service、@Repository、@Component 注解的类到 spring 容器中
数据访问组件@Repository类上用于标注数据访问组件(DAO 组件),可确保 DAO 或 repositories 提供异常转译,会被 ComponetScan 发现并配置,无需 XML 配置项
服务层组件@Service类上一般用于修饰 service 层的组件
控制层组件@RestController类上用于标注控制层组件,是 REST 风格的控制器,是 @Controller 和 @ResponseBody 的合集,将函数的返回值直接填入 HTTP 响应体中
响应体相关@ResponseBody方法上表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用,使用 @RequestMapping 后,加此注解可避免返回值被解析为跳转路径,直接返回数据(如 json)
通用组件@Component类上泛指组件,当组件不好归类时使用此注解标注
Bean 管理@Bean方法上相当于 XML 中的<bean>,产生一个 bean 并交给 spring 管理
自动装配@AutoWired类成员变量、方法及构造函数上byType 方式,把配置好的 Bean 拿来用,完成属性、方法的组装,自动装配工作,加(required=false)时,找不到 bean 不报错
自动装配辅助@Qualifier类成员变量、方法及构造函数上当有多个同一类型的 Bean 时,与 @Autowired 配合使用,用 @Qualifier ("name") 来指定具体 Bean
自动装配@Resource类成员变量、方法及构造函数上无括号内内容时默认 byName,与 @Autowired 类似
请求映射@RequestMapping类或方法上用来处理请求地址映射,提供路由信息,负责 URL 到 Controller 中具体函数的映射,用于类上时表示类中所有响应请求的方法以该地址作为父路径
请求参数@RequestParam方法的参数前面用于方法的参数,如 @RequestParam String a = request.getParameter ("a")
路径变量@PathVariable方法的参数上路径变量,参数与大括号里的名字要相同,如 @RequestMapping ("user/get/mac/{macAddress}"),可在方法参数中使用 @PathVariable String macAddress 获取路径变量
环境配置@Profiles类上Spring Profiles 提供一种隔离应用程序配置的方式,让这些配置只能在特定环境下生效,可标记 @Component 或 @Configuration 以限制加载时机
配置映射@ConfigurationProperties类上Spring Boot 使用此注解将自定义的 properties 文件映射到实体 bean 中,如将 config.properties 文件映射到类中

7 周末总结

     这一周学习了一下SpringBoot的一些基础知识内容,包括入门和综合SSMP案例的练习。主要是根据黑马程序员的课程逐步完善代码,由于之前并没有使用过Spring,并不能理解SprigBoot的便捷性。对于MVC分层的程序,根据需求逐步完成项目的过程中,学习了表格模型的增删改查操作。以及分页和相关显示和一些事务的处理,譬如删除元素后停留在没有元素的空页面。这些需要一些经验。另外对于前端的开发,整合案例中使用了axios的模型,这部分比较陌生,需要学习一下。然后,在基本了解了一个简单项目开发后,后续需要进行项目练习和mevan知识的复习。


学习时间 2025.1.9 - 2025.1.13


http://www.kler.cn/a/501898.html

相关文章:

  • 小米vela系统(基于开源nuttx内核)——如何使用信号量进行PV操作
  • 25年无人机行业资讯 | 1.1 - 1.5
  • 汽车电子相关的协议UDS、DOIP、CAN
  • 【Uniapp-Vue3】Prop校验与prop默认值用法及循环遍历数组对象
  • Maven核心插件之maven-resources-plugin
  • npm i 报错
  • 蓝桥杯_B组_省赛_2022(用作博主自己学习)
  • 人工智能:人形机器人的开发需求会创造哪些热门的就业岗位?
  • 基于深度学习的视觉检测小项目(十二) 使用线条边框和渐变颜色美化界面
  • JSON转EXCEL
  • 《零基础Go语言算法实战》【题目 2-27】goroutine 的使用问题
  • MPLS原理及配置
  • 【SpringBoot】用一个常见错误说一下@RequestParam属性
  • 解锁“搭子小程序”开发新机遇,助力企业数字化转型
  • 【SH】Xiaomi9刷Windows10系统研发记录 、手机刷Windows系统教程、小米9重装win10系统
  • HTML实战课堂之简单的拜年程序
  • 4G、5G移远模块SIM卡热插拔问题解决
  • 10.Linux 时间
  • 一文讲解常见API开发工具
  • 【机器学习:十、神经网络概述】
  • 1. 初识Scala
  • 一 rk3568 Android 11固件开发环境搭建 (docker)
  • NAT 代理服务器
  • 【芯片设计- RTL 数字逻辑设计入门 9.2 -- flip flop 与 寄存器的关系详细介绍】
  • 【LeetCode】力扣刷题热题100道(26-30题)附源码 轮转数组 乘积 矩阵 螺旋矩阵 旋转图像(C++)
  • 项目实战--网页五子棋(用户模块)(1)