程式寫了老半天,說到底就是為了處理資料。
不管處理邏輯使用了多少技術,到頭來終究會得出一個結果,並且需要將這個結果儲存起來,這就是資料庫的用處了。
在Java中我們會使用JDBC來進行資料庫的操作,有統一的語法來進行,不過這些都是Java官方高級工程師們的心血結晶,在使用的同時了解一下背後原理也會用得安心一些,發生問題也大概知道要修哪裡。
下圖就是JDBC的概念圖:
我們在程式碼寫的會是JDBC code,而JDBC其實就是一組介面,真正提供介面實作內容的是各家資料庫廠商的驅動程式(driver),為什麼要這麼做?
資料庫不是只有一種,有好多廠商都推出自家的資料庫,賺錢嘛,提供給商用公司就可以收使用權費用。
但這就衍生出一個問題,每家資料庫都有自己的通訊協定,這樣開發好的程式如果以後要用另一家廠商的資料庫,那不就要重寫?
所以Java官方提出了JDBC的解決方案,Java開發者只要專心寫JDBC code,要用哪家資料庫就只要再載入該家資料庫的driver,替介面注入實作內容,一切就都可以運作了~ 這也完全符合write once, run everywhere的宗旨。
在我們寫JDBC的時候會有Statement以及PreparedStatement兩種放入SQL語句的物件,我們都會說用Statement需要直接放入完整的SQL語句,但程式中常常需要用字串連接的方式加上變數,這就導致有SQL Injection的可能了。下面舉個例子:
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter username:");
String username = scanner.next();
System.out.println("Please enter password:");
String password = scanner.next();
String sql = "SELECT * FROM USER WHERE username = '" + username + "' and password = '" + password + "'";
Connection conn = DriverManager.getConnection("jdbc:xxxx....", "someUserName", "somePwd");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
範例中會藉由console輸入的username和password來尋找資料庫中USER表格相對應的user資料。如果這時候我們在console要輸入username的時候輸入以下:
Please enter username:
Jack' OR 1=1; --
Please enter password:
whatever
密碼隨便輸入沒差,我們來看看這樣sql會變什麼:
SELECT * FROM USER WHERE username = 'Jack' OR 1=1; --' and password = 'whatever'
"--"在某些資料庫中就是註解的符號,所以上面的sql語句在";"後面都被註解掉了,而我們WHERE條件式不管username=什麼,加上了"OR 1=1"就一定會是true,所以這個sql就會找出USER表格中所有的user!
這樣的情況就是被SQL Injection了。
交易(Transaction)