如何使用 JDBC 库在 Google 云 SQL 中存储 Blob
How to Store Blob in Google Cloud SQL Using JDBC Library
我正在使用 Google Apps 脚本,它在启动时向用户显示 HTML 页面。我在网页上包含了一个文件输入字段,这样就可以上传各种格式的 PDF 和图像。接下来,我想将上传的文件 return 通过 运行 google.script.run 上传到 Google 脚本,然后在函数内部将文件作为 Blob 存储在我的Google 云 SQL 数据库。
到目前为止,这是我的一些代码:
HTML:
<input type="file" id="cert">
<input type="button" id="btnCheck" onclick="readFiles()" value="Read Files">
JavaScript:
function readFiles() {
var x = document.getElementById("cert");
if ('files' in x) {
if (x.files.length != 0) {
for (var i = 0, f; f = x.files[i]; i++) {
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
google.script.run.storeFile(e.target.result);
};
})(f);
reader.readAsBinaryString(f);
}
}
}
}
Google 脚本:
function storeFile(f) {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);
var results = stmt.executeQuery('select * from my_table');
results.moveToInsertRow();
var newBlob = conn.createBlob();
var uBlob = Utilities.newBlob(f, 'application/pdf');
newBlob.setBytes(1, uBlob.getBytes());
results.updateBlob('file', newBlob);
results.insertRow();
results.moveToCurrentRow();
results.close();
stmt.close();
}
现在解决手头的问题。此时数据已存储在数据库中,但似乎已附加了很多额外信息,当我使用 MySQL Workbench 将数据导出到文件时(在这种情况下我是使用 PDF 进行测试)文件无法打开。
如果我使用 MySQL Workbench 手动将文件插入数据库,数据大小正确,可以导出,并且可以正常打开。我注意到,如果我打印 uBlob.getBytes() 的大小,则值为 754244,如果我打印 uBlob.getDataAsString() 的大小,则值为 528004。原始文件大小为 516kB(~528384 ).看原始数据肯定有相似之处,观察下。
当使用 MySQL Workbench 存储时(前 20 行):
%PDF-1.3
%âãÏÓ
1 0 obj
>
endobj
2 0 obj
>
stream
ÿØÿà JFIF ,, ÿÛ
使用 Google Apps 脚本存储时(前 20 行):
%PDF-1.3
%âãÃÃ
1 0 obj
>
endobj
2 0 obj
>
stream
ÿÃÿà JFIF ,, ÿà Â
我可以发送到 Google 脚本函数的内容有限,但收到的二进制字符串似乎是合法的。 newBlob 是一个 JdbcBlob,我使用 setBytes 函数对其进行设置,其第二个参数的类型为 BlobSource,因此我使用 Utilities.newBlob 创建一个 Blob 用作 BlobSource,并将网页中的文件二进制字符串作为其输入。 results.updateBlob 的第二个参数是 JdbcBlob 类型,所以我在这里提供 newBlob 作为输入。
非常感谢您的帮助,因为我现在很困惑。谢谢!
好的,看来我找到了解决办法!
使用函数 btoa(...) 将 FileReader 的二进制字符串结果编码为 Base64。然后在 Google 脚本中使用 Utilities.base64Decode(...) 将数据作为 Blob 获取。
JavaScript:
function readFiles() {
var x = document.getElementById("cert");
if ('files' in x) {
if (x.files.length != 0) {
for (var i = 0, f; f = x.files[i]; i++) {
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
google.script.run.storeFile(btoa(e.target.result));
};
})(f);
reader.readAsBinaryString(f);
}
}
}
}
Google 脚本:
function storeFile(f) {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);
var results = stmt.executeQuery('select * from my_table');
results.moveToInsertRow();
var newBlob = conn.createBlob();
newBlob.setBytes(1, Utilities.base64Decode(f));
results.updateBlob('file', newBlob);
results.insertRow();
results.moveToCurrentRow();
results.close();
stmt.close();
}
我正在使用 Google Apps 脚本,它在启动时向用户显示 HTML 页面。我在网页上包含了一个文件输入字段,这样就可以上传各种格式的 PDF 和图像。接下来,我想将上传的文件 return 通过 运行 google.script.run 上传到 Google 脚本,然后在函数内部将文件作为 Blob 存储在我的Google 云 SQL 数据库。
到目前为止,这是我的一些代码:
HTML:
<input type="file" id="cert">
<input type="button" id="btnCheck" onclick="readFiles()" value="Read Files">
JavaScript:
function readFiles() {
var x = document.getElementById("cert");
if ('files' in x) {
if (x.files.length != 0) {
for (var i = 0, f; f = x.files[i]; i++) {
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
google.script.run.storeFile(e.target.result);
};
})(f);
reader.readAsBinaryString(f);
}
}
}
}
Google 脚本:
function storeFile(f) {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);
var results = stmt.executeQuery('select * from my_table');
results.moveToInsertRow();
var newBlob = conn.createBlob();
var uBlob = Utilities.newBlob(f, 'application/pdf');
newBlob.setBytes(1, uBlob.getBytes());
results.updateBlob('file', newBlob);
results.insertRow();
results.moveToCurrentRow();
results.close();
stmt.close();
}
现在解决手头的问题。此时数据已存储在数据库中,但似乎已附加了很多额外信息,当我使用 MySQL Workbench 将数据导出到文件时(在这种情况下我是使用 PDF 进行测试)文件无法打开。
如果我使用 MySQL Workbench 手动将文件插入数据库,数据大小正确,可以导出,并且可以正常打开。我注意到,如果我打印 uBlob.getBytes() 的大小,则值为 754244,如果我打印 uBlob.getDataAsString() 的大小,则值为 528004。原始文件大小为 516kB(~528384 ).看原始数据肯定有相似之处,观察下。
当使用 MySQL Workbench 存储时(前 20 行):
%PDF-1.3 %âãÏÓ 1 0 obj > endobj 2 0 obj > stream ÿØÿà JFIF ,, ÿÛ
使用 Google Apps 脚本存储时(前 20 行):
%PDF-1.3 %âãÃà 1 0 obj > endobj 2 0 obj > stream ÿÃÿà JFIF ,, ÿà Â
我可以发送到 Google 脚本函数的内容有限,但收到的二进制字符串似乎是合法的。 newBlob 是一个 JdbcBlob,我使用 setBytes 函数对其进行设置,其第二个参数的类型为 BlobSource,因此我使用 Utilities.newBlob 创建一个 Blob 用作 BlobSource,并将网页中的文件二进制字符串作为其输入。 results.updateBlob 的第二个参数是 JdbcBlob 类型,所以我在这里提供 newBlob 作为输入。
非常感谢您的帮助,因为我现在很困惑。谢谢!
好的,看来我找到了解决办法!
使用函数 btoa(...) 将 FileReader 的二进制字符串结果编码为 Base64。然后在 Google 脚本中使用 Utilities.base64Decode(...) 将数据作为 Blob 获取。
JavaScript:
function readFiles() {
var x = document.getElementById("cert");
if ('files' in x) {
if (x.files.length != 0) {
for (var i = 0, f; f = x.files[i]; i++) {
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
google.script.run.storeFile(btoa(e.target.result));
};
})(f);
reader.readAsBinaryString(f);
}
}
}
}
Google 脚本:
function storeFile(f) {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.createStatement(Jdbc.ResultSet.TYPE_SCROLL_INSENSITIVE, Jdbc.ResultSet.CONCUR_UPDATABLE);
var results = stmt.executeQuery('select * from my_table');
results.moveToInsertRow();
var newBlob = conn.createBlob();
newBlob.setBytes(1, Utilities.base64Decode(f));
results.updateBlob('file', newBlob);
results.insertRow();
results.moveToCurrentRow();
results.close();
stmt.close();
}