第17章,練習3:使用鍵盤輸入流,接收一大段文本數據,並輸入一個圖片的路徑, 然後將這些數據保存在數據表中,數據表由用戶自行創建。

/**
 * 使用鍵盤輸入流,接收一大段文本數據,並輸入一個圖片的路徑, 然後將這些數據保存在數據表中,數據表由用戶自行創建。
 */
package exercise17;

import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Ex03 {
	public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver";
    public static final String DBURL = "jdbc:mysql://localhost:3306/test";
    public static final String DBUSER = "root";
    public static final String DBPASS = "mysqladmin";
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
        Connection conn = null;
        Class.forName(DBDRIVER);   // 加載驅動程序
        conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
        createTable(conn);        // 創建名爲info的數據表
        insertData(conn);        // 向數據庫表中插入一行數據
        showPhoto(conn);          // 展示數據表中的數據內容,longtext類型數據打印在控制檯,二進制大對象(longblob類型)輸出到桌面的文件中
	}
	
	/**
	 * 
	 * @return 用戶從鍵盤輸入的字符串
	 * @throws Exception
	 */
	public static String getString() throws Exception {
	    InputStreamReader isr = new InputStreamReader(System.in);  // 創建字符輸入流實例,從鍵盤輸入
	    BufferedReader buf = new BufferedReader(isr);   // 創建字符輸入流緩衝
	    String temp = null;         // 保存用戶輸入的字符串
	    temp = buf.readLine();      // 從字符輸入流緩衝中讀取一行字符
	    return temp;
	}
	
	/**
	 * @param 數據庫的連接實例
	 * @throws Exception
	 * @function 向數據庫中插入一行數據
	 */
	public static void insertData(Connection conn) throws Exception {
		boolean flag = true;               //  定義一個標識符
		InputStream input = null;          // 定義一個字節輸入流
		PreparedStatement pstmt = null;    // 數據庫操作
		// 定義向數據庫中插入數據的SQL語句
        String sql = "INSERT INTO info(note, photo) VALUES(?, ?)";
        pstmt = conn.prepareStatement(sql); // 獲取數據庫操作實例
		while (flag) {                     // 反覆插入數據,直至標識符爲false
			String text = getLargeText("請輸入一個大文本數據:");   // 提示用戶輸入longtext類型的大文本數據
			byte[] b = text.getBytes();    // 將文本數據從字符串轉換爲byte類型的數組b
		    input = new ByteArrayInputStream(b);  // 創建字節數組輸入流,將字節數組b傳入輸入流
		    pstmt.setAsciiStream(1, input);  // 設置SQL語句中的第一個?的值
		    // 提示用戶輸入要保存的圖片(longblob類型)路徑,返回該文件的File實例
		    File f = getPhotoDir("請輸入一張圖片的保存路徑:", "路徑錯誤,請重新輸入:");  
	        input = new FileInputStream(f);  // 創建文件的輸入流
	        pstmt.setBinaryStream(2, input); // 設置SQL語句中的第二個?的值
	        pstmt.executeUpdate();           //  向數據庫中的info表中插入數據
	        System.out.println("是否繼續更新數據?結束請輸入‘N’:");
	        String str = "";
	        if ((str = getString()).equals("N") || str.equals("n")) {  // 如果用戶輸入了n(部分大小寫),則將標識符改爲false結束更新
	        	flag = false;
	        }
		}
	}
	
	/**
	 * 
	 * @param 提示信息
	 * @return 字符串(用戶輸入的大文本數據內容)
	 * @throws Exception
	 */
	public static String getLargeText(String info) throws Exception {
		System.out.println(info);     // 打印提示信息
        StringBuffer buffer = new StringBuffer(); // 創建字符串緩衝
        String str = "";
     // 用戶可多行輸入字符串(刪除字符串兩端的空格被刪除),直到輸入end爲止(建議用戶輸入圖片文件的名稱,這樣在讀取時可以利用note列獲得文件名稱)
        while (!(str = getString().trim()).equals("end")) { 
        	buffer.append(str).append("\r\n");    // 每輸入一行就加入到StringBuffer中
        }
        buffer.delete(buffer.length()-2, buffer.length());  // 當結束輸入時,將最後面多餘的換行符(\r和\n兩個字符)刪除
        return buffer.toString();     // 以字符串形式返回
	}
	
	/**
	 * 
	 * @param info:輸入提示
	 * @param err:錯誤提示
	 * @return 用戶輸入的文件路徑的File實例
	 * @throws Exception
	 */
	public static File getPhotoDir(String info, String err) throws Exception {
		System.out.println(info);    // 打印輸入提示
		String path = getString();   // 獲得文件路徑的一個字符串
		File f = null;
		f = new File(path);          // 獲得文件的File實例
		while (!f.exists() || !path.matches(".+\\.(jpg|png|jpeg|gif)")) {  // 判斷文件是否存在,或文件格式(圖片)是否正確
			System.err.println(err); // 如果判斷結果爲否,則打印錯誤提示
			path = getString();      //  重新輸入
			f = new File(path);      // 重新創建File實例
		}
		return f;                    // 返回正確的文件File實例
	}
	
	/**
	 * 
	 * @param conn:數據庫連接實例
	 * @throws SQLException
	 * @function 在數據庫中創建數據表info(如果這個類型的表已經存在就不用重複創建了)
	 */
    public static void createTable(Connection conn) throws SQLException {
    	Statement stmt = null;    // 數據庫操作
    	stmt = conn.createStatement(); // 通過數據庫連接得到數據庫操作實例
    	// 定義SQL語句,該語句的內容就是:創建數據表info(如果表不存在)。
    	String sql = "create table if not exists info("
    			+ "id int auto_increment primary key,"   // id列,自動增長、主鍵
    			+ "note varchar(30) CHARACTER SET gbk DEFAULT NULL,"                       // note列,大文本數據對象
    			+ "photo longblob"                       // photo列,二進制大數據對象(圖片)
    			+ ");";
    	stmt.execute(sql);        // 執行SQL語句,創建info表
    }
    
    /**
     * @function 展示數據表中的全部數據內容,longtext類型數據打印在控制檯,二進制大對象(longblob類型)輸出到桌面的文件中
     * @param conn: 數據庫連接實例
     * @throws Exception
     */
    public static void showPhoto(Connection conn) throws Exception {
    	PreparedStatement pstmt = null;
    	ResultSet rs = null;
    	String sql = "SELECT id, note, photo FROM info;";
    	pstmt = conn.prepareStatement(sql);  // 獲得數據庫操作實例
    	rs = pstmt.executeQuery();    // 實行SQL語句,得到查詢的結果集
    	while (rs.next()) {           // 展示結果集中的全部內容
    		int id = rs.getInt("id"); // 獲得id的值
    		Clob clob = rs.getClob("note");  // 從結果集中獲得大文本數據
    		String note = clob.getSubString(1, (int)clob.length()); // 轉換成字符串
    		System.out.println("id:  " + id + "; note:  " + note);  // 輸出id和note內容
    		File f = new File("C:" + File.separator + "Users" + File.separator + "yeqin" + 
    	        File.separator + "Desktop" + File.separator + note + ".gif"); // 得到輸出文件的路徑(在桌面)
    		if (!f.exists()) {        // 如果輸出的文件不存在,則新建一個
    			System.out.println("在" + f.toString() + "處新建一個文件!");
    			f.createNewFile();    // 新建一個文件
    		}
    		OutputStream output = new FileOutputStream(f);   // 得到文件的寫入流
    		Blob blob = rs.getBlob("photo");    // 從結果集中獲得Blob實例
    		byte[] b = blob.getBytes(1, (int)blob.length());  // 將Blob實例中的數據保存在byte類型數組中,注意Blob實例的起始位置爲1,而不是0
    		output.write(b);              // 將數組內容寫入文件中
    		output.close();
    	}
    	pstmt.close();
    }
}


/**
 * 程序運行結果:
	 請輸入一個大文本數據:
	 red flower
	end
	請輸入一張圖片的保存路徑:
	d:\photo\red flower.gif
	是否繼續更新數據?結束請輸入‘N’:
	y
	請輸入一個大文本數據:
	HeloIcon_solid
	end
	請輸入一張圖片的保存路徑:
	y
	路徑錯誤,請重新輸入:
	d:\photo\HelpIcon_solid.gif
	是否繼續更新數據?結束請輸入‘N’:
	y
	請輸入一個大文本數據:
	image1
	end
	請輸入一張圖片的保存路徑:
	d:\photo\image1.gif
	是否繼續更新數據?結束請輸入‘N’:
	n
	id:  1; note:  red flower
	在"C:\Users\yeqin\Desktop\red flower.gif"處新建一個文件!
	id:  2; note:  HeloIcon_solid
	在"C:\Users\yeqin\Desktop\HeloIcon_solid.gif"處新建一個文件!
	id:  3; note:  image1
	在"C:\Users\yeqin\Desktop\image1.gif"處新建一個文件!
 *
 */

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章