JDBC是使用JAVA代碼來連接和操作數據庫的一項技術,內部提供了許多API。其中有一個Driver接口。每個數據庫廠商實現這個類提供一個驅動。通過這個驅動獲取與數據庫的鏈接就能夠操作數據庫了。
JDBC實現原理流程圖如下
一,JDBC具體實現步驟
1,首先要導入jar包.使用mysql就導入mysql包,oracle就導入oracle包
以下是數據庫驅動包的下載地址:
MySQL:http://central.maven.org/maven2/mysql/mysql-connector-java/
oracle:https://www.oracle.com/technetwork/cn/database/features/jdbc/index-093096-zhs.html
2,編寫JAVA代碼,以MySQL爲例
(1)查詢語句select執行過程
大致步驟:
1,註冊數據庫驅動
2,獲取數據庫連接
3,獲取sql語句執行平臺
4,執行sql語句
5,執行查詢語句時獲取結果集
6,關流
方法 | 返回值 | 描述 |
---|---|---|
Class.forName(“com.mysql.jdbc.Driver”); | Class | 註冊mysql驅動 |
DriverManager.getConnection(String url,String user, Stringpwd) | Connection | 獲取數據庫連接 |
connection.createStatement() | Statement | 獲取sql語句執行平臺 |
statement.executeQuery(String sql) | ResultSet | 執行查詢語句獲取一個查詢結果集 |
statement.executeUpdate(String sql) | int | 執行增刪改語句,返回影響行數 |
resultSet.next() | boolean | 遍歷結果集時判斷下一個是否還有數據 |
resultSet.getObject(String columnLabel) | Object | 獲取當前行指定列名的數據 |
resultSet.getObject(int columnIndex) | Object | 獲取當前行第index列的數據 |
resultSet.getXXX() | XXX | 根據設定的類型獲取相應類型的數據,比如geiInt獲取int數據,getString獲取String數據 |
public static void main(String[] args) throws ClassNotFoundException, SQLException {
/**
* 1,註冊數據庫驅動.就這麼一句話。MySQL驅動在com.mysql.jdbc.Driver中
* oracle驅動在oracle.jdbc.OracleDriver中
*/
Class.forName("com.mysql.jdbc.Driver");
/**
* 2,獲取數據庫連接.需要連接的url,user和pwd
* mysql--jdbc:mysql://地址/數據庫名稱
* oracle--jdbc:oracle:thin:@地址:1521:實例(一般是orcl)
*/
String url = "jdbc:mysql://localhost:3306/demo";
String user = "root";
String pwd = "root";
//使用DriverManager.getConnection(url,user,pwd);方法來獲取數據庫連接
Connection connection = DriverManager.getConnection(url, user, pwd);
/**
* 3,獲取數據庫語句執行平臺connection.createStatement()得到一個
* Statement對象,然後在使用執行方法來執行數據庫
* ResultSet executeQuery(String sql);執行查詢語句
* int executeUpdate(String sql);執行更新語句
* 查詢語句執行然後會返回一個ResultSet對象,裏面包含着查詢結果
* 更新語句執行後會返回一個int值,用來表示更新了多少行
*/
Statement statement = connection.createStatement();
String sql = "select * from user";
//這樣就執行完了這句查詢語句。接着在遍歷結果集就能獲取查詢到的數據
ResultSet resultSet = statement.executeQuery(sql);
/**
* 4,用while遍歷結果集,resultSet.next()判斷是否還有數據
* resultSet.getObject(int columnIndex);//獲取第index列的數據,類似根據設定的來獲取
* resultSet.getObject(String columnLabel);//獲取列名爲columnLabel的數據,類似根據設定的來獲取
* 如果要獲取一個字符串就getString();獲取整數就是getInt();
*
*/
while (resultSet.next()){
String username = resultSet.getString("username");
String pawd = resultSet.getString(3);
System.out.println(username+"="+pawd);
}
/**
* 最後關流。後得到的先關閉
*/
resultSet.close();
statement.close();
connection.close();
}
表數據如下:
執行上述查詢過程後結果如下:
(2)增刪改語句執行過程
在獲取連接和sql語句執行平臺後使用executeUpdate(String sql)來執行增刪改語句
操作前表數據
/**
* 執行增刪改語句
*/
//更改
String updateSql = "update user set pwd='456789' where username='zhangsan'";
statement.executeUpdate(updateSql);
//插入
String insertSql = "insert into user(username,pwd) values('lisi','123456')";
statement.executeUpdate(insertSql);
//刪除
String deleteSql = "delete from user where username='wangba'";
statement.executeUpdate(deleteSql);
執行後表數據
二,預編譯sql執行平臺
預編譯sql執行平臺prepareStatement(String sql);將sql事先編譯並緩存好在需要的時候直接使用。比起statement每次執行sql語句時都要重新編譯來的更快些。
方法 | 返回值 | 描述 |
---|---|---|
connection.prepareStatement(String sql) | PreparedStatement | 獲取預編譯sql語句執行平臺,先把sql實現編譯好。執行的時候在使用 |
preparedStatement.executeQuery() | ResultSet | 執行預編譯好的查詢語句獲取一個查詢結果的結果集 |
preparedStatement.executeUpdate() | int | 執行預編譯好的增刪改語句,返回影響的行數 |
preparedStatement.setXXX(int parameterIndex,xxx) | void | 對相應index位置上的佔位符參數設置值,設置String就setString() |
1,預編譯sql使用步驟
前後步驟還是一致的,在使用上的區別就是獲取sql執行平臺的時候使用 connection.prepareStatement(String sql) 這個方法,並且要把你執行的sql放進去。然後再用
executeQuery和executeUpdate來執行sql語句。其中預編譯語句可以使用佔位符,即你要在sql的where條件附上位置的值時使用。比如
select * from user where username=?
上面這句sql的"?“就是佔位符。事先佔好一個位置然後在需要的地方使preparedStatement.setXXX(int parameterIndex,xxx)來給它賦值,比如執行preparedStatement.setString(1,“zhangsan”).上面那句sql就變成了select * from user where username=“zhangsan”,如果有兩個”?“就按”?“出現的順序來賦值,第一個”?"的index是1後面依次累加
select * from user where username=? and pwd=?
preparedStatement.setString(1,“zhangsan”)
preparedStatement.setString(2,“123456”)
–>sql:select * from user where username=“zhangsan” and pwd=“123456”
之後的結果集處理過程是一樣的
(1)預編譯查詢
//1,註冊驅動獲取鏈接---
Connection connection = DriverManager.getConnection(url, user, pwd);
/**
* 預編譯sql執行平臺prepareStatement(String sql);
* 將sql事先編譯並緩存好在需要的時候直接使用。比起statement每次執行
* sql語句時都要重新編譯來的更快些。
*/
String sql = "select * from user where username=?";
//使用預編譯sql來執行查詢語句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//預編譯可以設置佔位符參數。普通的編譯平臺是沒有佔位符的
preparedStatement.setString(1,"zhangsan");
//執行查詢sql
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
String username = resultSet.getString("username");
String pawd = resultSet.getString(3);
System.out.println(username+"="+pawd);
}
//關流...
(2)預編譯增刪改
/**
* 預編譯執行增刪改語句
*/
//更改
String updateSql = "update user set pwd='456789' where username='zhangsan'";
PreparedStatement updateStatement = connection.prepareStatement(updateSql);
updateStatement.executeUpdate();
//插入
String insertSql = "insert into user(username,pwd) values('lisi','123456')";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.executeUpdate();
//刪除
String deleteSql = "delete from user where username='wangba'";
PreparedStatement deleteStatement = connection.prepareStatement(deleteSql);
deleteStatement.executeUpdate();
三,預編譯平臺和普通編譯平臺的區別
1,預編譯具有佔位符,能有效防止sql注入
(1)預編譯具有佔位符的功能。使用佔位符來爲where條件中未知的值賦值能夠有效的防止sql注入
/**
* 預編譯進行where條件拼接
*/
String sql = "select * from user where username=? and pwd = ?";
//預編譯兩條要創建兩個預編譯平臺對象來執行sql
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,username);
preparedStatement.setString(2,pwd);
ResultSet resultSet = preparedStatement.executeQuery();
/**
* 普通編譯平臺進行條件拼接
*/
String sql = "select pwd from user where username='“+username+”' and pwd='"+pwd+"'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
上述兩個編譯平臺中。我們給username賦值"zhangsan",pwd賦值"123456’ or ‘1’='1"
然後分別執行後結果如下:
預編譯的sql–>
編譯平臺的sql–>select * from user where username=‘zhangsan’ and pwd=‘123456’ or ‘1’=‘1’:
可以發現普通編譯平臺用拼接的方式受到類似sql攻擊時會永遠查出數據。這樣就會判斷成登入成功。而預編譯的不會。
(2)使用預編譯執行頻繁使用的sql語句可以提升效率