---
# System prepended metadata

title: 2/5、2/6、2/7、2/10
tags: [Java]

---

---
tags: Java 
---
# 2/5、2/6、2/7、2/10

## 2/5 hashCode 跟 泛型的相關

hashCode(): 主要是用來分類的，實務上小於或等於equals的方法， 像我可以直接用category去判斷也是一樣。

comparator<類別>: 泛型為了解決編譯時期型別的問題，只需要定義一次。

Q: .text 內有很多資料，內容可能有中文(簡體或繁體)、日文，把它讀取出來，print出來，可參考java.nio.files

## 2/6 JDBC 資料庫

### 連接資料庫
```
String url = "jdbc:mysql://localhost:3306/test"; 
        String user = "root"; 
        String password = "root"; 
        try { 
            Connection conn = 
               DriverManager.getConnection(url, 
                                  user, password);
     if(conn != null && !conn.isClosed()) {
            System.out.println("資料庫連線測試成功！"); 
            Statement sm = conn.createStatement();
          ResultSet rs = sm.executeQuery("SELECT * FROM sample");
        ...
        }catch(SQLException e) { 
            System.out.println("連線失敗");
            e.printStackTrace(); 
        }  
```

若有要寫資料進資料庫要指定編碼
> static String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8"; 

### try-with-result
自動關閉資源，他必需要是AutoCloseable的物件，所以所有的Closeable物件都是AutoCloseable物件。 JVM會在離開try之後依建構的反向順序 呼叫AutoCloseable.close()。



Q: 為何IDE再把encode改成big5就無法編碼，會產生亂碼
Ans: JVM預設編碼模式是big5，連結的標準輸出是utf8就會產生亂碼，這時可以利用下列，去設定PrintStream的編碼。 
```
System.setOut(new PrintStream(System.out, true, "big5"));
```
Q: 建立一個資料庫，資料庫編碼用UTF8，建立表格，並取表格資料出來，使用JDBC

## 2/7 Map、Stream
![](https://i.imgur.com/A5qrqZ4.jpg)

### Map
* Map: 對應到key跟Value。
* key->getKeys(): Set。
* Value -> getValue(): Collection
* 內容為Entry ->key/Value , entrySet(): Set

### Stream
串流: Binary(byte, 2進制)、 Text(Char)
Input 內有: InputStream 、Reader。
Output 內有: OutputStream、Writer。
[對象]: 檔案
[類型]: InputStream、 OutputStream、Reader、 Writer

Q: 圖檔(越大越好約6-700K)複製、用FileInputStream、OutputStream。

### 2/10 資料庫取資料 、 圖片的複製

![](https://i.imgur.com/jxaXNIZ.jpg)

JDBC API: 沒有實作介面，所以必須指定要使用哪個資料庫。

> String jdbcDriver = "com.mysql.jdbc.Driver";

### FileInputStream read 跟 FileOutputStream write

讀取資料可以直接讀不用存在buffer沒關係，但寫出需要是讀進Buffer多少再寫出buffer。
```
int capacity = 4096;  //記憶體空間
byte[] buffer = new byte[capacity];
int size = -1;
//讀進來可以直接讀就好
while((size = fis.read(buffer)) != -1){ 
fout.write(buffer , 0, size); //寫出去時要注意讀多少寫多少}
```

### 用命令字元查詢
* 查詢IP: ipconfig
* 連結其他電腦可以用: ping 位置
* 查詢位置卡在哪個點: tracert 位置
* 測試port使否有通: telnet port號

### 資料庫去實作介面產生連線
```
//1. 註冊DriverName
String jdbcDriver = "com.mysql.jdbc.Driver";
Class.forName(jdbcDriver);
//2. create connect
String url = "jdbc:mysql://localhost:3306/test";
String user="root", password="root";
Connection con = DriverManager.getConnection(url, user, password);
//3. create statement
Statement stmt = con.createStatement();
//4. execute SQL
String sql = "SELECT sid, number, name, perPrice, qty FROM sample";
ResultSet rs = stmt.executeQuery(sql);
```

Q: 把資料表的產品名稱改英文，要加有效日期Date:2019/3~2020/2, 水果內有a的塞選出來，還有日期內的塞選出來
Q: 使用Prepared Statement跟Statement的不同處
Ans: 1. PreparedStatement是預編譯的, 會先初始化SQL,對於批量處理可以大大提高效率，不會像createStatement沒有初始化，沒有預處理，每次都是從0開始執行SQL，只取一次資料會感受不出差別，但執行多次SQL語句的時候速度會大大的不同。2. 傳遞給PreparedStatement對象的參數可以被強制進行類型轉換，使開發人員可以確保在插入或查詢數據時與底層的數據庫格式匹配。3. 可以防止SQL的注入攻擊，把字串另外做處理，利用問號跟setString(index, String)給值。

