Loading

SpringBoot实战教程

SpringBoot实战教程

参考笔记https://blog.csdn.net/lijiaming_99/article/details/119393342

Spring Boot 是 Spring 家族中的一个全新的框架,它用来简化 Spring 应用程序的创建和开发过程,也可以说 Spring Boot 能简化我们之前采用 SpringMVC + Spring +MyBatis 框架进行开发的过程。

在以往我们采用 SpringMVC + Spring +MyBatis框架进行开发的时候,搭建和整合三大框架,我们需要做很多工作,比如配置 web.xml,配置 Spring,配置 MyBatis,并将它们整合在 一起等,而 Spring Boot 框架对此开发过程进行了革命性的颠覆,完全抛弃了繁琐的 xml 配置过程,采用大量的默认配置简化我们的开发过程。

所以采用 Spring Boot 可以非常容易和快速地创建基于 Spring 框架的应用程序,它让编码变简单了,配置变简单了,部署变简单了,监控变简单了。正因为 Spring Boot 它化繁为简,让开发变得极其简单和快速,所以在业界备受关注。 Spring Boot 在国内的关注趋势图:http://t.cn/ROQLquP

1、入门案例

1.1、创建一个新的 Module,选择类型为 Spring Initializr

在这里插入图片描述

1.2、指定 GAV 及 pom 配置信息

在这里插入图片描述

1.3、选择 Spring Boot 版本及依赖

会根据选择的依赖自动添加起步依赖并进行自动配置
在这里插入图片描述

snapshot为快照不是稳定版本

release一定是正式版本

1.4、目录结构和pom.xml说明

image-20220501193713292

  • .mvn|mvnw|mvnw.cmd:使用脚本操作执行 maven 相关命令,国内使用较少,可删
  • .gitignore:使用版本控制工具 git 的时候,设置一些忽略提交的内容
  • static|templates:后面模板技术中存放文件的目录
  • application.properties:SpringBoot 的配置文件,很多集成的配置都可以在该文件中
  • 进行配置,例如:Spring、springMVC、Mybatis、Redis 等。目前是空的
  • Application.java:SpringBoot 程序执行的入口,执行该程序中的 main 方法,SpringBoot
    就启动了

对 POM.xml 文件进行解释

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <!--当前工程的GAV-->
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>demo</name>
    <description>demo</description>
    
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
                <!--springboot框架web项目起步依赖-->
<!--SpringBoot 框架 web 项目起步依赖,通过该依赖自动关联其它依赖,不需要我们一个一个去添加了
-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    <!--springboot框架测试起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
             <!--SpringBoot项目编译打包的插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

image-20220501194633309

@SpringBootApplication是核心注解,主要用于开启spring的自动配置

1.5、集成并验证Spring MVC

步骤明明和上面一毛一样

创建完成就是集成完毕

验证一下

注意:新创建的类一定要位于 Application 同级目录或者下级目录,否则 SpringBoot 加载不到。

image-20220501201403426

package com.example.demo.web;

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

/**
 * @Author: Kopoo
 * @Date: 2022/5/1 20:13
 */

@Controller
public class IndexController {
    @RequestMapping(value = "/springboot/say")
    public @ResponseBody String say() {
        return "hello";
    }
}

image-20220501202033903

image-20220501202120161

1.6、使用springboot的核心配置文件

a、在application.properties进行配置,项目中只能有一个

image-20220501203954749

image-20220501204035169

修改了端口号,上下文根

image-20220501204205808

image-20220501204152309

b、在application.yml进行配置

yaml一个道理,这个配置文件是有一定格式的,通过制表符来进行格式

image-20220501205233005

image-20220501205325500

c、两种配置文件都同时存在时

image-20220501210031695

image-20220501210116542

同时存在是以properties为标准的

1.7、多个生产环境下的配置文件设置

image-20220503165045478

开发-生成-准备-测试->dev-product-ready-test

由主核心配置文件设置选择哪个配置文件

image-20220503165128876

image-20220503165301266

image-20220503165316178

因此本项目的端口设置为8080 ,环境配置文件为开发环境

注意文件命名规范 一定要application-开头

1.8、多环境yml配置文件使用

yml配置类似,同样要application-开头,但是是以.yml为结尾

1.9、springboot自定义配置

image-20220503172655881

注意加个@Value(“${school.name}”)

image-20220503172619306

image-20220503172545919

1.10、自定义配置映射到对象

image-20220503174201721

package com.example.demo.config;

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

/**
 * @Author: Kopoo
 * @Date: 2022/5/3 17:34
 */
//将此类交给spring容器进行管理
@Component
@ConfigurationProperties(prefix = "school")
public class School {
    public String getName() {
        return name;
    }

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

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }

    private String name;
    private String website;
}

@Component来设定此类为配置类,然后进行依赖注入

@ConfigurationProperties使其读取properties的配置文件

package com.example.demo.web;

import com.example.demo.config.School;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Kopoo
 * @Date: 2022/5/1 20:13
 */

@Controller
public class IndexController {
    @Autowired
    private School school;



    @RequestMapping(value = "/say")
    @ResponseBody
    public String say() {
        return "hello"+school.getName();
    }

    @RequestMapping(value = "/mapvalue")
    public @ResponseBody Map<String, String> mapvalue() {
        Map<String, String> retMap = new HashMap<>();
        retMap.put("message", "sdhfiusdhifu");
        return retMap;
    }
}

通过@Autowired对school对象进行依赖注入

中文乱码的处理

image-20220629175819048

1.11、springboot集成jsp

1、新建一个文件夹webapp

2、设置识别webapp

image-20220629182659706

3、设置之后成为web资源文件夹

image-20220629182901895

4、pom.xml依赖配置

(1)在 pom.xml 文件中dependency标签种配置以下依赖项

        <!--引入 Spring Boot 内嵌的 Tomcat 对 JSP 的解析包,不加解析不了 jsp 页面-->
        <!--如果只是使用 JSP 页面,可以只添加该依赖-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

在 pom.xml 的 build 标签中要配置以下信息

(2)在 pom.xml 的 build 标签中要配置以下信息

image-20220629205537064

SpringBoot 要求 jsp 文件必须编译到指定的 META-INF/resources 目录下才能访问,否则
访问不到。其实官方已经更建议使用模板技术(后面会讲模板技术)

        <!--
            SpringBoot框架集成jsp,指定jsp文件编译的路径META-INF/resources
        -->
        <resources>
            <resource>
                <!--指定源文件路径-->
                <directory>src/main/webapp</directory>
                <!--指定编译的路径-->
                <targetPath>META-INF/resources</targetPath>
                <includes>
                <!--指定要把哪些文件编译进去,**表示 webapp 目录及子目录,*.*表示所有文件-->
                    <include>*.*</include>
                </includes>
            </resource>
        </resources>

5、在 application.properties 文件配置 Spring MVC 的视图展示为 jsp,这里相当于 Spring MVC 的配置

image-20220629210330736

6、 在src/main/java/com/example/demo/web 包下创建 IndexController 类,并编写代码

    @RequestMapping(value = "/heihei")
    public ModelAndView heihei() {
        ModelAndView mv = new ModelAndView();
        mv.addObject("message", "Hello");
        mv.setViewName("heihei");
        return mv;
    }

image-20220629212038751

注意jsp创建在webapp里面

image-20220629212441281

image-20220629212112309

2、Spring Boot 集成 MyBatis

1、新建一个springboot的module

2、然后在pom.xml里面添加依赖

ctrl+shift+/ 就是在xml文件里面添加注释

        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--mybatis 集成springboot框架的起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

image-20220701142220550

3、使用Mybatis提供的逆向工程生成实体bean,映射文件,DAO接口

方便生成实体bean和映射文件

首先这个逆向工程实际就是个代码生成器,先创建一个mapper和model文件夹

image-20220701154104195

在目录下新建xml文件,然后配置以下GeneratorMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>

    <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 -->
    <classPathEntry location="C:\Users\32611\.m2\repository\mysql\mysql-connector-java\5.1.48\mysql-connector-java-5.1.48.jar"/>

    <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
    <context id="tables" targetRuntime="MyBatis3">
        <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>


        <!-- 配置数据库连接信息 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="123456">
        </jdbcConnection>

        <!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定
        生成的 model 放在 idea 的哪个工程下面-->
        <javaModelGenerator targetPackage="com.example.demo.model"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>

        <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
        包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
        <sqlMapGenerator targetPackage="com.example.demo.mapper"
                         targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
        名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.example.demo.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 数据库表名及对应的 Java 模型类名 -->
        <table tableName="stuinfo" domainObjectName="Student"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>

image-20220701154344338

好神奇!!!

就全都有了,自动生成代码,生成6个方法

package com.example.demo.mapper;

import com.example.demo.model.Student;

public interface StudentMapper {
    int deleteByPrimaryKey(Integer stuid);

    int insert(Student record);

    int insertSelective(Student record);

    Student selectByPrimaryKey(Integer stuid);

    int updateByPrimaryKeySelective(Student record);

    int updateByPrimaryKey(Student record);
}

如果出现只有insert方法康康这里

https://blog.csdn.net/u013541707/article/details/106274909?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1-106274909-blog-117620757.pc_relevant_multi_platform_whitelistv1&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~default-1-106274909-blog-117620757.pc_relevant_multi_platform_whitelistv1&utm_relevant_index=1

image-20220701154559428

mapper.xml文件解释

prefix:在trim标签内sql语句加上前缀。

suffix: 在trim标签内sql语句加上后缀。

suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。

prefixOverrides: 指定去除多余的前缀内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjpowernode.springboot.mapper.StudentMapper">
  <resultMap id="BaseResultMap" type="com.bjpowernode.springboot.model.Student">
  <!--    id标签只能修改主键-->
  <!--    result除了主键以外的字段-->
  <!--    column数据库中的字段名称-->
  <!--    property映射对象的属性名称-->
  <!--    jdbcType列中数据库中字段的类型(可以省略不写)-->
    <!--  resultMap作用:
        1,当数据库中字段名称与实体类对象的属性名不一致时,可以进行转换
        2,当前查询的结果没有对象一个表的时候,可以自定义一个结果集-->
<!--    数据库表字段名称               实体对象属性名称-->
<!--    user name product_type      userName productType-->

<!--    如果数据库中字段名称由多个单词构成,通过MyBatis逆向工程生成的对象属也会按照驼峰命名法规则生成属性名称-->
<!--    其中:数据库中字段名称由多个单词构成的时候必须使用_下划线分隔-->

    <id column="stuid" jdbcType="INTEGER" property="stuid" />
    <result column="stuname" jdbcType="VARCHAR" property="stuname" />
    <result column="gender" jdbcType="CHAR" property="gender" />
    <result column="borndate" jdbcType="TIMESTAMP" property="borndate" />
  </resultMap>
    
    <!--  sql语句片段,将公共的部分抽取出来通过include标签引用sql语句片段-->
    
  <sql id="Base_Column_List">
    stuid, stuname, gender, borndate
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from stuinfo
    where stuid = #{stuid,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from stuinfo
    where stuid = #{stuid,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.example.demo.model.Student">
    insert into stuinfo (stuid, stuname, gender, 
      borndate)
    values (#{stuid,jdbcType=INTEGER}, #{stuname,jdbcType=VARCHAR}, #{gender,jdbcType=CHAR}, 
      #{borndate,jdbcType=TIMESTAMP})
  </insert>
    
      <!-- suffixOverrides 去除后缀多余的逗号-->
    
  <insert id="insertSelective" parameterType="com.example.demo.model.Student">
    insert into stuinfo
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="stuid != null">
        stuid,
      </if>
      <if test="stuname != null">
        stuname,
      </if>
      <if test="gender != null">
        gender,
      </if>
      <if test="borndate != null">
        borndate,
      </if>
    </trim>

    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="stuid != null">
        #{stuid,jdbcType=INTEGER},
      </if>
      <if test="stuname != null">
        #{stuname,jdbcType=VARCHAR},
      </if>
      <if test="gender != null">
        #{gender,jdbcType=CHAR},
      </if>
      <if test="borndate != null">
        #{borndate,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
    
    
          <!-- set 去除后缀多余的逗号-->
  <update id="updateByPrimaryKeySelective" parameterType="com.example.demo.model.Student">
    update stuinfo
    <set>
      <if test="stuname != null">
        stuname = #{stuname,jdbcType=VARCHAR},
      </if>
      <if test="gender != null">
        gender = #{gender,jdbcType=CHAR},
      </if>
      <if test="borndate != null">
        borndate = #{borndate,jdbcType=TIMESTAMP},
      </if>
    </set>
    where stuid = #{stuid,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.example.demo.model.Student">
    update stuinfo
    set stuname = #{stuname,jdbcType=VARCHAR},
      gender = #{gender,jdbcType=CHAR},
      borndate = #{borndate,jdbcType=TIMESTAMP}
    where stuid = #{stuid,jdbcType=INTEGER}
  </update>
</mapper>

只能进行单表操作

4、 在 web 包下创建 StudentController 并编写代码

image-20220703202133947

package com.example.demo.web;

import com.example.demo.model.Student;
import com.example.demo.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Author: Kopoo
 * @Date: 2022/7/3 20:01
 */
@Controller
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "/student")
    public @ResponseBody Object student(Integer id) {
        Student student = studentService.queryStudentById(id);
        return student;
    }
}

5、在service 包下创建 service 接口并编写代码

package com.example.demo.service;

import com.example.demo.model.Student;
import org.springframework.stereotype.Service;

/**
 * @Author: Kopoo
 * @Date: 2022/7/3 20:05
 */

public interface StudentService {

    /**
     * 根据学生id查询详情
     * @param id
     * @return
     */
    Student queryStudentById(Integer id);
}

6、在 service.impl 包下创建 service 接口并编写代码

package com.example.demo.service.impl;

import com.example.demo.mapper.StudentMapper;
import com.example.demo.model.Student;
import com.example.demo.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author: Kopoo
 * @Date: 2022/7/3 20:08
 */
@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public Student queryStudentById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }
}

spring注解@Service注解的使用

7、在 Mybatis 反向工程生成的 StudentMapper 接口上加一个 Mapper 注解

package com.example.demo.mapper;

import com.example.demo.model.Student;
import org.apache.ibatis.annotations.Mapper;

@Mapper//扫描dao接口到springboot容器
public interface StudentMapper {
    int deleteByPrimaryKey(Integer stuid);

    int insert(Student record);

    int insertSelective(Student record);

    Student selectByPrimaryKey(Integer stuid);

    int updateByPrimaryKeySelective(Student record);

    int updateByPrimaryKey(Student record);
}

8、别忘了在 Springboot 的核心配置文件 application.properties 中配置数据源

#设置数据库的连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456

9、在pom.xml文件中指定资源文件夹(这个前题是Studentmapper.xml文件在src/main/java路径下)

默认情况下,Mybatis 的 xml 映射文件不会编译到 target 的 class 目录下,所以我们需要在 pom.xml 文件中配置 resource

            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>

target依然显示不出来xml,就直接复制一个过去。。(离谱但是很有用)

image-20220703210728431

一般xml放在resource里面更好点,可以直接读取到

10、DAO 其它开发方式(替换7)

在 运 行 的 主 类 上 添 加 注 解 包 扫 描
@MapperScan(“com.abc.springboot.mapper”)
注释掉 StudentMapper 接口上的@Mapper 注解

在运行主类 Application 上加@MapperScan(“com.abc.springboot.mapper”)

在这里插入图片描述

11、将接口和映射文件分开

因为 SpringBoot 不能自动编译接口映射的 xml 文件,还需要手动在 pom 文件中指定,
所以有的公司直接将映射文件直接放到 resources 目录下
➢ 在 resources 目录下新建目录 mapper 存放映射文件,将 StudentMapper.xml 文件移
到 resources/mapper 目录下

在这里插入图片描述

在 application.properties 配置文件中指定映射文件的位置,这个配置只有接口和映
射文件不在同一个包的情况下,才需要指定

# 指定 Mybatis 映射文件的路径
mybatis.mapper-locations=classpath:mapper/*.xml

无须再配置 resource

关于Mapper映射文件存放的位置的写法有以下两种:
1,将Mapper接口和Mapper映射文件存放到src/main/java同一目录下,还需要在pom文件中手动指定资源文件夹路径resources
2·将Mapper接口和Mapper映射文件分开存放Mapper接口类存放到src/main/java目录下Mapper映射文件存放到resources(类路径)
在springboot核心配置文件中指定mapper映射文件存放到位置

3、Springboot的事务支持

Spring Boot 使用事务非常简单,底层依然采用的是 Spring 本身提供的事务管理

事务只跟sql语句有关,也就是dml语句,增删改查

➢ 在入口类中使用注解 @EnableTransactionManagement 开启事务支持
➢ 在访问数据库的 Service 方法上添加注解 @Transactional 即可
通过 SpringBoot +MyBatis 实现对数据库学生表的更新操作,在 service 层的方法中构建
异常,查看事务是否生效

该项目是在 章节2的基础上添加新增方法,在新增方法中进行案例的演示

1、在 StudentController 中添加更新学生的方法

    @RequestMapping(value = "/update")
    public @ResponseBody Object update(Integer id,String name) {
        int count = 0;
        try {
            Student student = new Student();
            student.setStuid(id);
            student.setStuname(name);
            count = studentService.updateStudentById(student);
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
        return "修改学生编号为"+id+"的姓名修改结果"+count;
    }

2、在 StudentService 接口中添加更新学生方法

    /**
     * 根据学生ID修改学生信息
     * @param student
     * @return
     */
    int updateStudentById(Student student);

3、在 StudentServiceImpl 接口实现类中对更新学生方法进 行实现,并构建一个异常,同时在该方法上加@Transactional 注解

    @Override
    @Transactional //添加此注解说明该方法添加的事务管理
    public int updateStudentById(Student student) {
        //修改成功
        int i = studentMapper.updateByPrimaryKeySelective(student);
        //失败
        int a =10/0;//在此构造一个除数为 0 的异常,测试事务是否起作用
        return i;
    }

4、Springboot下的SpringMVC

posted @ 2022-05-01 21:47  kopoo  阅读(1426)  评论(0编辑  收藏  举报