【NextJS】PostgreSQL 遇上 Prisma ORM

NextJS 数据库 之 遇上Prisma ORM

  • 前言
  • 一、环境要求
  • 二、概念介绍
    • 1、Prisma Schema Language(PSL) 结构描述语言
      • 1.1 概念
      • 1.2 组成
        • 1.2.1 Data Source 数据源
        • 1.2.2 Generators 生成器
        • 1.2.3 Data Model Definition 数据模型定义
          • 字段(数据)类型和约束
          • 关系(Relations)
          • 枚举(Enum)
    • 2、Prisma Client 数据交互接口
      • 2.1 概念
      • 2.2 使用示例
    • 3、Prisma Migrate 迁移与种子
      • 3.1 概念
      • 3.2 迁移流程
      • 3.3 数据库迁移(Migrate)
      • 3.3 数据种子(Seeding)
    • 4、Prisma CLI 命令行工具
      • init
      • generate
  • 三、Next.js 中应用示例
    • 1、全新项目示例
      • 1.1 项目初始化
      • 1.2 初始化Prisma ORM
      • 1.3 数据迁移
      • 1.4 播种数据(可选)
      • 1.5 模拟业务

前言

Next.js 全栈开发的时候不免要用到数据库,采用原生数据库语法可能还需要顾虑很多方面的问题(语法安全、原生语法麻烦/繁琐/复杂、更换数据库时的语法兼容等等),为了解决这类问题诞生了ORM‌(Object-Relational Mapping)数据访问方式技术及周边工具;

这里介绍一个易用又强大的ORM‌框架/工具库:Prisma ORM

官网:https://www.prisma.io/
GitHub:https://github.com/prisma/prisma

内容包含以下两个部分:

  • 重点概念

    • Prisma Schema Language (PSL).:用来描述数据库架构的语言
  • 两个主要(常用)操作库

    • Prisma Client:为 Node.js 和 TypeScript 自动生成类型安全的查询生成器
      可用于任何Node.jsTypeScript 后端应用程序(包括无服务器应用程序和微服务)。
    • Prisma Migrate:声明式数据建模和迁移系统
      主要用于生产部署、数据迁移等应用场景
    • Prisma CLI:辅助快捷的操作命令工具

延展辅助(平台服务):

  • Prisma Postgres[链接]:托管的 PostgreSQL 数据库服务
  • Prisma Accelerate[链接]:针对现有数据库的完全托管的全局连接池和缓存层,可直接从 Prisma ORM 支持查询级缓存策略。
  • Prisma Optimize[链接]:针对数据操作,基于AI进行优化分析服务
  • Prisma Studio[链接]:用于查看和编辑等操作的数据库可视化GUI工具

一、环境要求

最新环境要求可前往官方文档:https://www.prisma.io/docs/orm/reference/system-requirements

软件:

工具最低要求版本
Node.js18.8 / 20.9 / 22.11
TypeScript (可选)5.1.X
Yarn (可选)1.19.2(当使用Yarn 1时)

操作系统:

Linux:

  • OpenSSL 1.0.x、1.1.x 或 3.x
  • zlib(libz.so.1)
  • libgcc( libgcc_s.so.1)
  • C 标准库(大多数 Linux 发行版上的 glibc 或 Alpine Linux 上的 musl libc)

Windows:

  • Microsoft Visual C++ 可再发行组件 2015或必须安装更新版本

macOS:

  • macOS 10.15 或更新版本

二、概念介绍

1、Prisma Schema Language(PSL) 结构描述语言

1.1 概念

Prisma Schema Language(简称:PSL) - Prisma ORM 的核心部分
用于定义数据库模型关系、以及生成 Prisma Client 的配置文件

  • 【Prisma Schema 参数文档】:https://www.prisma.io/docs/orm/reference/prisma-schema-reference

想要将架构拆分为多个文件? Prisma ORM 5.15.0 及更高版本中的 prismaSchemaFolder 预览功能 支持多文件 Prisma Schema 。

它是一个声明式语言,通过定义 .prisma 文件来描述数据库结构关系
Prisma Client将基于(PSL)生成数据库交互代码。

1.2 组成

  • Data Source:数据库源(例如:PostgreSQL or MongoDB…)
  • Generators:数据模型生成器(例如:Prisma Client)
  • Data model definition:数据模型定义(例如,user数据表有哪些字段、分别什么数据类型等)
1.2.1 Data Source 数据源

定义数据库的连接信息,通常包括数据库的类型(例如PostgreSQL、MySQL、SQLite等)、连接URL、以及数据库的其他配置。

示例:

datasource db {
  provider = "postgresql" // 指定 PostgreSQL 作为数据库
  url      = env("DATABASE_URL") // 从环境变量 DATABASE_URL 获取连接字符串
}
1.2.2 Generators 生成器

定义生成器的配置,Prisma默认使用生成Prisma Client。
通常会在此配置生成的Prisma Client存放的位置,以及语言(TypeScript/JavaScript)。

示例:

generator client {
  provider = "prisma-client-js"
  output   = "./generated/client"
}
1.2.3 Data Model Definition 数据模型定义

定义数据库中的实体(表)。每个model对应数据库中的一个表,表的字段对应model中的属性
可以定义字段的类型默认值约束(如@id@unique等)以及关系(如@relation)。

model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String
  posts Post[]
}

model Post {
  id      Int    @id @default(autoincrement())
  title   String
  content String?
  author  User   @relation(fields: [authorId], references: [id])
  authorId Int
}
字段(数据)类型和约束

每个字段可以指定数据类型,支持多种类型,如IntStringBooleanDateTimeFloatDecimal等。
可以通过@default()设置默认值,@unique设置唯一约束,@id定义主键等。

  • 更多内置约束:https://www.prisma.io/docs/orm/reference/prisma-schema-reference#attributes
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  published Boolean  @default(false)
  createdAt DateTime @default(now())
}
关系(Relations)

PSL支持定义实体之间的关系。常见的关系包括一对一(1:1)一对多(1:N)多对多(M:N)。通过@relation定义。

  • 更多关系说明:https://www.prisma.io/docs/orm/prisma-schema/data-model/relations
// 示例:一对多关系

model User {
  id    Int    @id @default(autoincrement())
  posts Post[]
}

model Post {
  id      Int    @id @default(autoincrement())
  userId  Int
  author  User   @relation(fields: [userId], references: [id])
}
枚举(Enum)

PSL还支持枚举类型,用于表示有多个固定选项的字段。

// 示例

enum Role {
  USER
  ADMIN
  MODERATOR
}

model User {
  id    Int    @id @default(autoincrement())
  name  String
  role  Role
}

更多数据模型内容可以前往官方文档探索:https://www.prisma.io/docs/orm/prisma-schema/data-model

2、Prisma Client 数据交互接口

2.1 概念

Prisma ClientPrisma ORM 的主要组成部分,它是一个自动生成的数据库查询客户端,用于与数据库进行交互。
提供一种类型安全的方式来执行数据库操作,简化与数据库的连接和操作。

  • 【Prisma Client API文档】:https://www.prisma.io/docs/orm/reference/prisma-client-reference

关键特点:

  • 自动生成:根据数据库模式(schema.prisma 文件)自动生成一个类型安全的客户端库(代码)
  • 类型安全:使用 TypeScript 来生成类型定义,这意味着在开发过程中,可以获得类型推导和自动补全,数据操作无需手动编写原始SQL语法交由Prisma Client 提供的 API 使用 JavaScript/TypeScript 中的类型安全语法
  • 完善接口(API):包含CRUD、关联、分页和排序、事务操作等
  • 数据库支持PostgreSQLMySQLMariaDBSQL ServerSQLiteCockroachDBMongoDB 各类主流数据库

2.2 使用示例

  1. 定义数据库模型(schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int    @id @default(autoincrement())
  name  String
  email String @unique
}
  1. 模型构建
pnpx prisma generate
  1. 在代码中使用
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function main() {
  const users = await prisma.user.findMany();
  console.log(users);
}

main().catch(e => {
  throw e
}).finally(async () => {
  await prisma.$disconnect()
});

3、Prisma Migrate 迁移与种子

3.1 概念

Prisma MigratePrisma ORM 中用于数据库迁移的工具。
通过自动生成和执行 SQL 迁移脚本来管理数据库结构变化,同时确保数据库结构与 Prisma Schema 文件(schema.prisma)保持一致。

3.2 迁移流程

Prisma ORM 的集成数据库迁移工具-工作流程
通常的工作流程包括以下几个步骤:

  • 修改 Prisma 模式:你在 schema.prisma 文件中修改数据库模型。
  • 创建迁移文件:运行 prisma migrate devprisma migrate create 命令,自动生成迁移文件。
  • 应用迁移:通过 prisma migrate deployprisma migrate dev 将迁移应用到数据库。
  • 查看迁移历史:Prisma 会在数据库中跟踪迁移历史,确保每次迁移都按顺序应用。

3.3 数据库迁移(Migrate)

3.3 数据种子(Seeding)

4、Prisma CLI 命令行工具

  • 文档[英]
  • 支持指令[英]

init

参数默认描述
--datasource-providerpostgresql指定块provider中字段的值datasource。选项包括sqlite、postgresql、mysql、和。sqlservermongodbcockroachdb
--url定义自定义数据源 URL
--with-model在初始 Prisma 模式中添加一个简单的用户模型。自 5.14.0 版起可用
--outputnode_modules/.prisma/client指定生成的客户端的输出位置
--generator-providerprisma-client-js定义要使用的生成器提供程序
--preview-feature定义要使用的预览功能

示例:

pnpx prisma init --datasource-provider PostgreSQL

generate

参数默认描述
--no-engine生成不带附带引擎的 Prisma Client 以与Prisma Accelerate–data-proxy一起使用。与和互斥–accelerate。在 Prisma ORM 5.2.0 及更高版本中可用。
--no-hints生成 Prisma Client,但不会在终端上打印使用提示。在 Prisma ORM 5.16.0 及更高版本中可用。
--allow-no-models将生成 Prisma Client,但不生成任何模型
--watch监视schema.prisma文件并在文件更改时重新生成 Prisma Client

示例:

prisma generate

其他的后续再整理补充…

三、Next.js 中应用示例

Next.js + PostgreSQL 组合为例!

node环境:

  • node:v20.17.0
  • pnpm:9.15.3

1、全新项目示例

1.1 项目初始化

  • react:^19.0.0
  • next:15.1.4
  • pg:^8.13.1
  • @prisma/client:^6.2.1
pnpx create-next-app@latest

// 安装时,将看到以下提示:
✔ What is your project named? … .
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … No
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for `next dev`? … No
✔ Would you like to customize the import alias (`@/*` by default)? … No

增加依赖包:pg@prisma/client

pnpm add pg @prisma/client

1.2 初始化Prisma ORM

// 初始化兼容PostgreSQL驱动数据库
pnpx prisma init --datasource-provider PostgreSQL

// 将看到以下提示:
✔ Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.

warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.

Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Run prisma db pull to turn your database schema into a Prisma schema.
3. Run prisma generate to generate the Prisma Client. You can then start querying your database.
4. Tip: Explore how you can extend the ORM with scalable connection pooling, global caching, and real-time database events. Read: https://pris.ly/cli/beyond-orm

More information in our documentation:
https://pris.ly/d/getting-started

至此,基础环境搞定,接下来重点查看编辑两个文件:.envprisma/schema.prisma
在这里插入图片描述
.env文件中,重点设置DATABASE_URL的值,用于建立数据库连接的配置

DATABASE_URL="postgresql://[username]:[password]@[ip|domain]:[port|5432]/[database][?param1=value1&param2=value2&...]"

prisma/schema.prisma文件中,对生成器、数据模型进行配置

generator client {
  provider = "prisma-client-js"
  output   = "./client"   // 配置生成器的代码生成位置(相对schema.prisma文件所在目录)
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// 以下部分均为数据模型构建配置
model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String
  posts Post[]
}

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String
  published Boolean
  user      User    @relation(fields: [userId], references: [id])
  userId    Int
}

完成以上配置后,开始生成Prisma客户端代码:

// 生成Prisma客户端
pnpx prisma generate

// 将看到以下提示:
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma

✔ Generated Prisma Client (v6.2.1) to ./prisma/client in 24ms

Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)

Tip: Need your database queries to be 1000x faster? Accelerate offers you that and more: https://pris.ly/tip-2-accelerate

在这里插入图片描述

1.3 数据迁移

将数据模型推送到数据库中

// 模型推送
pnpx prisma db push

// 将看到以下提示:
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "xxxx", schema "public" at "xxxx:5432"

🚀  Your database is now in sync with your Prisma schema. Done in 6.22s

✔ Generated Prisma Client (v6.2.1) to ./prisma/client in 28ms

1.4 播种数据(可选)

添加ts-node@types/node到开发依赖项

pnpm add -D ts-node @types/node

Ps:非TypeScript项目需要增加typescript依赖包

prisma目录下创建一个seed.ts文件,写入播种数据

// 导入 PrismaClient(注:pnpx prisma generate生成的代码)
import { PrismaClient } from './client'

// 创建 PrismaClient 实例
const prisma = new PrismaClient()

// 定义 main 函数
async function main() {
    // 使用 upsert 方法创建或更新用户
    const alice = await prisma.user.upsert({
        where: { email: 'alice@prisma.io' },
        update: {},
        create: {
            email: 'alice@prisma.io',
            name: 'Alice',
            posts: {
                create: {
                    title: 'Check out Prisma with Next.js',
                    content: 'https://www.prisma.io/nextjs',
                    published: true,
                },
            },
        },
    })
    // 创建另一个用户
    const bob = await prisma.user.upsert({
        where: { email: 'bob@prisma.io' },
        update: {},
        create: {
            email: 'bob@prisma.io',
            name: 'Bob',
            posts: {
                create: [
                    {
                        title: 'Follow Prisma on Twitter',
                        content: 'https://twitter.com/prisma',
                        published: true,
                    },
                    {
                        title: 'Follow Nexus on Twitter',
                        content: 'https://twitter.com/nexusgql',
                        published: true,
                    },
                ],
            },
        },
    })
    console.log({ alice, bob })
}

// 执行 main 函数并处理错误
main()
    .then(async () => {
        await prisma.$disconnect()
    })
    .catch(async (e) => {
        console.error(e)
        await prisma.$disconnect()
        process.exit(1)
    })

package.json文件中新增以下配置,告诉prisma播种文件所在位置及其他配置信息

{
  // .....
  "prisma": {
    "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
  },
  // .....
}

将种子数据推送上数据库里

// 种子推送
pnpx prisma db seed

// 将看到以下提示:
Environment variables loaded from .env
Running seed command `ts-node --compiler-options {"module":"CommonJS"} prisma/seed.ts` ...
{
  alice: { id: 1, email: 'alice@prisma.io', name: 'Alice' },
  bob: { id: 2, email: 'bob@prisma.io', name: 'Bob' }
}

🌱  The seed command has been executed.

在这里插入图片描述

1.5 模拟业务

创建一个api接口GET /api/users 用于获取用户表所有数据

1、实例化 Prisma 客户端

prisma目录创建一个db.ts文件,用于实例化
在这里插入图片描述

// file:/prisma/db.ts

import {PrismaClient} from './client'

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }

export const prisma = globalForPrisma.prisma || new PrismaClient()

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

export default prisma

2、创建数据API接口
在这里插入图片描述

"use server";

import {NextResponse} from 'next/server'
// 导入客户端实例
import prisma from "@/prisma/db"

export async function GET() {
	// 使用findMany方法获取user表相关数据
    const allUsers = await prisma.user.findMany();

    return NextResponse.json({
        message: 'Hello World',
        data: allUsers
    }, {status: 200});
}

3、测试获取是否正常
在这里插入图片描述


有何不足之处欢迎评论区或者私信我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/955957.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

细说STM32F407单片机电源低功耗SleepMode模式及应用示例

目录 一、STM32F4的低功耗模式 1、睡眠(Sleep)模式 2、停止(Stop)模式 3、待机(Standby)模式 二、睡眠模式 1、进入睡眠模式 2、睡眠模式的状态 3、退出睡眠模式 4、SysTick的影响 三、应用示例 1、工程配置 (1) 时钟、DEBUG、GPIO、CodeGen…

YOLOv11改进,YOLOv11检测头融合RepConv卷积,并添加小目标检测层(四头检测),适合目标检测、分割等任务

摘要 作者提出了一种简单而强大的卷积神经网络架构,其推理阶段采用与 VGG 类似的网络体结构,仅由一堆 3x3 卷积和 ReLU 组成,而训练阶段的模型具有多分支拓扑。这种训练阶段和推理阶段架构的解耦通过结构重参数化技术实现,因此我们将该模型命名为 RepVGG。 # 理论介绍 Re…

ScratchLLMStepByStep:训练自己的Tokenizer

1. 引言 分词器是每个大语言模型必不可少的组件,但每个大语言模型的分词器几乎都不相同。如果要训练自己的分词器,可以使用huggingface的tokenizers框架,tokenizers包含以下主要组件: Tokenizer: 分词器的核心组件,定…

Linux 操作二:文件映射与文件状态

Linux 操作二:文件映射与文件状态查询 文件映射 ​ mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程…

网络编程-TCP套接字

文章目录 初始TCP套接字TCP的Socket APISocketServerSocket 使用TCP模拟通信服务器端客户端 上述测试代码的问题分析IO的输入缓冲区的问题关于TCP协议中的粘包的问题不能进行多线程通信的问题 处理问题之后的完整代码启动多个实例完整代码测试结果 关于IO多路复用机制的引入 初…

flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈

flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈 开发背景 可能大家听过过蓝湖可以转ui设计图为vue.js,react native代码,那么请问听说过将figma的设计图转换为flutter源代码吗?本文优雅草央千澈带…

重拾Python学习,先从把python删除开始。。。

自己折腾就是不行啊,屡战屡败,最近终于找到前辈教我 第一步 删除Python 先把前阵子折腾的WSL和VScode删掉。还是得用spyder,跟matlab最像,也最容易入手。 从VScode上搞python,最后安装到appdata上,安装插…

【机器学习实战中阶】音乐流派分类-自动化分类不同音乐风格

音乐流派分类 – 自动化分类不同音乐风格 在本教程中,我们将开发一个深度学习项目,用于自动化地从音频文件中分类不同的音乐流派。我们将使用音频文件的频率域和时间域低级特征来分类这些音频文件。 对于这个项目,我们需要一个具有相似大小和相似频率范围的音频曲目数据集…

[Qt]事件-鼠标事件、键盘事件、定时器事件、窗口改变事件、事件分发器与事件过滤器

目录 前言:Qt与操作系统的关系 一、Qt事件 1.事件介绍 2.事件的表现形式 常见的Qt事件: 常见的事件描述: 3.事件的处理方式 处理鼠标进入和离开事件案例 控件添加到对象树底层原理 二、鼠标事件 1.鼠标按下和释放事件(单击&#x…

后盾人JS -- 好用的 JavaScript Symbol 类型

Symbol使用场景介绍 举个例子,当leader让你去机房取某个电脑的时候,机房那么多电脑,你怎么知道取哪个 所以这个时候symbol的作用就显现出来了(上面有什么贴纸的,什么型号的电脑) 声明定义Symbol的几种方…

社区版Dify实现文生视频 LLM+ComfyUI+混元视频

社区版Dify实现文生视频 LLMComfyUI混元视频 一、 社区版Dify实现私有化混元视频效果二、为什么社区版Dify可以在对话框实现文生视频?LLMComfyUI混元视频 实现流程图(重点)1. 文生视频模型支持ComfyUI2. ComfyUI可以轻松导出API实现封装3. Di…

数智化转型 | 星环科技Defensor 助力某银行数据分类分级

在数据驱动的金融时代,数据安全和隐私保护的重要性日益凸显。某银行作为数字化转型的先行者,面临着一项艰巨的任务:如何高效、准确地对分布在多个业务系统、业务库与数仓数湖中的约80万个字段进行数据分类和分级。该银行借助星环科技数据安全…

Spring boot启动原理及相关组件

优质博文:IT-BLOG-CN 一、Spring Boot应用启动 一个Spring Boot应用的启动通常如下: SpringBootApplication Slf4j public class ApplicationMain {public static void main(String[] args) {ConfigurableApplicationContext ctx SpringApplication.…

中国石油大学(华东)自动评教工具(涵盖爬虫的基础知识,适合练手)

我开发了一个用于自动评教的工具,大家可以试着用用,下面是链接。 https://github.com/restrain11/auto_teachingEvaluate 可以点个星吗,感谢!🫡 以下是我在开发过程中学到的知识 以及 碰到的部分问题 目录 动态爬虫和静…

PyTorch使用教程(2)-torch包

1、简介 torch包是PyTorch框架最外层的包,主要是包含了张量的创建和基本操作、随机数生成器、序列化、局部梯度操作的上下文管理器等等,内容很多。我们基础学习的时候,只有关注张量的创建、序列化,随机数、张量的数学数学计算等常…

机器学习-距离的度量方法

文章目录 一. 欧式距离二. 曼哈顿距离三. 切比雪夫距离四. 闵式距离1. p不同取值,表示不同距离2. 当 ( p → ∞ ) ( p \to \infty ) (p→∞) 时,为什么闵式距离变为切比雪夫距离 五. 总结 一. 欧式距离 欧式距离(Euclidean distance):多维空…

ComfyUI 矩阵测试指南:用三种方法,速优项目效果

在ComfyUI中,矩阵测试也叫xyz图表测试,作用是通过控制变量的方式来对Lora模型以及各种参数开展测试,并进行有效区分。其中测试方法有很多种,可以通过借助插件也可以自行搭建工作流实现,下面介绍3种方式: 1…

内存与缓存:保姆级图文详解

文章目录 前言1、计算机存储设备1.1、硬盘、内存、缓存1.2、金字塔结构1.3、数据流通过程 2、数据结构内存效率3、数据结构缓存效率 前言 亲爱的家人们,创作很不容易,若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的…

UllnnovationHub,一个开源的WPF控件库

目录 UllnnovationHub1.项目概述2.开发环境3.使用方法4.项目简介1.WPF原生控件1.Button2.GroupBox3.TabControl4.RadioButton5.SwitchButton6.TextBox7.PasswordBox8.CheckBox9.DateTimePicker10.Expander11.Card12.ListBox13.Treeview14.Combox15.Separator16.ListView17.Data…

【STM32-学习笔记-10-】BKP备份寄存器+时间戳

文章目录 BKP备份寄存器Ⅰ、BKP简介1. BKP的基本功能2. BKP的存储容量3. BKP的访问和操作4. BKP的应用场景5. BKP的控制寄存器 Ⅱ、BKP基本结构Ⅲ、BKP函数Ⅳ、BKP使用示例 时间戳一、Unix时间戳二、时间戳的转换(time.h函数介绍)Ⅰ、time()Ⅱ、mktime()…