如何保存和检索图像 to/from mysql?
How to save & retrive image to/from mysql?
两部分问题。
第 1 部分:
我正在将图像上传到我的服务器并想将它保存到我的数据库中。
到目前为止:
table:
解析器:
registerPhoto: inSequence([
async (obj, { file }) => {
const { filename, mimetype, createReadStream } = await file;
const stream = createReadStream();
const t = await db.images.create({
Name: 'test',
imageData: stream ,
});
},
])
正在执行查询:
Executing (default): INSERT INTO `images` (`Id`,`imageData`,`Name`) VALUES (DEFAULT,?,?);
但是什么都没有保存。
我是新手,我可能遗漏了一些东西但不知道是什么。
第二部分:
接下来是第 1 部分,假设我设法保存了图像,我如何读取它并将其发送回我的 FE?
编辑:我阅读了很多指南,将图像名称保存到数据库,然后将实际图像保存在文件夹中。这不是我想要的,想要将图像保存到数据库,然后能够从数据库中获取它并呈现它。
有两种方法可以将图像存储在 SQL 数据库中。您可以将实际图像存储在服务器上并将图像路径保存在 mySql 数据库中,或者使用图像创建一个 BLOB 并将其存储在数据库中。
这是一个方便的阅读 https://www.technicalkeeda.com/nodejs-tutorials/nodejs-store-image-into-mysql-database
这花了我一些时间,但我终于弄明白了。
第一步(保存到数据库):
必须获取整个流数据并像这样读取它:
export const readStream = async (stream, encoding = 'utf8') => {
stream.setEncoding('base64');
return new Promise((resolve, reject) => {
let data = '';
// eslint-disable-next-line no-return-assign
stream.on('data', chunk => (data += chunk));
stream.on('end', () => resolve(data));
stream.on('error', error => reject(error));
});
};
像这样使用:
const streamData = await readStream(stream);
在保存之前,我将流转为缓冲区:
const buff = Buffer.from(streamData);
最后保存部分:
db.images.create(
{
Name: filename,
imageData: buff,
Length: stream.bytesRead,
Type: mimetype,
},
{ transaction: param }
);
请注意,我添加了 Length
和 Type
参数,如果您想在 return 图像时 return 流,这是必需的。
步骤 2(检索图像)。
正如@xadm 多次说过的那样,你不能 return 来自 GRAPHQL 的图像,一段时间后我不得不接受这个事实,希望 graphql 将来能解决这个问题。
S 我需要做的是在我的 fastify 后端设置一个路由,将一个图像 ID 发送到这个路由,获取图像然后 return 它。
我对此有一些不同的方法,但最后我简单地 return 编辑了一个二进制文件,并在前面将其编码为 base64。
后端部分:
const handler = async (req, reply) => {
const p: postParams = req.params;
const parser = uuIdParserT();
const img = await db.images.findByPk(parser.setValueAsBIN(p.id));
const binary = img.dataValues.imageData.toString('binary');
const b = Buffer.from(binary);
const myStream = new Readable({
read() {
this.push(Buffer.from(binary));
this.push(null);
},
});
reply.send(myStream);
};
export default (server: FastifyInstance) =>
server.get<null, any>('/:id', opts, handler);
前端部分:
useEffect(() => {
// axiosState is the obj that holds the image
if (!axiosState.loading && axiosState.data) {
// @ts-ignore
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
// @ts-ignore
// eslint-disable-next-line no-plusplus
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
};
const blob = b64toBlob(axiosState.data, 'image/jpg');
const urlCreator = window.URL || window.webkitURL;
const imageUrl = urlCreator.createObjectURL(blob);
setimgUpl(imageUrl);
}
}, [axiosState]);
最后在 html 中:
<img src={imgUpl} alt="NO" className="imageUpload" />
其他:
对于任何尝试相同的人请注意,这不是最佳做法。
我发现的几乎每篇文章都将图像保存在服务器上,并在数据库中保存图像 Id 和其他元数据。对于这方面的确切利弊,我发现以下内容很有帮助:
Storing Images in DB - Yea or Nay?
如果出于某种原因我想在数据库中保存图像并最终解决了它,我专注于找出如何做。
你应该将图像保存在一个目录中,并将此图像的link保存在数据库中
两部分问题。
第 1 部分:
我正在将图像上传到我的服务器并想将它保存到我的数据库中。
到目前为止:
table:
解析器:
registerPhoto: inSequence([
async (obj, { file }) => {
const { filename, mimetype, createReadStream } = await file;
const stream = createReadStream();
const t = await db.images.create({
Name: 'test',
imageData: stream ,
});
},
])
正在执行查询:
Executing (default): INSERT INTO `images` (`Id`,`imageData`,`Name`) VALUES (DEFAULT,?,?);
但是什么都没有保存。
我是新手,我可能遗漏了一些东西但不知道是什么。
第二部分:
接下来是第 1 部分,假设我设法保存了图像,我如何读取它并将其发送回我的 FE?
编辑:我阅读了很多指南,将图像名称保存到数据库,然后将实际图像保存在文件夹中。这不是我想要的,想要将图像保存到数据库,然后能够从数据库中获取它并呈现它。
有两种方法可以将图像存储在 SQL 数据库中。您可以将实际图像存储在服务器上并将图像路径保存在 mySql 数据库中,或者使用图像创建一个 BLOB 并将其存储在数据库中。 这是一个方便的阅读 https://www.technicalkeeda.com/nodejs-tutorials/nodejs-store-image-into-mysql-database
这花了我一些时间,但我终于弄明白了。
第一步(保存到数据库):
必须获取整个流数据并像这样读取它:
export const readStream = async (stream, encoding = 'utf8') => {
stream.setEncoding('base64');
return new Promise((resolve, reject) => {
let data = '';
// eslint-disable-next-line no-return-assign
stream.on('data', chunk => (data += chunk));
stream.on('end', () => resolve(data));
stream.on('error', error => reject(error));
});
};
像这样使用:
const streamData = await readStream(stream);
在保存之前,我将流转为缓冲区:
const buff = Buffer.from(streamData);
最后保存部分:
db.images.create(
{
Name: filename,
imageData: buff,
Length: stream.bytesRead,
Type: mimetype,
},
{ transaction: param }
);
请注意,我添加了 Length
和 Type
参数,如果您想在 return 图像时 return 流,这是必需的。
步骤 2(检索图像)。
正如@xadm 多次说过的那样,你不能 return 来自 GRAPHQL 的图像,一段时间后我不得不接受这个事实,希望 graphql 将来能解决这个问题。
S 我需要做的是在我的 fastify 后端设置一个路由,将一个图像 ID 发送到这个路由,获取图像然后 return 它。
我对此有一些不同的方法,但最后我简单地 return 编辑了一个二进制文件,并在前面将其编码为 base64。
后端部分:
const handler = async (req, reply) => {
const p: postParams = req.params;
const parser = uuIdParserT();
const img = await db.images.findByPk(parser.setValueAsBIN(p.id));
const binary = img.dataValues.imageData.toString('binary');
const b = Buffer.from(binary);
const myStream = new Readable({
read() {
this.push(Buffer.from(binary));
this.push(null);
},
});
reply.send(myStream);
};
export default (server: FastifyInstance) =>
server.get<null, any>('/:id', opts, handler);
前端部分:
useEffect(() => {
// axiosState is the obj that holds the image
if (!axiosState.loading && axiosState.data) {
// @ts-ignore
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
// @ts-ignore
// eslint-disable-next-line no-plusplus
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
};
const blob = b64toBlob(axiosState.data, 'image/jpg');
const urlCreator = window.URL || window.webkitURL;
const imageUrl = urlCreator.createObjectURL(blob);
setimgUpl(imageUrl);
}
}, [axiosState]);
最后在 html 中:
<img src={imgUpl} alt="NO" className="imageUpload" />
其他: 对于任何尝试相同的人请注意,这不是最佳做法。 我发现的几乎每篇文章都将图像保存在服务器上,并在数据库中保存图像 Id 和其他元数据。对于这方面的确切利弊,我发现以下内容很有帮助:
Storing Images in DB - Yea or Nay?
如果出于某种原因我想在数据库中保存图像并最终解决了它,我专注于找出如何做。
你应该将图像保存在一个目录中,并将此图像的link保存在数据库中