学习一 后端开发
在后端开发中,通常会有以下几个层次:
- 数据层(Data Layer):直接与数据库交互,负责数据的存储、检索和管理。(
NEON) - 数据访问层(Data Access Layer):定义了访问和操作数据的接口和逻辑。将底层数据库的具体操作细节隐藏起来,对外提供一组通用的接口或方法来访问数据。 (
Drizzle) - 业务逻辑层(Business Logic Layer):处理应用程序的核心业务逻辑,如用户认证、数据处理等。
- 表示层(Presentation Layer):通常指的是 API 网关或后端服务,它们处理来自前端的请求,并返回相应的数据或视图。
- 接口层(API Layer):定义了前后端交互的接口,如 RESTful API 或 GraphQL。
1.数据库和数据库查询系统MySQL
数据库是一个系统化的数据集合,它允许用户存储、检索和管理数据。SQL是数据库查询语言,它用于执行各种数据库操作,如查询、更新和管理数据。 MySQL是众多数据库系统中最常用的一种。不同的数据库系统虽然在某些 SQL 语法和功能上有所不同,但都遵循 SQL 标准的基本规则。
以下是一些相关的数据库术语:
-
表(Table) :
- 表是数据库中存储数据的主要结构,它由行和列组成,类似于Excel中的表格。
-
行(Row)/记录(Record) :
- 表中的每行数据称为一条记录,它包含了所有列的数据。
-
列(Column)/字段(Field) :
- 表中的每列称为一个字段,用于存储特定类型的数据,如整数、字符串、日期等。
-
主键(Primary Key) :
- 主键是表中的一个或多个字段,其值唯一标识表中的每一行记录。
-
外键(Foreign Key) :
- 外键是一个表中的字段,它指向另一个表的主键,用于建立两个表之间的关系。
-
索引(Index) :
- 索引是一种特殊的数据库结构,用于加快查询速度。
-
数据类型(Data Type) :
- 数据类型定义了列可以存储的数据类型,如整数(INT)、小数(DECIMAL)、字符串(VARCHAR)、日期(DATE)等。
-
约束(Constraint) :
- 约束用于限制列中的数据,保证数据的完整性和准确性,如非空(NOT NULL)、唯一(UNIQUE)等。 下载SQLynx 打开chat GPT 把建表的信息和我们的要求对AI提问 复制生成的代码即可
2.应用程序编程接口API(RESTful风格+JSON数据格式)
API API(Application Programming Interface)是指应用程序编程接口,包括在操作系统中的动态链接库文件例如dll\so,或者基于TCP层的socket连接,用来提供预定义的方法和函数,调用者无需访问源码和理解内部原理便可实现相应功能。而当前通常指通过HTTP协议传输的web service技术。
API在概念上和语言无关,理论上具有网络操作能力的所有编程语言都可以提供API服务。Java、PHP、Node甚至C都可以实现web API,都是通过响应HTTP请求并构造HTTP包来完成的,但是内部实现原理不同。
RESTful RESTful规定了URL和HTTP Method的使用,是一种对基于HTTP的应用设计风格,只是提供了一组设计原则和约束条件,而不是一种标准。它尽可能复用HTTP特性来规范软件设计,甚至提高传输效率,用更简洁、清晰、高效的方式实现同样的需求。
JSON JSON是最主流的网络传输格式,定义请求或者返回对象的结构,以及该如何针对不同的情况返回不同的HTTP 状态码。它是一种用于数据交换的轻量级格式。使用键值对来表示对象,并使用有序列表来表示数组。键是字符串,必须用双引号包围,值可以是字符串、数字、布尔值、数组、对象或 null
JSON 格式易于人类阅读和编写,也易于机器解析和生成,广泛应用于Web开发中的数据传输、配置文件和数据存储。需要注意的是,JSON 中的键和值必须遵循严格的语法规则,如键名必须是字符串,不能包含多余的逗号等。
学习 杂记
VSCode小技巧
- ctrl + space vs提示快捷键
- shift >reload window 刷新vscode
- ctrl + shift + p 頂部搜索框
- rfec 在空白页面中新建函数组件(react function export component)
Next.js
- 文件路径直接映射到 URL 路径
- 文件命名有以下方式
- pages/api/route.js:处理 /api/route 请求
- pages/api/route/[param].js:处理 /api/route/[param] 请求,并将 param 作为参数
- pages/api/route/[...slug].js:处理 /api/route/ 下的所有请求,如 /api/route/a/b/c2。
- 被(小括号)包裹的文件夹不会参与路由的创建(文件名不会出现在url中)
- 被[[双方括号包裹]]的文件夹约定文件夹内成员拥有所有必要的路线身份验证
实战数据库
使用 Neon 提供的 PostgreSQL 数据库服务的同时,利用 Drizzle ORM 来管理数据库交互。可以让你使用一个 JSON 文件快速创建一个完整的 RESTful API 服务器,帮助你在没有后端服务器的情况下进行前端开发和测试。
Neon Postgres是一个完全托管的无服务器Postgres服务。
NEON(数据库)连接配置
使用GitHub 账户登录并新建项目、数据库
项目名称:这是您项目的描述性名称。它可以是您的应用程序名称或客户名称。“Dashboard”。
Postgres 版本: 您选择了 Postgres 版本 16。Neon 应该会自动提供最新的稳定版 PostgreSQL,确保您拥有最新的功能和安全补丁。
数据库名称: 您将数据库命名为“neondb”。这是您在 Neon 中引用数据库的名称。
云服务提供商: 您可以选择 AWS、Azure 或其他提供商。您选择了 AWS,这是一个因其全球覆盖和性能而受欢迎的选择。
区域: 您选择了“亚洲(新加坡)”作为您的区域。这很重要,因为它决定了您的数据库将被物理放置在哪里,这可能影响延迟和数据居住地要求的合规性。
高级选项: 这部分通常包括额外的配置选项,如 VPC 设置、安全组、备份计划等。您可以根据具体需求自定义这些选项。
新建数据库(我的面板与up的面板不同,流程是自己摸索的)
侧边栏中选择 Dashboard ,在Connection Details 中打开Database的下拉框,新建数据库
项目中安装依赖
npm i drizzle-orm @neondatabase/serverless
控制台报错,错误 ERESOLVE 表示 npm 在解析依赖树时遇到了问题,修改package.json中react的版本 "18.3.1"
npm i -D drizzle-kit
初始化驱动程序并执行查询
保存NEXT_PUBLIC_DATABASE_URL_CONFIG变量
在之前的.env.local文件中保存,值是neon仪表盘中Connection Details里的Connection string
NEXT_PUBLIC_DATABASE_URL_CONFIG = postgresql://neondb_owner ...(已省略)
Drizzle 配置(数据库系统)
已经安装,所以跳过安装依赖
在根目录下新建configs文件夹,文件夹内新建schema.ts文件:用于创建数据库,在其中定义类型、字段名,帮助我们编写查询
import { pgTable, serial, varchar, text, timestamp } from "drizzle-orm/pg-core";
export const JsonForms = pgTable("jsonforms", {
//serial是自增的整数 primaryKey是主键
id: serial("id").primaryKey(),
// 定义jsonform字段 类型为text
jsonform: text('jsonform').notNull(),
createBy: varchar("createBy").notNull(),
createdAt: varchar("createdAt").notNull(),
});
在根目录新建drizzle.config.ts文件
这里使用环境变量不能直接被访问,需要把整个url字符串贴过来
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./configs/schema.ts",
out: "./drizzle.config.ts",
dialect: 'postgresql',
dbCredentials: {
url: 'postgresql://neondb_owner:(已省略)'
},
});
配置configs/index.ts文件
import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
import * as schema from './schema';
const sql = neon(process.env.NEXT_PUBLIC_DATABASE_URL_CONFIG!);
export const db = drizzle({ client: sql, schema });
在package.json中添加脚本
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio"
},
运行
配置package.json之后运行 npm run db:push将本地的数据库迁移推送到远程数据库(schema.ts中内容每有更改都必须推送)
接着运行npm run db:studio 打开 Drizzle ORM 的工作室(studio)。这个命令提供了一个交互式的界面,允许开发者执行和管理数据库相关的任务,如查看数据库架构、生成迁移、推送迁移等。
实现表单创建功能(AI)
前端页面完成点击创建form事件 > 应用dialog组件弹出提示框及textarea > 使用 openAI
使用openAI
- 获取API密钥地址,(鉴权 key,允许一个用户生成多个,每个都可以与 openai 联动,简单来说,你可以基于这个创建机器人,或者创建脚本服务,批量帮你完成一系列事情)添加到环境变量文件,设置环境变量被gitignore忽略。
NEXT_PUBLIC_OPENAI_API_KEY='your apiKey'
- 命令行安装 OpenAI 客户端库
npm install openai - 引入 OpenAI 客户端库 ( 在configs文件夹下添加AIModal.ts文件
- 在AIModal.ts中实例化 OpenAI 客户端,并调用 OpenAI API
import{OpenAI} from 'openai';
//设置表单基本内容及格式
const PROMPT = 'on the basis of description please give form in json format with form title,form subheading withform having Form field,Form name, placeholder name ,and form label,fieldType,field required in json format'
//传入密钥及请求地址
const apiClient = new OpenAI({
apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
dangerouslyAllowBrowser: true, // 允许浏览器使用
baseURL: 'https://api.chatanywhere.tech' //baseURL` 是 OpenAI API 的基础 URL,指向 API 请求的地址。
});
//调用 OpenAI API,传入用户需求,return返回值
export async function AiChatSession(userInput: string) {
const completion = await apiClient.beta.chat.completions.parse({
model: 'gpt-3.5-turbo',
messages: [ { role: "user", content: "Discription:" + userInput + PROMPT } ],
});
console.log(completion.choices[0].message.content);
return completion;
}
beta.chat.completions.parse 是一个 API 调用,用于生成聊天完成结果。
- 获取返回值
//createForm文件中,提交input内容的onCreateForm函数内调用
const onCreateForm = async () => {
AiChatSession(input).then((res) => {
console.log(res.choices[0].message.content, 'result')
//收到AI返回的json格式的表单
})
}
API参数 API文档参考
messages 参数
-
类型:数组
-
内容:包含对话消息的对象,每个对象代表一条消息。
-
格式:每个对象有两个字段:
-
role:消息的角色,常见的角色包括:'user':表示用户发送的消息。'system':表示系统消息,通常用于设定对话的背景或规则。'assistant':表示 AI 助理的回复。
-
content:消息的内容,即文本字符串。
-
model 参数
-
类型:字符串
-
内容:指定使用的 OpenAI 模型的名称。
-
说明
:不同的模型有不同的能力和性能,常用的模型包括:
gpt-3.5-turbo:一个高效的语言模型,适用于各种对话和生成任务。text-davinci-003:功能更强大的模型,适用于更复杂和高级的任务。
将返回的JSON数据格式的表单存储到数据库
if (result) {
// 数据库操作 确保与configs中schema文件中定义的表命名与结构一致
const resp = await db.insert(JsonForms).values({
jsonform:result,
createBy:user?.primaryEmailAddress?.emailAddress,
createdAt:moment().format('YYYY-MM-DD')
}).returning({id:JsonForms.id});
console.log(resp,'resp')
setLoading(false)//进程中使按钮不可用
}
将生成的表单id转发给表单页
新建forms文件夹(与dashboard同级),创建一个[formId]动态路由文件夹,page.tsx为主页面 在onCreateForm函数中获取到数据库返回的id后添加跳转,为创建按钮添加动态loading
const route = useRouter()
if (resp[0].id) {
route.push(`/forms/${resp[0].id}`)
}
<Button disabled={loading} onClick={onCreateForm} className=' text-white px-4 py-2 rounded-md'>{loading ? <Loader2 className='animate-spin'/> : 'Create'}</Button>
未完待续...