JDBC备忘录6_处理大段文本和二进制数据

xusong 2013-06-26

varchar()最大容量为255个,当需要更大的数据时候,我们需要使用大段文本数据类型 clob

各种数据库对clob类型的支持不同,在mysql中使用text(只能存放纯文本)

将文本文件的内容存入clob字段中

如果文件中只有ascii码,没有中文字符则使用下面的方法
ps.setAsciiStream(int parameterIndex, InputStream x, int length)

不确定文件内容的编码时,可以使用
setCharacterStream(int parameterIndex, Reader reader, int length)

存入

public static void create() throws Exception {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			String sql = "insert into clob_test(big_text) values (?) ";
			ps = conn.prepareStatement(sql);
			File file = new File("src/cn/itcast/jdbc/JdbcUtils.java");
			Reader reader = new BufferedReader(new FileReader(file));
			ps.setCharacterStream(1, reader, file.length());
			int i = ps.executeUpdate();
			System.out.println("i=" + i);
			reader.close();
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
		
	}

它的主要原理是通过IO的Reader,将文件内容读到字符流中,然后写入到数据库中(File-->Reader-->DB)。
对于内存而言,把文件的内容载入内存,文件-->内容,需要读取的字符流Reader。
由于java 的String类型是没有限制的,
所以可以通过把Reader转化成String,然后通过 ps.setString(1, str)的形式插入数据库;

读取clob类型的时候,先获取Reader,然后在写到其他地方。

public static void read() throws Exception {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		
		try {
			conn = JdbcUtils.getConnection();
			String sql = "select big_text from clob_test where id = ? ";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, 1);
			rs = ps.executeQuery();

			while (rs.next()) {
				File file = new File("clob.txt");
				Clob clob = rs.getClob("big_text");
				Reader reader = clob.getCharacterStream();
				Writer writer = new BufferedWriter(new FileWriter(file));
				char[] buffer = new char[1024];
				
				//这里为什么要定义hasReader呢
				//因为在最后一次读取的时候不一定可以可以读到1024个数据
				//所以这里应该使用读取多少就写入多少
				int hasRead = 0;
				while ( (hasRead = reader.read(buffer)) > 0) {
					writer.write(buffer, 0, hasRead);
				}
				
				reader.close();
				writer.close();
			}
		} finally {
			JdbcUtils.free(rs, ps, conn);	
		}
	}

大的二进制文本字段,在mysql中叫Blob
blob类型存放的数据小,无法存储时候可以使用longblob

blob类型的处理和大段文本数据处理的方式是一致的,都是借助IO来进行处理。
blob类型处理二进制文本信息,只能通过流处理,而不能通过字符来处理。

public class BlobTest {
	public static void main(String[] args) throws SQLException, IOException {
//		writeBlob();
		readBlob();
	}
	
	public static void readBlob() throws SQLException, IOException {
		String sql = "select big_blob from blob_test where id = ? ";
		Connection conn = JdbcUtils.getConnection();
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setInt(1, 2);
		ResultSet rs = pstmt.executeQuery();
		
		while (rs.next()) {
			Blob blob = rs.getBlob("big_blob");
			InputStream is = blob.getBinaryStream();
			File file = new File("a.jpg");
			OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
			
			byte[] buffer = new byte[1024];
			int hasRead = 0;
			
			while ((hasRead = is.read(buffer)) > 0) {
				os.write(buffer, 0, hasRead);
			}
			
			is.close();
			os.close();
		}
		
		JdbcUtils.free(rs, pstmt, conn);
	}
	
	public static void writeBlob() throws SQLException, IOException {
		String sql = "insert into blob_test(big_blob) values(?) ";
		Connection conn = JdbcUtils.getConnection();
		PreparedStatement pstmt = conn.prepareStatement(sql);
		
		File file = new File("bg.jpg");
		InputStream is = new BufferedInputStream(new FileInputStream(file));
		pstmt.setBlob(1, is, file.length());
		
		boolean flag = pstmt.execute();
		System.out.println("flag = " + flag);
		is.close();
		
		JdbcUtils.free(null, pstmt, conn);
		
	}
}

相关推荐