首页 > 数据库 >NodeJS系列(13)- Next.js 框架 (六) | Node.js + Next.js + Prisma/Sequelize (ORM) + MySQL 搭建 JSON API 服务

NodeJS系列(13)- Next.js 框架 (六) | Node.js + Next.js + Prisma/Sequelize (ORM) + MySQL 搭建 JSON API 服务

时间:2023-11-04 22:56:59浏览次数:50  
标签:Node ... prisma Prisma Next user js schema

Next.js 是一个用于构建 Web 应用程序的框架。Next.js 是一个用于生产环境的 React 框架,是一个 React 服务端渲染应用框架。

NextJS: https://nextjs.org/


Prisma 是一个基于 promise 的 Node.js 和 TypeScript 的 ORM,目前支持 Mysql,MariaDB,SQLite,PostgreSQL,AWS Aurora Serverless 和 Aws Aurora ,暂不支持 Microsft SQL Server 。Prisma 通过提供 类型安全、丰富的自动补全、平滑的 API 等特性。

Prisma: https://www.prisma.io
Prisma CN: https://prisma.yoga/
Prisma NextJS: https://www.prisma.io/nextjs

 

Sequelize 是一个基于 promise 的 Node.js 的 ORM,目前支持 Mysql,Postgres,MariaDB,SQLite 以及 Microsft SQL Server。它具有强大的事务支持,关联关系,预读和延迟加载,读取复制等功能。
Sequelize: https://sequelize.org/

Sequelize CN: https://www.sequelize.cn/


Prisma 和 Sequelize 各自支持的功能比较表如下:

  Prisma Sequelize
原始查询 yes yes
事务 yes yes
自动生成 Schema yes yes
迁移 yes yes
TypeScript yes yes
子查询 yes no
读写分离 no yes
乐观锁 yes no
高级函数 yes no


                       
  
本文选择使用 Node.js + Next.js + Prisma + MySQL 搭建 JSON API 服务。

 

1. 系统环境

    NodeJS:  16.20.1
    NPM: 8.19.4
    NextJS: 13.4.12
    Prisma:5.5.2

 

2. 创建 NextJS 项目

    安装 create-next-app 脚手架,命令如下:

        # 使用 -g 参数,表示该命令只需在本机上运行一次
        $ npm install -g [email protected]      

            ...

        注:或直接使用如下命令创建 next 项目  
            
            $ npx [email protected]

    使用 create-next-app 命令创建 NextJS 项目,命令如下:

        $ create-next-app furniture-service
        
            √ What is your project named? ... furniture-service
            √ Would you like to use TypeScript? ... No / Yes
            √ Would you like to use ESLint? ... No / Yes
            √ Would you like to use Tailwind CSS? ... No / Yes
            √ Would you like to use `src/` directory? ... No / Yes
            √ Would you like to use App Router? (recommended) ... No / Yes
            √ Would you like to customize the default import alias? ... No / Yes
            Creating a new Next.js app in ..\furniture-service.

        注:这里选择 App Router

    进入 furniture-service 项目目录安装依赖,命令如下:

        $ npm install

            ...

    运行 furniture-service 项目,命令如下:

        $ npm run start     # npm run dev

            ...

    浏览器访问 http://localhost:3000,显示内容如下:
    
        Get started by editing src/app/page.js


3. API 路由

    路由处理程序 (Route Handlers) 允许用户使用 Web 请求和响应 API 为给定路由创建自定义请求处理程序。它定义在 app 目录及其子目录下的 route.js 或 route.ts 文件中,比如:

        app/api/route.js

    路由处理程序类似于 page.js 和 layout.js,但在同一目录下 page.js 和 router.js 不能同时存在。

    支持以下 HTTP 方法:GET、POST、PUT、PATCH、DELETE、HEAD 和 OPTIONS。如果调用了不支持的方法,Next.js 将返回一个 405 method Not Allowed 响应。

    示例,创建 app/api/route.js 文件,内容如下:

       import { NextResponse } from 'next/server';

        export async function GET(request) {

            //console.log(request.nextUrl.searchParams);
            return NextResponse.json({ ret: 'GET Success' }, { status: 200 });
        }

        export async function POST(request) {
            //console.log(request);  
            return NextResponse.json({ ret: 'POST Success' }, { status: 200 });
        }


    运行 furniture-service 项目,浏览器访问 http://localhost:3000/api,显示内容如下:

        {"ret":"GET Success"}

    Postman 用 POST 方法访问 http://localhost:3000/api,显示内容如下:

        {
            "ret": "POST Success"
        }


4. 安装 MySQL 支持

    手动创建 MySQL 数据库 testdb 和 user 表,SQL 脚本如下:

        CREATE TABLE `user` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `username` varchar(50) NOT NULL,
            `password` varchar(255) DEFAULT NULL,
            `age` int(11) DEFAULT NULL,
            `createtime` timestamp NULL DEFAULT NULL,
            PRIMARY KEY (`id`),
            UNIQUE KEY (`username`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        # 创建一条用户记录
        INSERT INTO user (username, password, age, createtime) VALUES ('admin', '123456', 18, Now());


    进入 furniture-service 项目目录,安装 MySQL 支持,命令如下:

        $ npm install mysql mysql2 --save

            ...

    修改 app/api/route.js 文件,内容如下:

        import { NextResponse } from 'next/server';
        import mysql from 'mysql';


        const getData = () => {
            return new Promise((resolve, reject) => {

                var connection = mysql.createConnection({     
                    host     : 'localhost',       
                    user     : 'root',              
                    password : '123456',       
                    port: '3306',                   
                    database: 'testdb'
                });
                
                connection.connect();
                connection.query('SELECT * FROM user', function (err, result) {
                    if (err) {
                        //console.log("getData() -> reject: " + err.message);
                        reject({ ret: 'error', msg: err.message })
                    }
                
                    //console.log("getData() -> resolve: " + result);
                    resolve({ ret: 'success', data: result});
                });
                
                connection.end();
            })
        }

        export async function GET(request) {

            let data = await getData();
            //console.log(data);

            return NextResponse.json( data, { status: 200 });
        }

        export async function POST(request) {
            console.log(request);  
            return NextResponse.json({ ret: 'POST Success' }, { status: 200 });
        }


    运行 furniture-service 项目,浏览器访问 http://localhost:3000/api,显示内容如下:

        {"ret":"success","data":[{"id":1,"username":"admin","password":"123456","age":18,"createtime":"2023-11-04T07:24:59.000Z"}]}


5. 安装 ORM 支持

    1) 安装 Prisma

        在 furniture-service 项目目录下安装 Prisma,命令如下:

            $ npm install prisma --save

                ...

            注:可以运行 npx prisma 来查看 prisma 的命令使用方法。

        创建 Prisma 架构文件模板来设置 Prisma 项目,命令如下:

            $ npx prisma init

                ✔ Your Prisma schema was created at prisma/schema.prisma

                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. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb.      
                3. Run prisma db pull to turn your database schema into a Prisma schema.
                4. Run prisma generate to generate the Prisma Client. You can then start querying your database.

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

        以上命令会在 furniture-service 项目的根目录下创建一个 .env 文件和一个 prisma 目录,.env 文件用于定义环境变量(例如数据库连接),prisma 目录下生成了一个 schema.prisma 文件,schema.prisma 文件包含带有数据库连接变量和模式模型的 prisma 模式。


    2) 配置 prisma


        修改 .env 文件,内容如下:

            DATABASE_URL="mysql://root:123456@localhost:3306/testdb?schema=public"

        修改 prisma/schema.prisma

            // This is your Prisma schema file,
            // learn more about it in the docs: https://pris.ly/d/prisma-schema

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

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

                
    3) 反向生成 prisma 数据模型

        上文的示例中,我们手动创建了 MySQL 数据库 testdb 和 user 表,这里在 .env 文件里配置了连接到 testdb 数据库,可以反向生成 user 表的数据模型,保存到 prisma\schema.prisma 文件,命令如下:

            $ npx prisma db pull

                Prisma schema loaded from prisma\schema.prisma
                Environment variables loaded from .env
                Datasource "db": MySQL database "testdb" at "localhost:3306"

                ✔ Introspected 1 model and wrote it into prisma\schema.prisma in 79ms

                Run prisma generate to generate Prisma Client.


        查看 prisma\schema.prisma 文件,内容如下:

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

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

            model user {
                id         Int       @id @default(autoincrement())
                username   String    @db.VarChar(50)
                password   String?   @db.VarChar(255)
                age        Int?
                createtime DateTime? @db.Timestamp(0)
            }


        可以看到  prisma\schema.prisma 文件里生成了 user 表的数据模型。

    4) 生成数据库基线 (Baseline)

        基线 (Baseline)是指初始化一个数据库的迁移记录。数据库的表结构可能因为业务需要而多次修改,可以使用 Baseline 技术,记录下表结构多次修改之间的差别。

        创建一个迁移目录 prisma/migrations/0_init,我们将使用 0_init 作为首次迁移的名称,命令如下:

            $ mkdir -p prisma/migrations/0_init

                ...

            注:-p 将在自动创建路径中不存在的中间路径。

        使用 prisma migrate diff 命令生成迁移文件,格式如下:
    
            $ npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql

                ...

            参数说明:

                --from-empty:假设从中迁移的数据模型为空
                --to-schema-datamodel:使用数据源块中 URL 的当前数据库状态
                --script:输出 SQL 脚本


6. 读写数据库

    在读写数据库的一个表之前,需要确保已经创建了这个表的 prisma 数据模型,并且要安装好 Prisma Client,Prisma Client 提供常用的数据库 CRUD 方法: create、update、delete、findUnique、findMany 等。

    安装 Prisma Client,命令如下:

        $ npm install @prisma/client

            ...

    读取 Prisma 架构并生成 Prisma Client 库,命令如下:

        $ npx prisma generate

            Environment variables loaded from .env
            Prisma schema loaded from prisma\schema.prisma

            ✔ Generated Prisma Client (v5.5.2) to .\node_modules\@prisma\client in 55ms

            Start using Prisma Client in Node.js (See: https://pris.ly/d/client)
            ```
            import { PrismaClient } from '@prisma/client'
            const prisma = new PrismaClient()
            ```
            or start using Prisma Client at the edge (See: https://pris.ly/d/accelerate)
            ```
            import { PrismaClient } from '@prisma/client/edge'
            const prisma = new PrismaClient()
            ```

            See other ways of importing Prisma Client: http://pris.ly/d/importing-client


    示例,创建 app/api2/route.js 文件,内容如下:

        import { NextResponse } from 'next/server';
        import { PrismaClient } from '@prisma/client'

        const prisma = new PrismaClient();

        export async function GET(request) {

            // By unique identifier
            let user = await prisma.user.findUnique({
                where: {
                    id: 2,
                },
            })
            //console.log(user);

            return NextResponse.json(user, { status: 200 });
        }

        export async function POST(request) {

            let user = await prisma.user.create({
                data: {
                    username: request.get('username'),
                    password: request.get('password'),
                    age: request.get('age'),
                    createtime: time()
                },
            })
            //console.log(user);

            return NextResponse.json(user, { status: 200 });
        }


    运行 furniture-service 项目,在 postman 上用 POST 方法访问 http://localhost:3000/api2,HTTP 请求的 Body 类型为 raw(JSON 格式),内容如下:

        {"username":"user","password":"abcdef","age": 99}

    返回结果为:

        {
            "id": 2,
            "username": "user",
            "password": "abcdef",
            "age": 99,
            "createtime": "2023-11-04T12:27:47.000Z"
        }


    浏览器访问 http://localhost:3000/api2, 显示结果如下:

        {"id":2,"username":"user","password":"abcdef","age":99,"createtime":"2023-11-04T12:27:47.000Z"}


标签:Node,...,prisma,Prisma,Next,user,js,schema
From: https://www.cnblogs.com/tkuang/p/17809971.html

相关文章

  • 前端学习-JavaScrip学习-js基础01
    学习教程:黑马程序员视频链接JS简介JS组成JavaScrip=ECMAscript(语言基础)+webAPIwebAPI=BOM+DOM资料查询网站:MDN<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="......
  • js tab跟随滑动切换tab
    js:letanchors=document.querySelectorAll("div[data-anchor-index]");letobserver=newIntersectionObserver((entries)=>{entries.forEach((entry)=>{if(entry.isIntersecting){letseq=Number(entry.target.ge......
  • JSONArray 分页
    publicJSONArraydatePageSize(IntegerpageNo,IntegerpageSize,JSONArraydata){JSONArraynewDate=newJSONArray();Integercounts=data.size();//获取数据总数Integerstart=(pageNo-1)*pageSize;//获取开始值Integerend=(pageNo)*p......
  • JS 工具函数
    1、校验数据类型exportconsttypeOf=function(obj){returnObject.prototype.toString.call(obj).slice(8,-1).toLowerCase()}示例:typeOf('树哥')//stringtypeOf([])//arraytypeOf(newDate())//datetypeOf(null)//nulltypeOf(true)//boolea......
  • java开发,json转list集合,原生实现
    java是一门面象对象的语言,对象需要先定义,但是在外理网络请求时候会用到json转成java对象,虽然现代开发框架中也提供了很多工具和方法直接转换,但是作为学习者了解一下底层实现,更能灵活变通现在有一个json格式如下{"list":[{"name":"Tom","sex":"b......
  • 二十六、QT发送http请求并解析返回的json数据
    1.使用的模块和类模块:network类:QNetworkAccessManager、QNetworkRequest、QNetworkReply、QJsonDocument、QJsonObject、QJsonArrayQSslSocket::sslLibraryBuildVersionString();:查看当前使用的ssl版本,访问HTTPS时需要使用、复制libcrypto-1_1-x64.dll和libssl-1_1......
  • 【2023最新】超详细!!!新商盟卷烟js逆向_包括验证码错误问题
    前言新商盟卷烟密码js逆向密码加密好解决,但是多次请求,还会有一个验证码这个时候就会请求失败所以验证码问题我也会解决1抓包先模拟登录,抓到返回表单的包2搜素加密字段输入加密的字段,搜索js文件打断点调试3断点调试在可疑的字段处打上断点再次输入进行调试调......
  • 两天实现思维导图的协同编辑?用Yjs真的可以
    最近使用Yjs给自己开源的一个思维导图加上了协同编辑的功能,得益于该框架的强大,一直觉得很复杂的协同编辑能力没想到实现起来异常的简单,所以通过本文来安利给各位。要实现协同编辑,目前主要有两种算法,一是OT(OperationalTransformation),二是CRDT(Conflict-freeReplicatedDataT......
  • nuxtjs2.x server 和client的数据共享?
    对于在Nuxt.js中实现服务器和客户端数据共享的需求,你可以考虑使用Vuex来管理共享数据。Vuex是一个专门为Vue.js应用程序开发的状态管理模式。首先,确保你的项目已经安装了Vuex。如果没有安装,你可以使用以下命令进行安装:npminstallvuex创建一个Vuexstore:在你的Nuxt.js项目中,创建......
  • node版本依赖报错那些事儿
    前言昨天还能跑的的项目,今天就歇菜了第一步删除大法依赖问题,那就把.lock/node_modules删除重新装第二步如果重装不好使,那就各种降低版本尝试遇到这样的有两种方式1、npmi--force/npmi--legacy-per-deps 2、一开始我用了第一种!但是有各......