程序写了老半天,说到底就是为了处理资料。
不管处理逻辑使用了多少技术,到头来终究会得出一个结果,并且需要将这个结果储存起来,这就是资料库的用处了。
在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)
>>: [Android Studio 30天自我挑战] CradView布局练习
今天来聊聊「多线程」的单元测试。 多线程测试的困难点 当系统成长到一个程度,效能的重要性就会慢慢浮现...
在网路世界中,安全永远是最最重要的事情,而云端安全当然也不例外。任何的安全问题都来自於人为的疏忽,部...
今天的内容是页面前後端资料传递,这个部分跟前面相比来说简单许多也比较直觉话。如果以前有写过 Vue....
大家好,我是长风青云。原来是27天了,自从我待在家後,对时间的流逝越来越不敏感,乾脆做个月历,放在身...
DAY23 MongoDB 免费监控工具 产品或服务上线最重要的当然是稳定度,大一点的团队会设置监控...