前言:TypeORM 0.3以上版本弃用了getConnectionManager
、createConnection
等一系列api,使用 DataSource
代替原本的 Connection
详情查看 CHANGELOG.md
1. 解决代码更新时的报错
文件: pages/index.tsx
,实现数据库连接
import {GetServerSideProps, NextPage} from "next";
import {AppDataSource} from "@/src/data-source"
import {User} from "@/src/entity/User";
type Props = {
name: string
}
const Posts: NextPage = (props) => {
return (
你好 {props.name}
);
}
export default Posts;
export const getServerSideProps: GetServerSideProps = async (context) => {
// createConnection 被弃用,使用 initialize 创建连接
const connection = await dataSource.initialize()
return {
props: { name: 'Bumble' }
};
};
以上代码可以成功连接数据库,但是在开发环境中,代码更新时会出现以下报错
Cannot create a "default" connection because connection to the database already established.
错误信息提示您正在尝试创建一个名为"default"的连接,但因为已经建立了与数据库的连接,所以无法创建新连接。
因此需要加判断,判断是否已有连接,复用连接。
解决方法:在代码中增加判断
export const getServerSideProps: GetServerSideProps = async (context) => {
const UserRepository = AppDataSource.isInitialized
? AppDataSource.getRepository(User)
: (await AppDataSource.initialize()).getRepository(User);
return {
props: { name: 'Bumble' }
};
};
上述代码使用 isInitialized
判断是否已有连接,已有连接就使用getRepository
获取 User 实体的存储库,无连接则先建立连接再获取实体存储库。
2. 解决报错 no metadata for User
上述代码实现了数据库连接,接下来实现数据查询。
查询 User 表的数据,代码实现:
export const getServerSideProps: GetServerSideProps = async (context) => {
const UserRepository = AppDataSource.isInitialized
? AppDataSource.getRepository(User)
: (await AppDataSource.initialize()).getRepository(User);
// 使用 find() 就可以实现查询,但是此时会报错
const users = await UserRepository.find()
console.log(users)
return {
props: { name: 'Bumble' }
};
};
报错内容
error - EntityMetadataNotFoundError: No metadata for "User" was found.
错误原因 TypeORM 无法找到与 “User” 实体相关的元数据。
解决方法:添加与 “User” 实体相关的元数据
export const getServerSideProps: GetServerSideProps = async (context) => {
// @ts-ignore
const dataSource = new DataSource({
...AppDataSource.options,
entities: [User],
});
const UserRepository = dataSource.isInitialized
? dataSource.getRepository(User)
: (await dataSource.initialize()).getRepository(User);
const users = await UserRepository.find()
console.log(users) // 成功打印出 User 表的所有数据
return {
props: { name: 'Bumble' }
};
};
以上代码就可以成功打印出User表的所有数据了
3. 总结:完整代码优化
有多个实体时,代码会出现冗余,可以封装方法以优化代码。
以下是优化后的完整代码
import {GetServerSideProps, NextPage} from "next";
import {AppDataSource} from "@/src/data-source"
import {User} from "@/src/entity/User";
import {Post} from "@/src/entity/Post";
import {Comment} from "@/src/entity/Comment";
import {DataSource} from "typeorm";
type Props = {
name: string
}
const Posts: NextPage = (props) => {
return (
你好 {props.name}
);
}
export default Posts;
export const getServerSideProps: GetServerSideProps = async (context) => {
const UserRepository = await handleGetRepository(User)
const PostRepository = await handleGetRepository(Post)
const users = await UserRepository.find()
const posts = await PostRepository.find()
console.log(users, posts)
return {
props: {
name: 'Bumble'
}
};
};
const handleGetRepository = async (entity) => {
// @ts-ignore
const dataSource = new DataSource({
...AppDataSource.options,
entities: [User, Post, Comment],
});
return dataSource.isInitialized
? dataSource.getRepository(entity)
: (await dataSource.initialize()).getRepository(entity);
}