Spring Boot 3 遇到的一些变化、知识点

2023-05-16  本文已影响0人  狄仁杰666

前言

来啦老铁!

前一阵子公司举办了编程比赛,我与几位同事也参加了,项目与结果且不说,重在参与!重在学习到了什么!!!

我记录一下在这过程当中学习(踩坑)到的一些技术知识吧~

今天先来记录后端部分~

学习路径

  1. Spring Boot 3 配置 Mybatis + Mysql;
  2. 跨域配置:allowedOriginPatterns;
  3. domain 与 entity 、dao 概念的理解;
  4. 多环境配置与使用;
  5. mysql 插入数据后,返回插入数据的值;
  6. 10 位数 timestamp;

1. Spring Boot 3 配置 Mybatis + Mysql;

我们在三年前曾经涉足 Mybatis + Mysql 的使用,当时是 Spring Boot 2,使用起来也是相当简单,详情请见:

而随着时间的流逝,Spring Boot 已经来到了 Spring Boot 3,我们在本次编程使用了 Spring Boot 3,没想到在这方面遇到困难,正确的做法是:

1. 安装 druid datasource maven 依赖,如:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.9</version>
</dependency>
2. 使用 druid datasource;

在项目配置文件 application.yml 中增加如下配置

com.alibaba.druid.pool.DruidDataSource
druid datasource
3. 添加 Mybatis 配置类,以取代默认的 Mybatis 配置,代码如下:
package com.XXXX.cosmos.configuration;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisConfig {
    @Autowired
    private DataSourceProperties dataSourceProperties;


    @Bean()
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(dataSourceProperties.getUrl());
        dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
        dataSource.setUsername(dataSourceProperties.getUsername());
        dataSource.setPassword(dataSourceProperties.getPassword());

        return dataSource;

    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        return sqlSessionFactoryBean.getObject();
    }
}
4. 在程序入口类上添加注解,如:
package com.XXXX.cosmos;

import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication(exclude = MybatisAutoConfiguration.class)
@ComponentScan(basePackages = {"com.XXX"})
@MapperScan(basePackages = {"com.XXXX.cosmos.dao"})
public class CosmosBackendApplication {

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

核心是:@SpringBootApplication(exclude = MybatisAutoConfiguration.class),意思是取消 Mybatis 默认配置;

这几个动作非常关键,因为 Mybatis 目前还不支持 Spring Boot 3,因此需要使用自定义的配置取代默认的 Mybatis。

Spring Boot 连接数据库的其他文章还有:

需要请自取~

2. 跨域配置:allowedOriginPatterns;

在允许跨域方面,Spring Boot 3 也与之前稍有不同;

package com.XXXX.cosmos.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowedOriginPatterns("*")
                .maxAge(3600);
    }
}

以前,在 addCorsMappings 方法是这样的:

@Override
public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowedOrigins("*")
                .maxAge(3600);
    }

眼尖的同学应该会发现,allowedOrigins("") 改为 allowedOriginPatterns("") 了,这也是 Spring Boot 2 到 Spring Boot 3 的一个变化;

3. domain 与 entity 、dao 概念的理解;

(按我个人理解与习惯来说)

package com.XXXX.cosmos.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;

import java.io.Serial;
import java.io.Serializable;
import java.util.Date;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Rule implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private int rule_id;
    private String name;
    private String description;
    private String expression;
    private Integer active;
    private String created_by;
    private String updated_by;
    private Date created_when;
    private Date updated_when;
}
package com.XXXX.cosmos.dao;

import com.XXXX.cosmos.entity.Rule;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface RuleDao {
    @Select("select * from rule where active=1 order by rule_id desc")
    @Results(value = {
            @Result(property = "rule_id", column = "RULE_ID"),
            @Result(property = "name", column = "NAME"),
            @Result(property = "description", column = "DESCRIPTION"),
            @Result(property = "expression", column = "EXPRESSION"),
            @Result(property = "active", column = "ACTIVE"),
            @Result(property = "created_by", column = "CREATED_BY"),
            @Result(property = "updated_by", column = "UPDATED_BY"),
            @Result(property = "created_when", column = "CREATED_WHEN"),
            @Result(property = "updated_when", column = "UPDATED_WHEN")
    })
    List<Rule> getActiveRules();

    @Select("select * from rule where rule_id = #{rule_id}")
    @Results(value = {
            @Result(property = "rule_id", column = "RULE_ID"),
            @Result(property = "name", column = "NAME"),
            @Result(property = "description", column = "DESCRIPTION"),
            @Result(property = "expression", column = "EXPRESSION"),
            @Result(property = "active", column = "ACTIVE"),
            @Result(property = "created_by", column = "CREATED_BY"),
            @Result(property = "updated_by", column = "UPDATED_BY"),
            @Result(property = "created_when", column = "CREATED_WHEN"),
            @Result(property = "updated_when", column = "UPDATED_WHEN")
    })
    Rule getRuleById(@Param("rule_id") int rule_id);

    @Options(useGeneratedKeys = true, keyProperty = "rule.rule_id")
    @Insert("insert into rule (name,description,expression,created_by) values (#{rule.name},#{rule.description},#{rule.expression},#{rule.created_by});")
    void addNewRule(@Param("rule") Rule rule);

    @Insert("update rule set active=0,updated_by=#{updated_by},updated_when=CURRENT_TIMESTAMP where rule_id = #{rule_id};")
    void deleteRule(@Param("rule_id") int rule_id, @Param("updated_by") String updated_by);

    @Insert("update rule set name=#{rule.name},description=#{rule.description},expression=#{rule.expression},updated_by=#{rule.updated_by},updated_when=CURRENT_TIMESTAMP where rule_id = #{rule.rule_id};")
    void updateRule(@Param("rule") Rule rule);
}

4. 多环境配置与使用;

通常,我们会有不同的环境,如开发环境、集成环境、生产环境等,其资源通常是互相隔离的,那么我们又如何在不同环境下使用不同的资源呢?

这时候就要用到多环境配置了~

例如(注意文件后缀是 .yml 不是 .yaml):

多环境配置 生产环境 mysql 配置 dev 环境 mysql 配置

例如启动 dev 环境,那么我知道的有几种方式:

a. 直接启动项目:

mvn spring-boot:run -Dspring-boot.run.profiles=dev

这种方式一般是本地调试用吧~

b. 将项目达成 jar 包,启动:

// 打包
mvn package

// 启动
java -jar -Dspring.profiles.active=dev cosmos-backend-0.0.1-SNAPSHOT.jar

这种方式让我能清晰感受到,以前为什么开发老说要打包,为什么说要将包传到服务器,又为什么说又要重启服务;

注意:-Dspring.profiles.active=dev 要放在 jar 包前~

5. mysql 插入数据后,返回插入数据的值;

我们知道,insert 语句是没有返回值的,因此 insert 语句在 dao 层的接口,其返回类型为 void,那么,在某些场景下,我们需要知道插入的数据是什么,以便返回给前端,又该如何做呢?

Mybatis 提供了一个我认为很棒的方式,如:

@Options(useGeneratedKeys = true, keyProperty = "rule.rule_id")
    @Insert("insert into rule (name,description,expression,created_by) values (#{rule.name},#{rule.description},#{rule.expression},#{rule.created_by});")
    void addNewRule(@Param("rule") Rule rule);

这样,在数据插入完成后,我们就可以很方便地拿到新插入数据的 id 了:

返回插入数据的值

6. 10 位数 timestamp;

new Date().getTime() / 1000

有时候会遇到 10 位数时间戳,就这么简单~

目前想到的值得记录有这些,希望对大家有所帮助~

(我想,下一篇我们可以来记录一下前端部分,因为也挺久没有用前端了,前端框架也在不断进化)。

如果本文对您有帮助,麻烦点赞、关注!

谢谢!

上一篇下一篇

猜你喜欢

热点阅读