站长工具在线免费观看一个新产品的营销方案
以下是使用 JDBC 操作 BLOB(二进制大对象)和 CLOB(字符大对象) 的完整示例代码,包含 插入、读取 操作及详细注释:
1. 数据库表结构(MySQL 示例)
CREATE TABLE files (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255),content BLOB, -- 存储二进制文件(如图片、PDF)text_content CLOB -- 存储大文本(如长文章)
);
2. Java 代码示例
import java.io.*;
import java.sql.*;public class BlobClobExample {// 数据库连接参数private static final String URL = "jdbc:mysql://localhost:3306/mydatabase";private static final String USER = "root";private static final String PASSWORD = "your_password";public static void main(String[] args) {Connection conn = null;try {// 1. 加载驱动并获取连接conn = DriverManager.getConnection(URL, USER, PASSWORD);conn.setAutoCommit(false); // 关闭自动提交,启用事务// 2. 插入 BLOB 和 CLOB 数据insertBlobAndClob(conn, "test_image.jpg", "large_text.txt");// 3. 查询并读取 BLOB 和 CLOB 数据readBlobAndClob(conn, 1);// 4. 提交事务conn.commit();System.out.println("操作成功,事务已提交!");} catch (SQLException e) {System.out.println("发生异常,事务回滚!");try {if (conn != null) conn.rollback();} catch (SQLException ex) {ex.printStackTrace();}e.printStackTrace();} finally {try {if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}}// ------------------------ 插入 BLOB 和 CLOB 数据 ------------------------private static void insertBlobAndClob(Connection conn, String blobFilePath, String clobFilePath) throws SQLException, IOException {// SQL 语句String sql = "INSERT INTO files (name, content, text_content) VALUES (?, ?, ?)";try (PreparedStatement pstmt = conn.prepareStatement(sql)) {// 设置 name 参数pstmt.setString(1, "Sample File");// 设置 BLOB 参数(二进制文件)try (FileInputStream fis = new FileInputStream(blobFilePath)) {pstmt.setBinaryStream(2, fis, (int) new File(blobFilePath).length());}// 设置 CLOB 参数(文本文件)try (FileReader fr = new FileReader(clobFilePath)) {pstmt.setCharacterStream(3, fr, (int) new File(clobFilePath).length());}pstmt.executeUpdate();}}// ------------------------ 读取 BLOB 和 CLOB 数据 ------------------------private static void readBlobAndClob(Connection conn, int id) throws SQLException, IOException {// SQL 语句String sql = "SELECT name, content, text_content FROM files WHERE id = ?";try (PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setInt(1, id);try (ResultSet rs = pstmt.executeQuery()) {if (rs.next()) {String name = rs.getString("name");Blob blob = rs.getBlob("content");Clob clob = rs.getClob("text_content");// 保存 BLOB 到文件saveBlobToFile(blob, "output_image.jpg");System.out.println("BLOB 文件已保存!");// 保存 CLOB 到文件saveClobToFile(clob, "output_text.txt");System.out.println("CLOB 文件已保存!");}}}}// ------------------------ 辅助方法 ------------------------// 将 Blob 保存为文件private static void saveBlobToFile(Blob blob, String outputFilePath) throws SQLException, IOException {try (InputStream is = blob.getBinaryStream();FileOutputStream fos = new FileOutputStream(outputFilePath)) {byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = is.read(buffer)) != -1) {fos.write(buffer, 0, bytesRead);}}}// 将 Clob 保存为文件private static void saveClobToFile(Clob clob, String outputFilePath) throws SQLException, IOException {try (Reader reader = clob.getCharacterStream();FileWriter fw = new FileWriter(outputFilePath)) {char[] buffer = new char[4096];int bytesRead;while ((bytesRead = reader.read(buffer)) != -1) {fw.write(buffer, 0, bytesRead);}}}
}
代码说明
1. 插入数据(BLOB 和 CLOB)
-
BLOB 操作:
- 使用
FileInputStream
读取本地文件。 - 通过
setBinaryStream()
将输入流传递给PreparedStatement
。 - 参数
2
对应 SQL 中的?
占位符(第二个参数)。
- 使用
-
CLOB 操作:
- 使用
FileReader
读取文本文件。 - 通过
setCharacterStream()
将字符流传递给PreparedStatement
。
- 使用
2. 读取数据(BLOB 和 CLOB)
-
BLOB 读取:
- 通过
getBlob("content")
获取Blob
对象。 - 使用
getBinaryStream()
获取输入流,逐块读取并写入目标文件。
- 通过
-
CLOB 读取:
- 通过
getClob("text_content")
获取Clob
对象。 - 使用
getCharacterStream()
获取字符流,逐块读取并写入目标文件。
- 通过
3. 关键注意事项
-
流操作:
- 使用缓冲区(
byte[]
或char[]
)逐块读写,避免内存不足。 - 确保所有流在使用后关闭(通过
try-with-resources
)。
- 使用缓冲区(
-
事务管理:
- 大文件操作建议在事务中执行,确保数据一致性。
- 插入和读取操作需在同一个事务中完成(示例中已关闭自动提交)。
-
异常处理:
- 捕获
SQLException
和IOException
,确保资源正确释放。
- 捕获
-
数据库兼容性:
- 不同数据库的 BLOB/CLOB 类型可能不同(如 Oracle 的
BLOB
和CLOB
,MySQL 的LONGBLOB
和LONGTEXT
)。
- 不同数据库的 BLOB/CLOB 类型可能不同(如 Oracle 的
运行前准备
- 依赖:确保项目包含 MySQL JDBC 驱动(如
mysql-connector-java
)。 - 文件路径:
blobFilePath
:替换为实际二进制文件路径(如D:/test_image.jpg
)。clobFilePath
:替换为实际文本文件路径(如D:/large_text.txt
)。
示例输出
BLOB 文件已保存!
CLOB 文件已保存!
操作成功,事务已提交!
扩展建议
-
分块读取优化:
对于超大文件,可调整缓冲区大小(如8192
)或使用ResultSet
的流式处理(getBinaryStream()
直接写入文件)。 -
性能优化:
- 使用
setBlob()
和setClob()
方法,直接传递InputStream
或Reader
,避免内存缓存。
- 使用
-
安全性:
确保文件路径权限正确,防止越权访问。
通过此示例,你可以实现对大文件的高效存储和读取,适用于图片、文档等二进制数据或长文本的存储场景。