背景
在虚拟机里安装mysql,本地连接mysql获取数据。
用到的软件版本:centeos7.6, docker, mysql5.7, nextjs14, mysql2(npm)
先看下效果
数据库:
node端:
页面:
安装软件
centeos7.6
虚拟机用的 virtualBox,大家找一下centeos7.6的镜像,安装一下。
安装后设置一下网络和端口映射
安装docker
yum 包更新到最新
sudo yum update
安装需要的软件包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
设置yum源为阿里云
sudo yum-config-manager --add-repo <http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo>
安装docker
sudo yum install docker-ce
# 启动
sudo systemctl start docker
安装后查看docker版本
docker -v
通过docker安装mysql
拉取mysql镜像
docker pull mysql:5.7
创建容器
docker run -di --name=msql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin mysql:5.7
docker run -id --name=m_ysql -p 3306:3306 \
-v /root/mysql/logs:/logs \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
docker cp m_ysql:/etc/mysql/conf.d .
-e 代表添加环境变量 MYSQL_ROOT_PASSWORD 是root用户的登陆密码
docker查看启动的容器
docker ps
如果下次启动的时候是3306 -> 3306可以通过下面的命令修改,先暂停容器
docker run -e MYSQL_ROOT_PASSWORD=123456 -p 0.0.0.0:3306:3306 image_name
接下来先试试远程连接是否能成功
远程链接mysql
mysql -h 127.0.0.1 -P 3306 -u root -p
如果mysql未找到先查一下如何安装mysql
出现这个表示连接成功
nextjs连接mysql
先看一下目录结构
db/index.ts:
import mysql from 'mysql2';
// 创建数据库连接池
const pool = mysql.createPool({
host: '127.0.0.1',
port: 3306,
user: 'root',
password: '123456',
database: 'knowledge',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
});
// 导出连接池
export default pool.promise();
query-utils.ts
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { ResultSetHeader } from 'mysql2/promise';
import pool from './connection';
export async function SelectQuery<T>(
queryString: string,
params?: any[]
): Promise<Partial<T[]>> {
let connection;
try {
connection = await pool.getConnection();
const [results] = await connection.execute(queryString, params);
return results as T[];
} catch (error) {
console.error(error);
throw error;
} finally {
if (connection) {
connection.release();
}
}
}
export async function ModifyQuery(
queryString: string,
params?: any[]
): Promise<ResultSetHeader> {
let connection;
try {
connection = await pool.getConnection();
const [result] = await connection.execute(queryString, params);
return result as ResultSetHeader;
} catch (error) {
console.error(error);
throw error;
} finally {
if (connection) {
connection.release();
}
}
}
db/index.ts
import * as employees from './employees/index';
const db = {
employees,
};
export default db;
db/employees/index.ts
/* eslint-disable @typescript-eslint/no-unsafe-return */
import type { RowDataPacket } from 'mysql2/promise';
import { SelectQuery } from '../query-utils';
export interface IEmployeesRow extends RowDataPacket {
id: number;
name: string;
salary: number;
}
export function getAll() {
return SelectQuery<IEmployeesRow>('SELECT * FROM employees;');
}
export function getOne(id: number) {
const queryString = 'SELECT * FROM employees WHERE id = ?;';
return SelectQuery<IEmployeesRow>(queryString, [id]);
}
页面上获取数据
app/employees/page.tsx
import Link from 'next/link';
import { getAll, type IEmployeesRow } from '~/db/employees/index';
export default async function Page() {
const req = await getAll();
console.log('req:::', req);
return (
<>
{req?.map((item: IEmployeesRow | undefined) => {
return (
<Link key={item?.id} href={`/employees/${item?.id}`}>
{item?.name}
</Link>
);
})}
</>
);
}
employees/[id]/page.tsx
import { getOne } from '~/db/employees/index';
export default async function Page({ params }: { params: { id: string } }) {
const req = await getOne(Number(params.id));
console.log('req:::', req);
return (
<>
<p>{req?.[0]?.name}</p>
<p>{req?.[0]?.salary}</p>
</>
);
}
这样可以从数据库读取到数据了,接下来看看drizzle-orm如何连接mysql及获取数据
更新一下测试mac下是否连接成功的例子
我的A1芯片,很久没看这块了,最近继续看看
本地先安装好docker,前端的依赖和上面的一样
拉取mysql
docker run --platform linux/amd64 -d --name=msql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin mysql:5.7
启动一个sql
docker run -id --name=ec_mysql -p 3306:3306 \
-v ~/mysql/logs:/logs \
-v ~/mysql/data:/var/lib/mysql \
-v ~/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
测试连接
index.ts:
import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
if (
!process.env.MYSQL_HOST ||
!process.env.MYSQL_POST ||
!process.env.MYSQL_USER ||
!process.env.MYSQL_PASSWORD ||
!process.env.MYSQL_DATABASE
) {
throw new Error('no mysql config');
}
// 创建数据库连接池
const poolConnection = mysql.createPool({
host: process.env.MYSQL_HOST,
port: Number(process.env.MYSQL_POST),
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
});
export const db = drizzle(poolConnection);
.env.example
# DateBase
MYSQL_HOST=localhost
MYSQL_POST=3306
MYSQL_USER=root
MYSQL_PASSWORD=xxx
MYSQL_DATABASE=xxx
db-test.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { sql } from 'drizzle-orm';
import { db } from '~/db'; // 引入你配置的 Drizzle ORM 数据库连接模块
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
// 尝试执行一条简单的 SQL 查询,例如获取当前时间
const result = await db.execute(sql`SELECT NOW() AS currentTime`)// 假设SQLWrapper是一个类,需要实例化
// 返回成功的响应
res.status(200).json({ message: 'Database connected successfully!', result });
} catch (error) {
// 捕获错误并返回失败的响应
console.error('Database connection failed:', error);
res.status(500).json({ message: 'Database connection failed.', error: String(error) });
}
}
可以看到
初始化表
首先定义一个schema,然后通过脚本来执行
先看下脚本
"migrations:generate": "drizzle-kit generate:mysql --config=drizzle.config.ts",
"db:push": "drizzle-kit push:mysql --config=drizzle.config.ts",
第一个生成过程,第二个推送到数据库
drizzle.config.ts
用于配置链接数据,返回一个链接后的数据库对象
import type { Config } from 'drizzle-kit';
if (
!process.env.MYSQL_HOST ||
!process.env.MYSQL_POST ||
!process.env.MYSQL_USER ||
!process.env.MYSQL_PASSWORD ||
!process.env.MYSQL_DATABASE
) {
throw new Error('no mysql config');
}
export default {
schema: './db/schema/index.ts',
out: './db/migrations',
driver: 'mysql2',
dbCredentials: {
host: process.env.MYSQL_HOST,
port: Number(process.env.MYSQL_POST),
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
},
} satisfies Config;
然后db/schema/index.ts里导出的是schema对象,可以理解成sql的对象
import { sql } from 'drizzle-orm';
import {
int, mysqlTable, timestamp, index, uniqueIndex,
} from 'drizzle-orm/mysql-core';
const cart = mysqlTable(
'cart',
{
id: int('id').autoincrement().primaryKey().notNull(),
userId: int('userId').notNull(),
productId: int('productId'),
quantity: int('quantity'),
checked: int('checked'),
createTime: timestamp('createTime').default(sql`now()`).notNull(),
updateTime: timestamp('updateTime').default(sql`now()`).notNull(),
},
// 调整索引命名以保持一致
(cart) => ({
uniqueUserIdIndex: uniqueIndex('mmall_cart__user_id__unique').on(
cart.userId
),
userIdIndex: index('mmall_cart__user_id__idx').on(cart.userId),
})
);
export default cart;
export {cart}
在对应的数据库中就会创建一个cart的表
插入数据
初始化表后一般都会有一些数据,主要通过db.insert(mmallCategory).values({xxx})
来插入数据
await db.insert(schema).values({
userId: 21, // 用户ID,假设是1
productId: 26, // 商品ID,假设是123
quantity: 1, // 商品数量,假设是2
checked: 1, // 是否选中,假设是选中(1代表选中,0代表未选中)
createTime: new Date(),
updateTime: new Date(),
});
schema为上面我们定义的schema,然后写入对应的值就行。