前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用NestJs、GraphQL、TypeORM搭建后端服务

使用NestJs、GraphQL、TypeORM搭建后端服务

原创
作者头像
路过的那只狗
发布于 2020-11-14 08:01:53
发布于 2020-11-14 08:01:53
6.9K0
举报
文章被收录于专栏:随便写写随便写写

本文介绍今年上半年使用的的一些技术,做一些个人的学习记录,温故而知新。主要包含了NestjsTypeGraphQLTypeORM相关的知识。本文示例代码以提交到github,可以在这里查看

一、介绍

1.1、什么是NestJs?

NestJs是一个后端框架,类似于ExpressKoa。不同的是它内置并完全支持TypeScript,使用渐进式JavaScript,结合了OOP(面向对象编程),FP(函数式编程)和 FRP(函数式响应编程)的元素。如果你使用过最新的AngularJs的话,那么你对可能会很容易上手,它最主要的特点就是,Module·Service·Controller·Provider,以及大量的使用装饰器

代码语言:txt
AI代码解释
复制
// 使用 @Module 定义一个 Module(模块)
import { PokemonResolver } from './pokemon.resolver'
import { Module } from '@nestjs/common'
import { PokemonService } from './pokemon.service'
import { TypeOrmModule } from '@nestjs/typeorm'
import { PokemonEntity } from './pokemon.entity'

@Module({
    imports: [ TypeOrmModule.forFeature([ PokemonEntity ]) ],
    providers: [ PokemonResolver, PokemonService ]
})
export class PokemonModule {}
1.2、什么是TypeGraphQL?

TypeGraphQL是基于GraphQL重写的TypeScript版本,GraphQL的全称是:Graph Query Langue 图形化查询语言,是一个可由调用端定义API返回数据结构语言。在我们过去常用的RestFul API中,我们可能在不同的业务中需要调用同一个接口,但是各自所需的数据有不同的情况下,服务端为了同时满足两个需求则提供了更多的字段,这样导致了一个两个业务请求到的数据都包含了自己不需要的字段,造成了不必要的资源浪费。GraphQL则是解决了这个问题,它可以让各个业务都可以通过一个接口拿到自己刚刚好的数据,而不用返回一个多余的字段。

代码语言:txt
AI代码解释
复制
// 使用 @ObjectType 定义一个GraphQL数据结构 
import { Field, ObjectType} from 'type-graphql'

@ObjectType()
export class CreatePokemonDto {
    @Field() readonly id?: string
    @Field() readonly name: string
    @Field() readonly type: string
    @Field() readonly pokedex: number
}

示例一:查询一个字段

示例二:查询两个字段

1.3、什么是TypeORM?

后端开发同学应该都知道ORM的全称是对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。 本质上就是将数据从一种形式转换到另外一种形式。而TypeORM则是使用TypeScript编写的JavaScript版本的ORM库。通过他我们可以定义一些Entity(实体),每个实体的数据字段,每个字段包含了数据类型,甚至是数据关系(一对多、多对多、多对一)。这些实体将映射到真实数据库中,创建真正的数据表。而数据字段和关系也就生成对应的数据库表字段以及表字段与表字段的关系。目前TypeORM已经支持mysqlpostgresmariadbsqlitecordovanativescriptoraclemssqlmongodbsqljsreact-native共计11种类型的数据库引擎的连接。

代码语言:txt
AI代码解释
复制
// 使用 @Entity 声明一个实体
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

@Entity('pokemon')
export class PokemonEntity {
    @PrimaryGeneratedColumn('uuid')
    id: string

    @Column('varchar', { length: 500, unique: true })
    name: string

    @Column('varchar', { length: 500 })
    type: string

    @Column('numeric')
    pokedex: number
}

二、项目初始化及项目初始内容解析

2.1、项目初始化

NestJs提供了CLI,可以直接使用他们的CLI工具创建项目。首先我们需要先安装CLI工具,然后使用 nest new project-name初始化项目。

代码语言:txt
AI代码解释
复制
$ npm i -g @nestjs/cli
$ nest new project-name

此处我们创建一个nest-pokemon项目,然后我们进入项目根目录使用yarn start:dev启动服务,打开http://localhost:3000 即可看到 hello word!

2.2、初始内容解析

项目内容如下所示:

代码语言:txt
AI代码解释
复制
src
├── app.controller.ts
├── app.module.ts
├── app.service.ts
└── main.ts

其中main.ts是入口文件,内容包含一个异步函数,它负责引导启动整个App。

代码语言:txt
AI代码解释
复制
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

app.module.ts是App的整个主体部分,所有的服务都从这里开始,NestJs的核心思想是万物皆Module,所以我们可以到AppModule由一个@Module装饰器进行修饰,@Module的参数是一个对象,包含三个属性:imports、controller、providers。他们分别的作用是:

  • imports:模块,用于添加App的子模块,可能是用户模块,可能是商品模块,也可能是支付模块。这里的类由@Module()装饰。
  • controller:控制器,里面用于路由控制,这里的类由@Controller()装饰。
  • providers:提供者,这里的主要功能是服务者的角色,这样的文件职责划分类似与MVC,这里的类由@Injectable()进行装饰。可以理解为依赖注入。 他们的值都为一个数组,方便添加多个模块功能。
代码语言:txt
AI代码解释
复制
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

三、添加TypeORM到项目,选择MySQL作为数据库

3.1、添加依赖,启动mysql服务

我们在src目录下创建一个modules文件夹,里面将会用来放置模块,这些模块将会被引入app.module.ts并且添加到imports字段里。再到src/modules下添加一个文件夹pokemon文件夹用于放置pokemon 模块。我们先来将TypeORM相关依赖添加到项目,依赖包括三部分,分别是NestJs支持TypeORM的依赖包@nestjs/typeormTypeORM本身typeorm,数据库支持MySQL

代码语言:txt
AI代码解释
复制
$ npm i @nestjs/typeorm --save
$ npm i typeorm --save
$ npm i mysql --save

除此之外,我们还需要开启MySQL服务,可以是本地的也是线上的。确保MySQL服务在线后,我们来改造代码。

3.2、改造app.module.ts

@nestjs/typeorm中引入NestJsTypeORM连接模块*TypeOrmModule,然后传入一个Object作为与数据库链接的 Connection,创建一个新的连接。此前有提到,在NestJs里面万物皆是Module,所以这里的TypeORM也是作为一个子Module添加到整个服务中。所以它的位置应该在imports这里

代码语言:txt
AI代码解释
复制
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "123456789",
      "database": "nest3",
      "synchronize": true,
      "logging": false,
      "entities": []
    })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

其中个字段分别的意义是:

  • type:数据库类型
  • host:数据库连接host
  • port:数据库连接port
  • username:数据库管理员名称
  • password:数据库管理员密码
  • database:数据库名称
  • synchronize:指示是否在每次应用程序启动时自动创建数据库架构,不可在开发环境使用。
  • logging:日志
  • entities:要加载并用于此连接的实体。接受要加载的实体类和目录路,值为一个数组。

现在保存文件,我们将会得到一个错误,因为TypeORM生成数据库表的时候至少需要一个实体Entity文件。现在我们来src/modules/pokemon目录下创建实体文件pokemon.entity.tsTypeORM的基本方法了解:

  • Entity:实体装饰器,将一个类声明为一个实体。传入一个字符串作为参数,这个名称将用于生成表的名称,使用方式@Entity('table_name')
  • Column:列装饰器,将一个字段声明为一个数据表的一个字段,可以设置字段的数据类型,基础的校验方式,使用方式@Column('varchar', { length: 500, unique: true })
  • PrimaryGeneratedColumn:主键装饰器,将一个字段声明为主键,对应数据库表字段的主键。

值得注意的是:@Entity只能装饰类,@Column只能装饰类属性

代码语言:txt
AI代码解释
复制
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

@Entity('pokemon')
export class PokemonEntity {
    @PrimaryGeneratedColumn('uuid')
    id: string

    @Column('varchar', { length: 500, unique: true })
    name: string

    @Column('varchar', { length: 500 })
    type: string

    @Column('numeric')
    pokedex: number
}

这时候我们引入这个实体到app.module.ts中,代码为如下所示:

代码语言:txt
AI代码解释
复制
import { Module } from '@nestjs/common';
import { AppService } from './app.service';
import { AppController } from './app.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PokemonEntity } from "./modules/pokemon/pokemon.entity";


@Module({
  imports: [
    TypeOrmModule.forRoot({
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "123456789",
      "database": "nest3",
      "synchronize": true,
      "logging": false,
      "entities": [PokemonEntity]
    })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

现在保存代码,我们可以看到错误已经消失了,我们进入mysql服务,查看数据多了一个名字叫nest3的数据库,选择它,我们可以查看到已经创建了pokemon表,使用desc pokemon;查看表详情:

pokemon
pokemon

到目前为止,我们的已经成功把TypeORM添加到了项目中,下一步添加GraphQL

四、添加TypeGraphQL到项目中

4.1、安装依赖与功能说明

同上,NestJs官方也支持了GraphQL,对于TypeGraphQL我们有两种选择方式,一是安装type-graphql,二是直接使用@nestjs/graphql,这里我们直接使用@nestjs/graphql。 我们先把需要的依赖安装下:

代码语言:txt
AI代码解释
复制
$ npm i @nestjs/graphql --save

因为Graphql需要依赖具体的事务,所以我们在src/modules/pokemon目录下创建三个文件,分别是:pokemon.module.tspokemon.service.tspokemon.resolver.tspokemon.module.ts用于声明pokemon模块,pokemon.service.ts则具体与数据库做交互,pokemon.resolver.ts则用于创建GraphQL相关的QueryMutation我们将在这个示例中首先两个功能,创建一个pokemon,查询全部的pokemon

4.2、GraphQL基本方法说明与Schema声明

首先GraphQL常用的几个装饰器方法分别是:

  • ObjectType:声明一个Schema(数据结构),对一个类进行装饰,用于声明这个Object的各个字段以及他们的类型,使用方式:@ObjectType
  • Field:声明一个属性,这个属性属于ObjectType在进行API查询的时候将会用于解释一个字段,它对类的一个属性进行装饰,使用方式:@Field
  • InputType:声明一个输入类型的Schema,当进行Mutation变异查询(提交数据)的时候,提交的数据格式必须要按照此结构提交,使用方式:InputType。同@ObjectType对一个类进行装饰。

现在我们声明一个Pokemon ObjectType,我们在src/modules/pokemon创建一个文件夹dto(Data Transfer Object),然后在src/modules/pokemon/dto目录下创建create-pokemon.dto.ts,内容为以下:

代码语言:txt
AI代码解释
复制
import { Field, ObjectType} from 'type-graphql'

@ObjectType()
export class CreatePokemonDto {
    @Field() readonly id?: string
    @Field() readonly name: string
    @Field() readonly type: string
    @Field() readonly pokedex: number
}

这个文件的内容做了以下行为:

  • 声明一个叫做CreatePokemonDto的类,并且使用了@ObjectType()进行修饰,所以它可以被当作一个TypeGraphQLSchema
  • 这个类声明了四个只读属性的字段,并且定义了输入的数据类型。
4.3、声明pokemon模块,并引入到App中

到目前为止,我们以及创建好了TypeORMentity实体,TypeGraphQLObjectType,现在我们先声明PokemonModule

代码语言:txt
AI代码解释
复制
import { Module } from '@nestjs/common'

@Module({
    imports: [],
    providers: []
})
export class PokemonModule {}

现在,我们把它们融合到pokemon.module.ts中,但在此之前,我们需要声明PokemonModuleProviders,一是在pokemon.service.ts中提供与数据库交互的方法。这两个方法即是我们之前提到的创建以及查询一个列表代码如下:

代码语言:txt
AI代码解释
复制
import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { PokemonEntity } from './pokemon.entity'
import { Repository } from 'typeorm'

@Injectable()
export class PokemonService {
    constructor (
        @InjectRepository(PokemonEntity) 
        private readonly PokemonRepository: Repository<PokemonEntity>
    ) {}
    async getPokemons () {}
    async createPokemon (data: CreatePokemonDto): Promise<PokemonEntity> {}
}

第二是在当前目录下创建pokemon.resolver.ts,这个文件的内容将用于提供GraphQL的方法,代码如下:

代码语言:txt
AI代码解释
复制
import { Resolver, Query, Mutation, Args } from '@nestjs/graphql'
import { PokemonEntity } from './pokemon.entity'
import { CreatePokemonDto } from './dto/create-pokemon.dto'
import { PokemonService } from './pokemon.service'
import { inputPokemon } from './input/pokemon.input'

@Resolver(() => PokemonEntity)
export class PokemonResolver {
    constructor (private readonly pokemonService: PokemonService) {}

    @Query(() => [ CreatePokemonDto ])
    async pokemon () {
        return this.pokemonService.getPokemons()
    }

    @Mutation(() => CreatePokemonDto)
    async createPokemon (@Args('data') data: inputPokemon) {
        return this.pokemonService.createPokemon(data)
    }
}

其中:inputPokemon是一个TypeGraphQL的输入类型的Schema,文件将放在src/mmodules/pokemon/input目录下,代码如下:

代码语言:txt
AI代码解释
复制
import { Field, InputType } from 'type-graphql'

@InputType()
export class inputPokemon {
    @Field() readonly name: string
    @Field() readonly type: string
    @Field() readonly pokedex: number
}

这个文件声明了inputPokemon的输入类型,并且规定了属性以及属性的数据类型。

现在开始改造pokemon.module.ts,代码如下:

代码语言:txt
AI代码解释
复制
import { PokemonResolver } from './pokemon.resolver'
import { Module } from '@nestjs/common'
import { PokemonService } from './pokemon.service'
import { TypeOrmModule } from '@nestjs/typeorm'
import { PokemonEntity } from './pokemon.entity'

@Module({
    imports: [ TypeOrmModule.forFeature([ PokemonEntity ]) ],
    providers: [ PokemonResolver, PokemonService ]
})
export class PokemonModule {}

这里的TypeOrmModule.forFeature()则是给当前模块提供功能的子模块,表示当前模块会使用到TypeORMproviders内包含两个元素,分别是提供GraphQL功能的PokemonResolver,提供与数据交互的PokemonService。我们现在把PokemonService的功能完善如下:

代码语言:txt
AI代码解释
复制
import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { PokemonEntity } from './pokemon.entity'
import { Repository } from 'typeorm'
import { CreatePokemonDto } from './dto/create-pokemon.dto'

@Injectable()
export class PokemonService {
    constructor (
        @InjectRepository(PokemonEntity) 
        private readonly PokemonRepository: Repository<PokemonEntity>
    ) {}
    async createPokemon (data: CreatePokemonDto): Promise<PokemonEntity> {
        let pokemon = new PokemonEntity()
        pokemon.name = data.name
        pokemon.pokedex = data.pokedex
        pokemon.type = data.type
        await this.PokemonRepository.save(pokemon)
        return pokemon
    }

    async getPokemons () {
        return await this.PokemonRepository.find()
    }
}

最后,我们将PokemonModule引入到app.module.ts中,并且在里面注入TypeGraphQL的功能模块,代码如下:

代码语言:txt
AI代码解释
复制
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { PokemonModule } from './modules/pokemon/pokemon.module'
import { PokemonEntity } from "./modules/pokemon/pokemon.entity";

@Module({
  imports: [
    TypeOrmModule.forRoot({
      "type": "mysql",
      "host": "localhost",
      "port": 3306,
      "username": "root",
      "password": "123456789",
      "database": "nest3",
      "synchronize": true,
      "logging": false,
      "entities": [PokemonEntity]
    }),
    GraphQLModule.forRoot({
      autoSchemaFile: 'schema.gpl'
    }),
    PokemonModule
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

保存以上文件,我们打开 http://localhost:3000/graphql ,即可看到GraphQL的调试界面。

结语

其实总体来说,整个NestJs应用的开发体验还是蛮好的,相关的生态也发展的比较成熟,本项目仅是对相关技术的一个整体尝试,实际在开发过程中遇到的还有很多别的问题,比如GraphQLN+1查询问题,前后端分离应用的登陆认证问题等等...TypeORM也并不是很完美的技术,当应用有比较复杂的查询关系的时候,效率会低下,相关代替产品有SequelizePrisma等等技术都可以代替掉。个人可以根据实际需求,对比优缺点进行选择。

学而时习之,不亦说乎。温故而知新,可以为师矣。努力努力~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringBoot3.x日志生产最佳实践原来是这样!
SpringBoot对日志的配置和加载进行了封装,让我们可以很方便地使用一些日志框架,只需要定义对应日志框架的配置文件,如LogBack、Log4j、Log4j2等,代码内部便可以直接使用。
JavaEdge
2023/08/15
2.4K0
SpringBoot3.x日志生产最佳实践原来是这样!
SpringBoot 系列-日志详解
默认情况下,如果使用 “starters”,则使用 Logback 进行日志记录。还包括适当的 Logback 路由,以确保使用 Java Util 日志记录、Commons 日志记录、Log4J 或 SLF4J 的依赖库都能正常工作。
安徽开发者圈
2020/03/02
1.9K0
SpringBoot日志源码解析:日志监听器的执行
LoggingApplicationListener 的主要作用是配置LoggingSystem, 如果 环境 包含 loggingconfig 属性,LoggingApplicationListener 将用于引导 日志记录系统,否则使用默认配置。
愿天堂没有BUG
2022/10/28
1K0
SpringBoot日志源码解析:日志监听器的执行
日志框架Log4j的学习小记
Java项目的框架基本就是slf4j,slf4j提供了一套规范,也就是门面,而至于后边是如何实现的只要按照人家定义的接口去做就行了。常见的日志框架又springboot自带的logback,还有异步的日志框架log4j,当然还有一些大佬自己做日志框架的。这里作者大概的看了一下日志框架的代码。稍微讲解一下日志框架是怎么做的。
写一点笔记
2022/08/11
3020
日志框架Log4j的学习小记
聊聊springboot的logging.group
org/springframework/boot/actuate/logging/LoggersEndpoint.java
code4it
2023/12/02
1890
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的
SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴 实现了 spring-boot 2.x.x 与 logback 1.3.x 的集成,分两步
青石路
2024/08/23
2220
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的
聊聊springboot的LogbackLoggingSystem
org/springframework/boot/logging/LoggingSystem.java
code4it
2023/11/02
2760
动态设置 log4j2 日志的级别不能落
上篇[ SpringBoot 动态设置 logback 日志的级别 ] 说了 logback 动态设置日志级别。这篇来说下 log4j2 日志框架结合 SpringBoot 动态设置日志级别。因为 log4j2 日志框架也有非常多的公司采用,毕竟 logback 和 log4j2 是现在用的最多的两个日志框架。都不能落对吧。
BUG弄潮儿
2021/05/17
2K0
动态设置 log4j2 日志的级别不能落
springboot中log加载流程
springboot容器启动的时候, 会在不同的阶段发送Event事件. 在LoggingApplicationListener中代码如下:
eeaters
2024/11/11
1521
springboot中log加载流程
聊聊springboot的LogbackLoggingSystem
org/springframework/boot/logging/LoggingSystem.java
code4it
2023/11/03
2030
聊聊springboot的LogbackLoggingSystem
集成动态日志,“消灭”logback-spring.xml
动态调整线上日志级别是一个非常常见的场景,借助apollo这种配置中心组件非常容易实现。作为apollo的官方技术支持,博主经常在技术群看到有使用者询问apollo是否可以托管logback的配置文件,毕竟有了配置中心后,消灭所有的本地配置全部交给apollo管理是我们的最终目标。可是,apollo不具备直接托管logback-spring.xml配置文件能力,但是,我们可以基于spring和logback的装载机制,完全取缔logback-spring.xml配置,以apollo中的配置驱动。而且,改造后,大大提高了日志系统的灵活性和可扩展性。
用户5546570
2020/12/09
1.4K0
实战:如何优雅地扩展Log4j配置?
Log4j 日志框架我们经常会使用到,最近,我就遇到了一个与日志配置相关的问题。简单来说,就是在原来日志配置的基础上,指定类的日志打印到指定的日志文件中。
杨同学technotes
2022/12/01
6120
springboot 默认日志配置源码
版本 2.2.x 日志系统初始化流程 应用启动时,ApplicationStartingEvent触发,屏蔽所有日志 ApplicationEnvironmentPreparedEvent触发,清空所有日志配置,重新初始化日志系统 配置变更,EnvironmentChangeEvent触发,重新设置日志级别 源码 org.springframework.cloud.bootstrap.LoggingSystemShutdownListener public class LoggingSystemShutdo
路过君
2020/09/07
1K0
日志级别动态调整——小工具解决大问题
背景 随着外卖业务的快速发展,业务复杂度不断增加,线上系统环境有任何细小波动,对整个外卖业务都可能产生巨大的影响,甚至形成灾难性的雪崩效应,造成巨大的经济损失。每一次客诉、系统抖动等都是对技术人员的重大考验,我们必须立即响应,快速解决问题。 如何提高排查问题的效率呢?最有效的方式是通过分析系统日志。如果系统日志全面,会为我们排查解决线上问题带来绝大的帮助,但是要想保证系统日志全面,就必须打印出所有的系统或业务日志。这样就会带来另一个问题,那就是日志量的暴涨,过多的日志除了能够帮助我们解决问题外,同时会直接造
美团技术团队
2018/03/12
2.5K1
日志级别动态调整——小工具解决大问题
Spring Boot 2动态修改日志级别
作为程序猿,定位问题是我们的日常工作,而日志是我们定位问题非常重要的依据。传统方式定位问题时,往往是如下步骤:
乱敲代码
2019/06/03
1.4K0
SpringBoot 用的 spring-jcl 打印日志,与 LoggingSystem 有鸡毛关系?
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的 从源码的角度讲述了 Spring Boot 的 LoggingSystem 与日志组件的绑定,默认情况下绑定的是 Logback;但当我们具体去看 Spring Boot 的日志打印,却发现用的是 spring-jcl ,通过它适配了 slf4j,真正的日志打印还得依赖具体的日志组件,默认情况下使用的是 logback;那这么说来,Spring Boot 的日志打印与 Spring Boot 的 LoggingSystem 貌似没关系呀?
青石路
2024/08/24
1250
SpringBoot 用的 spring-jcl 打印日志,与 LoggingSystem 有鸡毛关系?
springboot超级详细的日志配置(基于logback)
  java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日志框架就能够用 slj4f 调用)。其中性能最高的应该使 logback 了,而且 springboot 默认使用的也是 logback 日志,所以本篇将会详细的讲解 logback 的日志配置方案。
用户2038589
2019/06/13
26.1K0
Spring Boot 系列:日志动态配置详解
不知道大家有没有过当线上出现问题的时候,需要某些DEBUG日志,但奈何当前使用时INFO。
用户5546570
2020/10/27
2.1K0
Spring Boot 系列:日志动态配置详解
Spring Boot 2动态修改日志级别
作为程序猿,定位问题是我们的日常工作,而日志是我们定位问题非常重要的依据。传统方式定位问题时,往往是如下步骤:
张乘辉
2019/06/14
1.3K0
Spring Boot 2动态修改日志级别
Java日志体系(log4j2)
1 log4j2 1.1 简介 log4j2,一个日志的实现框架,是log4j的升级版本,于2014年7月正式亮相。与第一代log4j不同,log4j2完全重写了log4j的日志实现,并不是在原有基础
贾博岩
2018/05/11
2.9K0
推荐阅读
相关推荐
SpringBoot3.x日志生产最佳实践原来是这样!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档