這篇文章主要用來展現jdbc的使用,是爲了方便閱讀MyBatis源碼使用的,爲源碼分析作一個提早熱身;java
裏面不少關鍵性的信息在MyBatis源碼裏面都能找到,本篇不作MyBatis源碼的分析,mysql
由於MyBatis源碼是一個龐大複雜的工程,不是 一時半會,隻言片語就能說完的。sql
jdbc Demo: 數據庫
1 public static void main(String[] args) throws Exception { 2 test1(); 3 } 4 5 public static void test1() throws Exception { 6 ResultSet rs=null; 7 PreparedStatement pst=null; 8 Connection conn=null; 9 try { 10 String sql="select id as sid,name,age,sex from user where id!=? order by id asc "; 11 //註冊驅動方式1 用反射加載數據庫驅動 12 //Class.forName("com.mysql.cj.jdbc.Driver"); 13 //註冊驅動方式2 也能夠用new MySql的Driver類方式註冊驅動 14 //new Driver(); 15 //註冊驅動方式3 用反射方式new 一個匿名對象 16 Driver.class.getConstructor().newInstance(); 17 conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/gys?serverTimezone=UTC","root","gys"); 18 System.out.println("======查詢前========"); 19 DatabaseMetaData dmd=conn.getMetaData(); 20 System.out.println("數據庫名稱:"+dmd.getDatabaseProductName()); 21 System.out.println("數據庫版本:"+dmd.getDatabaseProductVersion()); 22 System.out.println("是否支持事務:"+dmd.supportsTransactions()); 23 //DriverManager.setLogWriter(); 24 pst=conn.prepareStatement(sql); 25 //給sql語句的?賦值 26 pst.setString(1,"5"); 27 28 System.out.println("======查詢時========"); 29 ParameterMetaData pmd=pst.getParameterMetaData(); 30 System.out.println("參數數量" + pmd.getParameterCount()); 31 //1表示入參,2表示出入參,3表示出參(主要用於存儲過程) 32 System.out.println("第一個參數mode:"+pmd.getParameterMode(1)); 33 34 //數據庫操做方式1 35 boolean res=pst.execute(); 36 rs=null; 37 if(res){ 38 rs=pst.getResultSet(); 39 }else{ 40 System.out.println("返回影響的行數:"+pst.getUpdateCount()); 41 return; 42 } 43 44 //數據庫操做方式2 45 //int resCount= pst.executeUpdate(); 46 //數據庫操做方式3 47 //rs= pst.executeQuery(); 48 49 System.out.println("======查詢後========"); 50 ResultSetMetaData rsm=rs.getMetaData(); 51 System.out.println("列數量:"+rsm.getColumnCount()); 52 System.out.println("第1列別名:"+rsm.getColumnLabel(1)); 53 System.out.println("第1列字段名:"+rsm.getColumnName(1)); 54 55 User user=null; 56 while(rs.next()){ 57 user=new User(); 58 user.setId(rs.getLong("sid")); 59 user.setName(rs.getString("name")); 60 user.setAge(rs.getInt("age")); 61 } 62 System.out.println("查詢數據:"+user.toString()); 63 }catch (Exception e){ 64 e.printStackTrace(); 65 }finally { 66 //6.釋放資源 67 if(rs!=null){ 68 rs.close(); 69 } 70 if(pst!=null){ 71 pst.close(); 72 } 73 if(conn!=null){ 74 conn.close(); 75 } 76 } 77 78 }
執行結果:源碼分析
demo解析:性能
驅動的註冊(第12,14,16行):ui
不要被這個高大上的名詞迷惑了,其實就是將MySql包中Driver這個類載入虛擬機,而後執行相應的動做。spa
那麼執行的是什麼動做呢?3d
MySql Driver.java看源碼:code
1 package com.mysql.cj.jdbc; 2 3 import java.sql.SQLException; 4 5 public class Driver extends NonRegisteringDriver implements java.sql.Driver { 6 7 static { 8 try { 9 java.sql.DriverManager.registerDriver(new Driver()); 10 } catch (SQLException E) { 11 throw new RuntimeException("Can't register driver!"); 12 } 13 } 14 15 16 public Driver() throws SQLException { 17 // Required for Class.forName().newInstance() 18 } 19 }
static塊在類載入的時候就會執行,執行的是jdk中DriverManager.registerDriver()註冊服務的方法。
Driver也繼承了 java.sql.Driver.這也應驗的網上處處都說的:jdbc提供接口,數據庫廠商提供實現的說法。
從上面的驅動源碼分析第12,14,16行三種方式,哪種註冊寫法更好呢?
第12行直接經過反射把驅動類載入虛擬機,可是並無建立任何的對象;
第14行經過new 一個匿名對象來載入驅動類,同時在堆內存中還須要開闢一個內存空間;
第16行也是建立了一個匿名對象,只不過是經過反射的方式,比new 稍微慢那麼一丟丟,一樣須要虛擬機在堆中開闢內存空間;
由於咱們並不須要這個匿名對象,一段時間事後就會被虛擬機給回收掉。
經過分析仍是第12行的寫法最完美,其實不管用哪一種方式註冊服務,對於性能和時間上來講都是微乎其微的。
數據庫的三種操做方式:
int executeUpdate():執行寫sql的操做,好比insert,update,delete;返回受影響的行數。對於建立數據庫,刪表的操做返回0
ResultSet executeQuery():執行select查詢操做的方法。返回查詢結果集
boolean execute();包含上面兩種操做。查詢後返回true,表示pst.getResultSet()有值,不然無值。