1.JDBC概述
JDBC(Java DataBase Connectivity)就是Java數據庫鏈接
早期SUN公司的天才們想編寫一套能夠鏈接天下全部數據庫的API,可是當他們剛剛開始時就發現這是不可完成的任務,由於各個廠商的數據庫服務器差別太大了。後來SUN開始與數據庫廠商們討論,最終得出的結論是,由SUN提供一套訪問數據庫的規範(就是一組接口),並提供鏈接數據庫的協議標準,而後各個數據庫廠商會遵循SUN的規範,提供一套訪問本身公司的數據庫服務器的API。SUN提供的規範命名爲JDBC,而各個廠商提供的,遵循了JDBC規範的,能夠訪問本身數據庫的API被稱之爲驅動!JDBC是接口,而JDBC驅動(相關jar包)纔是接口的實現,沒有驅動沒法完成數據庫鏈接!每一個數據庫廠商都有本身的驅動,用來鏈接本身公司的數據庫。java
2.JDBC核心類(接口)介紹
JDBC中的核心類有:DriverManager、Connection、PreparedStatement,和ResultSetmysql
(1)DriverManger(驅動管理器)的做用有兩個:web
- 註冊驅動:這可讓JDBC知道要使用的是哪一個驅動
- 獲取Connection:若是能夠獲取到Connection,那麼說明已經與數據庫鏈接上了。
(2)Connection:Connection對象表示鏈接,與數據庫的通信都是經過這個對象展開的sql
- Connection最爲重要的一個方法就是用來獲取PreparedStatement對象
(3)PreparedStatement是用來向數據庫發送SQL語句的,這樣數據庫就會執行發送過來的SQL語句.他有兩個重要方法:數據庫
- int executeUpdate(String sql):執行更新操做(insert、update、delete等),返回更新的條數(int類型)
- ResultSet executeQuery(String sql):執行查詢操做,返回查詢結果ResultSet
(4)ResultSet對象表示查詢結果集,只有在執行查詢操做後纔會有結果集的產生。結果集是一個二維的表格,有行有列。操做結果集要移動ResultSet內部的「行光標」,以及獲取當前行上的每一列上的數據:服務器
- boolean next():使「行光標」移動到下一行,並返回移動後的行是否存在;
- XXX getXXX(int col):獲取當前行指定列上的值,參數就是列數,列數從1開始,而不是0。
操做光標的方法有兩類:一類用來判斷遊標位置的,另外一類是用來移動遊標的。光標的移動是一行一行的移動url
3.代碼訪問數據庫
MySQL驅動包:mysql-connector-java-5.1.39-bin.jarspa
(1)原始方法訪問數據庫code
public class JDBCUtils_V1 { public static Connection getConnection() { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver");//註冊驅動 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web08", "root", "root"); } catch (Exception e) { e.printStackTrace(); } return conn; } public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) { ...... } } public class MyTest001 { public static void main(String[] args) throws SQLException { Connection conn = JDBCUtils_V1.getConnection(); String sql="select * from user"; PreparedStatement prepareStatement = conn.prepareStatement(sql); ResultSet resuleSet = prepareStatement.executeQuery(); while(resuleSet.next()) { System.out.println(resuleSet.getObject(2)); } JDBCUtils_V1.release(conn, prepareStatement, resuleSet); } }
(2)使用ResourceBundle讀取properties文件訪問數據庫對象
DRIVER=com.mysql.jdbc.Driver URL=jdbc:mysql://localhost:3306/user Username:root Password:123 public class JDBCUtils_V2 { private static String driver; private static String url; private static String username; private static String password; /** * 靜態代碼塊加載配置文件信息 */ static{ ResourceBundle bundle = ResourceBundle.getBundle("db"); driver = bundle.getString("driver"); url = bundle.getString("url"); username = bundle.getString("username"); password = bundle.getString("password"); } public static Connection getConnection() { Connection conn = null; try { Class.forName(driver); conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } return conn; } public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) { } }
(3)使用類加載器的classLoader.getResourceAsStream("db.properties");方法讀取properties配置文件來鏈接數據庫
public class JDBCUtils_V3 { private static String driver; private static String url; private static String username; private static String password; /** * 靜態代碼塊加載配置文件信息 */ static { try { // 1.經過當前類獲取類加載器 ClassLoader classLoader = JDBCUtils_V3.class.getClassLoader(); // 2.經過類加載器的方法得到一個輸入流 InputStream is = classLoader.getResourceAsStream("db.properties"); // 3.建立一個properties對象 Properties props = new Properties(); // 4.加載輸入流 props.load(is); // 5.獲取相關參數的值 driver = props.getProperty("driver"); url = props.getProperty("url"); username = props.getProperty("username"); password = props.getProperty("password"); } catch (IOException e) { e.printStackTrace(); } } /** * 獲取鏈接方法 */ public static Connection getConnection() { Connection conn = null; try { Class.forName(driver); conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } return conn; } public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) { } }
4.SQL攻擊
在須要用戶輸入的地方,用戶輸入的是SQL語句的片斷,最終用戶輸入的SQL片斷與咱們DAO中寫的SQL語句合成一個完整的SQL語句!例如用戶在登陸時輸入的用戶名和密碼都是爲SQL語句的片斷!
在登陸頁面輸入參數:‘a' or 'a'='a", "a' or 'a'='a‘
這會使咱們登陸成功!由於是輸入的用戶名和密碼是SQL語句片斷,最終與咱們的login()方法中的SQL語句組合在一塊兒!組合在一塊兒的SQL語句:
SELECT * FROM user WHERE username='a' or 'a'='a' and password='a' or 'a'='a' |
- 使用PreparedStatement能夠防止SQL攻擊。PreparedStatement叫預編譯聲明,是Statement的子接口,可使用PreparedStatement來替換Statement。
- PreparedStatement相比於Statement,最大的好處就是在於重複使用同一模板,給予其不一樣的參數來重複的使用它。這纔是真正提升效率的緣由。
5.MySQL相關內容
5.1表與表的關係
(1)主表---主鍵,從表---外鍵字段
聲明外鍵約束語法:alter table 從表 add [ constraint ] 外鍵名稱 foreignkey 從表外鍵字段名 references 主表(主表的主鍵)
注:外鍵名稱用於刪除外鍵約束(alter table 從表 drop foreignkey 外鍵名稱),通常建議以「_fk」結尾
一對多(一個主鍵對應多個外鍵):分類表和商品表的關係以下:
多對多(多個主鍵對應多個外鍵):訂單表,訂單項表和商品表
5.2 多表查詢語句
*student表和score分數表
(1)內鏈接:結果僅包含符合鏈接條件的兩表中的行。兩種寫法
(2)外鏈接。結果包含符合條件的行,同時包含不符合條件的行(分爲左外鏈接、右外鏈接和全外鏈接)
左外鏈接:左表所有行+右表匹配的行,若是左表中某行 在右表中沒有匹配的行,則右表該行顯示NULL。以下:
右外鏈接:右表所有行+左表匹配的行。以下: