springboot重学日记

一、用Maven建时的相关导包
在 pom.xml 中添加 Spring Boot 相关的父级依赖, spring-boot-starter-parent 是一个特殊的starter,它提供
了项目相关的默认依赖,使用它之后 ,常用的包依赖可以省去 version 标签。

<parent>
        <artifactId>spring-boot-starter-web</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.4.4</version>
    </parent>
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lx</groupId>
    <artifactId>spring-Boot-01-hello</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- spring-boot-starter-parent是当前项目的父依赖
         spring-boot-starter-parent 继承 spring-boot-dependencies
         spring-boot-dependencies里面定义了很多组件版本号,我们引用对应依赖时,不需要写<version>标签-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.4</version>
    </parent>

    <!-- spring-boot-starter-web
         spring-boot-starter :它是springboot的场景启动器,针对不同场景定义了很多场景的启动器
         项目需要使用那些场景启动器,就直接依赖对应的启动器就可以了-->
    <!-- spring-boot-starter-web 构建Web项目,比如:tomcat,springmvc-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!-- 可以将当前项目打成一个jar包进行运行 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

关于注解@SpringBootApplication
用于标识,一个引导力,说明当前是一个Springboot项目,其构成的关键注解:

  • 1.@SpringBootConfiguration
    @Configuration 它属于spring中的一个注解,定义配置类,等价于配置文件
    @Component 添加到spring容器中,表示是一个组件
  • 2.@EnableAutoConfiguration
    @AutoConfigurationPackage 将引导类所在的包及子包下面所有的组件添加到 spring 容器中
    @Import({AutoConfigurationImportSelector.class})
    1.将所有组件以全类名的方式返回,并且添加到spring 容器中
    2.会给容器中导入非常多的自动配置类(…AutoConfiguration),省去手动编写配置然后注入到组件中
  • 3.@ComponentScan
    被该注解标识的类,会被spring容器进行管理

二、使用Spring Initializr 构建项目
在这里插入图片描述
resources 文件夹中目录结构:

  • static :保存所有的静态资文件, js css images
  • templates :保存所有的模板页面(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页
    面),可以使用模板引擎(freemarker、thymeleaf);
  • application.properties :Spring Boot应用的配置文件;可以修改一些默认设置;
    如修改默认端口 server.prot=8081

三、springboot核心配置
Spring Boot 使用一个全局配置文件,放置在 src/main/resources 目录或类路径的 /config 下;

  • application.properties
  • application.yml

配置文件的作用:修改 Spring Boot 自动配置的默认值;

#修改Servlet相关配置 server.servlet.xxx 
#端口名加/servlet加/hello才可请求
server.servlet.context-path=/servlet

yml 是 YAML(YAML Ain’t Markup Language)不是一个标记语言;
标记语言:以前的配置文件;大多都使用的是 xxxxx.xml文件;

<server>
    <port>8081</port> 
</server>

YAML:以数据为中心,配置数据的时候具有面向对象的特征;比 json、xml 等更适合做配置文件;

server:
  port: 8081
  • key: value 表示一对键值对(冒号后面必须要有空格)
  • 使用空格缩进表示层级关系
  • 左侧缩进的空格数目不重要,只要同一层级的元素左侧对齐即可
  • key 与 value 大小写敏感
  • @ConfigurationProperties 告诉SpringBoot将配置文件中对应属性的值,映射到这个组件类中,进行一一绑定
  • prefix = “emp”:配置文件中的前缀名,哪个前缀与下面的所有属性进行一一映射
  • @Component 必须将当前组件作为SpringBoot中的一个组件,才能使用容器提供的 @ConfigurationProperties功能,@Component 组件,等价于<bean id=“xx” class=“com.lx.xx”》

测试类中的注解
@RunWith(SpringRunner.class) : 在当前这个测试类,可以把所有组件都拿到

@Autowired : 其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property,实现自动装配

四、获取值
1、 @Value :

  • @Value("${xxx.name}"):将.yml或.properties中的xxx中的某个值赋给该注释下的变量,用美元符
  • @Value("#{10*2}"):计算后赋值,直接用#
  • @Value(“8000”):直接赋值

2、 @ConfigurationProperties(prefix = “xxx”)

  • 将 .yml或.properties直接一一对应赋值

五、操作使用.xml配置文件
SpringBoot提倡零配置, 即无xml配置,但是在实际开发中,可能有一些特殊要求必须使用 xml 配置;
这时我们可以通过 Spring 提供的 @ImportResource 来加载 xml 配置文件。
1、在service层建立一个方法

public class EmpService {
    public void add(){
        System.out.println("测试一下");
    }
}

2、建立一个.xml
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="empService" class="com.lx.springboot.service.EmpService">
    </bean>

</beans>

3、main方法上加注解@ImportResource(locations = {“xxx.xml”})

@ImportResource(locations = {"classpath:spring-01.xml"})
@SpringBootApplication
public class SpringBoot02ConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot02ConfigApplication.class, args);
    }

}

4、测试方法

    @Autowired
    ApplicationContext context;

    @Test
    public void testxml(){
        EmpService empService = context.getBean("empService",EmpService.class);
        System.out.println(empService);
        empService.add();
    }

六、自定义配置类向容器注入组件
第五点不提倡,但有些时候却不得不用,Spring Boot 推荐使用注解的方式向容器中注入组件
操作如下:

  • 使用 @Configuration 配置类,来表示对应Spring配置文件

  • 使用 @Bean 向容器中注入组件对象

  • @Configuration 等价于beans.xml

  • @Bean 类似bean标签
    //注册一个bean ,就相当于我们之前写的一个bean标签
    //这个方法的名字,就相当于bean标签中的id属性
    //这个方法的返回值,就相当于bean标签中的class属性

@Configuration
public class EmpConfig {
    @Bean
    public EmpService empService2(){
        System.out.println("再次测试一下,EmpService 组件注入成功");
        return new EmpService();
    }
}

测试:

    @Test
    public void testxml(){
        EmpService empService2 = context.getBean("empService2",EmpService.class);
        System.out.println(empService2);
    }

七、Profile 多环境支持
Profile 是 Spring 用来针对不同的环境要求,提供不同的配置支持, 全局 Profile 配置使用的文件名可以是
application-{profile}.properties / application-{profile}.yml ;
如: application-dev.properties / application-prod.properties

在这里插入图片描述
在yml中:

server:
  port: 8081  # 默认配置的端口号
spring:
  profiles: dev  # 激活哪个profile , 当前激活的是 dev 开发环境
---
server:
  port: 8082
spring:
  profiles: dev   # 指定属于哪个环境, dev 环境时使用

---
server:
  port: 8088
spring:
  profiles: prod  # 指定属于哪个环境, prod 环境时使用

八、日志
若出现java: 不兼容的类型: java.lang.String无法转换为java.util.function.Supplier<java.lang.String>
那就是idea导包导错了
正确的应该是:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Logger logger = LoggerFactory.getLogger(getClass());

九、模板引擎Thymeleaf

<!-- thymeleaf 模板启动器 --> 
<dependency> 
	<groupId>org.springframework.boot</groupId> 
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

通过模板加上响应的数据即可得到想要的输出,类似固定句式加上一个名称。
.html中导入,后面th: 将会有提示

<html lang="en" xmlns:th="http://www.thymeleaf.org">
@RequestMapping("/success")
    public String success(Map<String,Object> map){
        map.put("name","张三");
        //将会去找classpath:/templates/success.html
        return "success";
    }

不需要@ResponseBody,因为我们是加载页面,而不是将success这个字符串打印到页面中

<p th:text="${name}">这里的名字将会被覆盖</p>

通过th:text="${xx}"进行赋值

th:value="${xxx}"用于回显

th里面的拼接@{/provider/} + ${p.pid} + ‘?type=update’
几个标号相连或加上‘ ’(单引号)

基本语法:
在这里插入图片描述
在这里插入图片描述
User.java中有private String username;和 private Integer gender;

<table border="1px">
        <tr>
            <th>姓名</th>
            <th>性别</th>
        </tr>
        <tr th:each="user :${userList}">
            <td th:text="${user.username}">hehe</td>
            <td th:text="${user.gender == 1 ?'':''}">haha</td>
        </tr>
    </table>
@RequestMapping("/study")
    public String study(Map<String,Object> map){
        List<User> userList = new ArrayList<>();
        userList.add(new User("张三",2));
        userList.add(new User("李四",1));
        userList.add(new User("王五",2));
        map.put("userList",userList);
        return "study";
    }

十、SpringBoot 热部署

<dependency> 
	<groupId>org.springframework.boot</groupId> 
	<artifactId>spring-boot-devtools</artifactId>
</dependency>

开发环境下:

#开发环境下关闭thymeleaf模板缓存,thymeleaf默认是开启状态 
spring.thymeleaf.cache=false

这样idea中 Ctrl+F9 就可以去网页看了

十一、controller和config注解
在controller中,在方法上面加上@Controller,标识为控制层

  • @RequestMapping(value = “/providers”,method = RequestMethod.GET)
    通过get方法去找providers
  • @GetMapping("/providers")
    上面那个的化简版

在config中,加上@Configuration。创建自己的webMVC,再用@Bean实现注入,可做到和controller中加载页面的方法。
在这里插入图片描述
十二、拦截器

@Configuration
public class MySpringMvcConfigurer {
    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer(){
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("main/login");
                registry.addViewController("/index.html").setViewName("main/login");
                registry.addViewController("/main.html").setViewName("main/index");
            }

            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LoginHandlerInterceptor())
                        //拦截所有请求 /**
                        .addPathPatterns("/**")
                        // 排除不需要拦截的请求
                        .excludePathPatterns("/", "/index.html", "/login")
                        //SpringBoot2+中要排除静态资源路径, 因访问时不会加/static,所以配置如下
                        .excludePathPatterns("/css/**", "/img/**","/js/**");
            }
        };
}
public class LoginHandlerInterceptor implements HandlerInterceptor {
    //调用目标方法之前被拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if(loginUser != null){
            //已经登录过,放行
            return true;
        }
        //没有登录过
        request.setAttribute("msg","没有权限,请先登录!");
        //转到登录页面
        request.getRequestDispatcher("/index.html").forward(request,response);
        return false;
    }
}

十三、Thymeleaf与controller

@GetMapping("/logout")
    public String logout(HttpSession session){
        session.removeAttribute("loginUser");
        session.invalidate();
        return "redirect:/index.html";
    }
<a th:href="@{/logout}" href="../main/login.html">

十四、 Restful 架构

十五、三大组件Servlet/Filter/Listener
Spring提供以下Bean来注册三大组件:

  • ServletRegistrationBean :注册自定义Servlet
  • FilterRegistrationBean :注册自定义Filter
  • ServletListenerRegistrationBean :注册自定义Listener

在这里插入图片描述

@Configuration
public class MyServletConfig {
    @Bean
    public ServletRegistrationBean helloSevlet() {
        ServletRegistrationBean<HelloServlet> bean = new ServletRegistrationBean<>(new HelloServlet(), "/hello");
        bean.setLoadOnStartup(1);
        return bean;
    }

    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        //指定过滤器
        bean.setFilter(new MyFilter());
        //过滤哪些请求
        bean.setUrlPatterns(Arrays.asList("/hello"));
        return bean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener() {
        return new ServletListenerRegistrationBean(new MyListener());
    }
}
import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter初始化");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter 过滤完成");
        //放行
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("filter销毁");
    }
}


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("SpringBoot.Servlet应用启动");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("SpringBoot.Servlet应用销毁");
    }
}
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello servlet success");
    }
}

十六、整合jdbc
controller层用@RestController等价于
@Controller + @ResponseBody

yml文件配置连接

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver

java中写sql

@Autowired
    JdbcTemplate jdbcTemplate;

    @GetMapping("providers")
    public Map list(){
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from provider");
        Map<String, Object> map = maps.get(0);
        return map;
    }

十七、druid连接池
首先导入依赖

		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>

yml中进行相关配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    # 数据源其他配置, DataSourceProperties中没有相关属性,默认无法绑定
    initialSize: 8
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false

    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,logback
    maxPoolPreparedStatementPerConnectionSize: 25
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

自定义配置类, 将配置中属性与 DruidDataSource 属性绑定

import javax.sql.DataSource;

@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return new DruidDataSource();
    }
}

启动后结果和上一大点的jdbc的运行结果相同

配置Druid监控

@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return new DruidDataSource();
    }

    /**
     * 配置Druid监控
     * 1. 配置一个管理后台的Servlet
     * 2. 配置一个监控的filter
     */
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        Map<String,String> initParam = new HashMap<>();
        //访问的用户名密码
        initParam.put(StatViewServlet.PARAM_NAME_USERNAME, "root");
        initParam.put(StatViewServlet.PARAM_NAME_PASSWORD, "123");
        //允许访问的ip,不写默认所有ip访问
        initParam.put(StatViewServlet.PARAM_NAME_ALLOW, "");
        //禁止访问的ip
        initParam.put(StatViewServlet.PARAM_NAME_DENY, "192.168.10.1");
        bean.setInitParameters(initParam);
        return bean;
    }

    //2. 配置一个监控的filter
    @Bean
    public FilterRegistrationBean filter() {
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new WebStatFilter());
        //配置初始化参数
        Map<String, String> initParam = new HashMap<>();
        //排除请求
        initParam.put(WebStatFilter.PARAM_NAME_EXCLUSIONS, "*.js,*.css,/druid/*");
        //拦截所有请求
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }

}

就可以打开这个神奇的页面
在这里插入图片描述

十八、整合mybatis
@PathVariable 映射 URL 绑定的占位符
注解版:
mapper层中(一个接口,包含相关的数据操作请求):

@Mapper
public interface ProviderMapper {
    @Select("select * from provider where pid = #{pid}")
    Provider getProvierByPid(Integer pid);

    //useGeneratedKeys是否使用自增主键,keyProperty指定实体类中的哪一个属性封装主键值
    @Options(useGeneratedKeys = true, keyProperty = "pid")
    @Insert("insert into provider(providerName) values(#{providerName})")
    int addProvider(Provider provider);

    @Delete("delete from provider where pid=#{pid}")
    int deleteProviderByPid(Integer pid);

    @Update("update provider set providerName=#{providerName} where pid=#{pid}" )
    int updateProvider(Provider provider);
}

controller层中(对于SQL操作的java代码):

@RestController
public class ProviderController {

    @Autowired
    ProviderMapper providerMapper;

    @GetMapping("/provider/{pid}")
    public Provider getProvider(@PathVariable("pid")Integer pid){
        Provider provider = providerMapper.getProvierByPid(pid);
        return provider;
    }

    @GetMapping("/provider")
    public Provider addProvider(Provider provider){
        providerMapper.addProvider(provider);
        return provider;
    }
}

此时页面请求http://localhost:8080/provider/1即可查询到相应的JSON数据。
开启驼峰式(自定义MyBatis配置类, 替代mybatis配置文件):

@Configuration
public class MyBatisConfig {
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return new ConfigurationCustomizer(){
            @Override
            public void customize(org.apache.ibatis.session.Configuration configuration) {
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
    }
}

配置文件版:
在这里插入图片描述
BillMapper.java

public interface BillMapper {
    Bill getBillByBid(Integer bid);
    int insertBill(Bill bill);
}

BillMapper.xml

<?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.lx.springboot.mapper.BillMapper">

    <select id="getBillByBid" resultType="com.lx.springboot.entities.Bill">
        select * from bill where bid=#{bid};
    </select>

    <insert id="insertBill">
        insert into bill(bill_code, bill_name) values(#{billCode}, #{billName});
    </insert>
    
</mapper>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--mybatis核心配置文件--> 
    <settings> 
        <!--开启驼峰命名--> 
        <setting name="mapUnderscoreToCamelCase" value="true"/> 
    </settings>
</configuration>

yml中

mybatis:
  #核心配置文件路径
  config-location: classpath:mybatis/mybatis-config.xml
  #映射配置文件路径
  mapper-locations: classpath:mybatis/mapper/*.xml

controller

@RestController
public class BillController {

    @Autowired
    BillMapper billMapper;

    @GetMapping("/bill/{bid}")
    public Bill getbill(@PathVariable("bid")Integer bid){
        Bill bill = billMapper.getBillByBid(bid);
        return bill;
    }

    @GetMapping("/bill")
    public Bill addProvider(Bill bill){
        billMapper.insertBill(bill);
        return bill;
    }
}

十九、jpa
yml中连接好数据库

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/jpa?serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
    # 会根据就映射实体类自动创建或更新数据表
      ddl-auto: update
    # 控制台显示SQL
    show-sql: true

创建实体类, 并使用JPA注解进行配置映射关系

  • 类上使用 JPA注解 @Entity 标注,说明它是和数据表映射的类; @Table(name=“表名”) 指定对应映射的表名,
    省略默认表名就是类名。
  • @Id 标识主键, @GeneratedValue(strategy = GenerationType.IDENTITY) 标识自增长主键
  • @Column 标识字段

entity.User.java

package com.lx.springboot.entity;

import javax.persistence.*;

/**
  * jpa采用的是Orm(对象关系映射)模型
  */
@Entity
@Table(name = "tbl_user")
public class User {
    @Id //标识主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) //标识自增长主键
    private Integer id;

    @Column(name = "user_name",length = 5) //这是和数据表对应的一个列
    private String userName;

    @Column //省略默认列名就是属性名
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

dao.UserRepository.java

package com.lx.springboot.dao;

import com.lx.springboot.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

//自定义接口继承JpaRepository,就会crud及分页等基本功能
//指定的泛型<操作的实体类,主键的类型>
public interface UserRepository extends JpaRepository<User,Integer> {
}

controller层中

@RestController
public class UserController {

    @Autowired
    UserRepository userRepository;

    @GetMapping("/user/{id}")
    public User getUserById(@PathVariable("id") Integer id) {
        return userRepository.findById(id).get();
    }

    @GetMapping("/user")
    public User addUser(User user) {
        return userRepository.save(user);
    }
}

测试即可使用

二十、事务管理
启动类上添加
@EnableTransactionManagement//开启注解的事务管理
service层的方法上加上@Transactional开启事务管理
在yml中

# 指定引擎: 创建的表类型是Innodb,才可以进行对事物的回滚。
database-platform: org.hibernate.dialect.MySQL57Dialect

@Transactional(isolation = Isolation.DEFAULT)指定隔离级别
@Transactional(isolation = Isolation.DEFAULT)指定传播行为

相关报错:

  • Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method ‘POST’ not supported]
    在配置文件中加上:
    spring.mvc.hiddenmethod.filter.enabled=true

mybatis的配置文件中的SQL不要复制粘贴,容易出事
如果真出现了变绿色的恶心的情况,给表加个别名就可以了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值