JDBC連接MySQL數據庫基礎
JDBC(Java Database Connectivity)提供了一種與平臺無關的用於執行SQL語句的標準Java API,可以方便地實現多種關係型數據庫的統一操作,它由一組用Java語言編寫的接口和類組成
主要內容:
使用DriverManager、Connection、PreparedStatement、ResultSet對數據庫進行增刪改查操作
連接數據庫
一、配置數據庫
要使用MySQL數據庫進行開發,首先去官網下載驅動,然後將MySQL數據庫的驅動程序配置到classpath中。
二、加載數據庫驅動程序
加載數據庫驅動程序是JDBC操作的第一步,由於已經將數據庫的驅動程序直接配置到了classpath中,所以,此時可以直接進行加載。MySQL中的數據庫驅動路徑是com.mysql.jdbc.Driver。得到驅動程序路徑之後,即可利用Class類進行驅動程序的加載。
可從https://mvnrepository.com下載驅動程序 Connector/J
三、 連接數據庫。
如果數據庫驅動程序可以正常加載,就可以利用DriverManager類連接數據庫。在DriverManager中,提供的主要操作就是得到一個數據庫的連接,getConnection()方法就是取得連接對象,此方法返回的是Connection對象,不管使用哪種方式連接,都必須提供一個數據庫的連接地址。
//1.加載MySQL的驅動類 com.mysql.jdbc.Driver
Class.forName("com.mysql.jdbc.Driver"); //JDK1.7及以下必須 JDK1.8及以上不是必須 建議加上
//2.獲取數據庫連接對象 連接要素:host port user password
String url = "jdbc:mysql://localhost:3306/myshopn?characterEncoding=utf8";
String user = "root";
String password = "1234";
conn = DriverManager.getConnection(url, user, password);
執行數據庫的更新操作
數據庫連接後,就可以進行數據庫的具體操作,要使用Statement接口完成,此接口可以使用Connection接口中提供的createStatement()方法實例化。
Connection conn = null;
try {
//1.加載MySQL的驅動類 com.mysql.jdbc.Driver
Class.forName("com.mysql.jdbc.Driver"); //JDK1.7及以下必須 JDK1.8及以上不是必須 建議加上
//2.獲取數據庫連接對象 連接要素:host port user password
String url = "jdbc:mysql://localhost:3306/myshopn?characterEncoding=utf8";
String user = "root";
String password = "1234";
conn = DriverManager.getConnection(url, user, password);
//TODO 3.實現數據庫的操作
//3.1 編寫sql語句
String insert_sql = "insert into commoditytype(ct_id,ct_name) values (7,'消費電子產品')"; //增
String delete_sql = "delete from commoditytype where ct_id = 7 "; //刪
String update_sql = "update commoditytype set ct_name='傢俱' where ct_id =6"; //改
//3.2獲取執行對象
Statement state = conn.createStatement();
int s = state.executeUpdate(insert_sql);
// int s = state.executeUpdate(delete_sql);
// int s = state .executeUpdate(update_sql);
System.out.println(s);//
catch (Exception e) {
e.printStackTrace();
}finally {
if(conn!=null) {
try {
conn.close();//關閉數據庫連接對象
} catch (SQLException e) {
e.printStackTrace();
}
}
數據庫查詢操作
使用SQL的select語句可以查詢出數據庫的全部結果,在JDBC的操作中數據庫的所有查詢記錄將使用ResultSet進行接收,並使用ResultSet顯示內容。要進行數據庫查詢操作,需要使用Statement接口定義的executeQuery()方法,此方法返回值類型就是一個ResultSet的對象,此對象中存放了所有的查詢結果。
Connection conn = null;
try {
//1.加載MySQL的驅動類 com.mysql.jdbc.Driver
Class.forName("com.mysql.jdbc.Driver"); //JDK1.7及以下必須 JDK1.8及以上不是必須 建議加上
//2.獲取數據庫連接對象 連接要素:host port user password
String url = "jdbc:mysql://localhost:3306/myshopn?characterEncoding=utf8";
String user = "root";
String password = "1234";
conn = DriverManager.getConnection(url, user, password);
//TODO 3.實現數據庫的操作
//3.1 編寫sql語句
String query_sql = "select * from customer"; //查
//3.2獲取執行對象
Statement state = conn.createStatement();
//執行sql語句,實現查詢
ResultSet rs = state.executeQuery(query_sql);
while(rs.next()) {
String cu_id = rs.getString(1); //從1開始
String cu_name = rs.getString(2);
String cu_phone = rs.getString(3);
int cu_gender = rs.getInt(4);
String cu_address = rs.getString(5);
System.out.println(cu_id+":"+cu_name+"|"+cu_phone+"|"+cu_gender+"|"+cu_address);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(conn!=null) {
try {
conn.close();//關閉數據庫連接對象
} catch (SQLException e) {
e.printStackTrace();
}
}
//--------------------------------------------------------------------------------
out:
2a4e0cdd-380e-41bf-960f-f2f6d0a6ccae:劉德華|9999|1|廣州
36da94a2-df44-4d6c-a46f-89f47f635aeb:姚明|4567|1|上海
54daf129-8315-4d91-90ad-eb2ae5ea4f0b:宋江|4444|1|三國
5893fc25-5f43-4b8f-9de3-ea5edd9ce9bf:張飛|123|1|河南
6198a5ed-27e9-4502-9535-36aca922b1a1:張學友|5678|1|北京
9de11bff-3dde-4655-aa81-22e0f5a0ac0b:王菲|7654|0|北京
d30aab14-eff2-4bf2-830a-8ee0c65d84ce:可樂|1111|1|美國
f626b9f4-ecde-4b30-916a-1f89d330cc7a:芬達|6666|1|美國
模擬登錄功能
來說個比較有意思的東西:注入攻擊,這是在很久以前的一種破解密碼的手段,現在基本上不存在網站可以通過這方法破解密碼
我們在用戶名中輸入 ’or 1=1#,密碼隨便寫。
我們把它代入到上面的那條語句中,就變成了
select count() from customer where cu_name =’’ or 1=1#’ and cu_phone =‘23123124’
我們分析下語義,在SQL語法中 # 是註釋符,所以後面的語句都會杯註釋掉,那麼上面的語句就等價於
select count() from customer where cu_name =’’ or 1=1
我們知道SQL語句中where相當於判斷語句,並且是由 or 連接的,所以 cu_name=’’ 和 1=1 中有一個爲真就爲真。1=1肯定爲真,所以語句又等價於
select count(*) from customer
這個語句的作用是爆出表中的所有字段。
也就是說我們用 ‘or 1=1# 這麼一個字符串就可以繞開登陸的密碼,直接進入程序。當然這僅限於那些可以被注入的程序或者網頁
Connection conn = null;
Scanner scan = new Scanner(System.in);
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myshopn?characterEncoding=utf8";
String user = "root";
String password = "1234";
conn = DriverManager.getConnection(url, user, password);
String cu_name = " 'or 1=1 # ";
String cu_phone = "23123124";
String sql = "select count(*) from customer where cu_name = '"+cu_name+"' and cu_phone = '"+cu_phone+"'";
Statement state = conn.createStatement();
ResultSet rs = state.executeQuery(sql);
rs.next();
int count=rs.getInt(1);
if(count>0) {
System.out.println("登陸成功");
}else {
System.out.println("登陸失敗");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(conn!=null) {
try {
conn.close();//關閉數據庫連接對象
} catch (SQLException e) {
e.printStackTrace();
}
}
}
out:登陸成功
如何解決注入攻擊
對於java數據庫連接JDBC而言,SQL注入攻擊只對Statement有效,對PreparedStatement是無效的,只是因爲PreparedStatement不允許在不同的插入時間改變查詢的邏輯結構
Connection conn = null;
Scanner scan = new Scanner(System.in);
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myshopn?characterEncoding=utf8";
String user = "root";
String password = "1234";
conn = DriverManager.getConnection(url, user, password);
String cu_name = " 'or 1=1 # ";
String cu_phone = "23123124";
String sql = "select count(*) from customer where cu_name = ? and cu_phone = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, cu_name);
ps.setString(2, cu_phone);
ResultSet rs = ps.executeQuery();
rs.next();
int count=rs.getInt(1);
if(count>0) {
System.out.println("登陸成功");
}else {
System.out.println("登陸失敗");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(conn!=null) {
try {
conn.close();//關閉數據庫連接對象
} catch (SQLException e) {
e.printStackTrace();
}
}
}
out:登陸失敗
練習:修改電話
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/myshopn?characterEncoding=utf8";
String user = "root";
String password = "1234";
conn = DriverManager.getConnection(url, user, password);
String cu_id = "2a4e0cdd-380e-41bf-960f-f2f6d0a6ccae";
String cu_phone="9999";
String sql = "update customer set cu_phone=? where cu_id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, cu_phone);
ps.setString(2, cu_id);
int line = ps.executeUpdate();
System.out.println(line);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(conn!=null) {
try {
conn.close();//關閉數據庫連接對象
} catch (SQLException e) {
e.printStackTrace();
}
}
}