JDBC是一組能夠執行SQL語句的API
由於傳統的數據庫操作方式需要程序員掌握各個不同的數據庫的API,極其不便
因此java定義了JDBC這一標准的接口和類,為程序員操作數據庫提供了統一的方式
JDBC的操作方式比較單一,由五個流程組成:
1.通過數據庫廠商提供的JDBC類庫向DriverManager注冊數據庫驅動
2.使用DriverManager提供的getConnection()方法連接到數據庫
3.通過數據庫的連接對象的createStatement方法建立SQL語句對象
4.執行SQL語句,並將結果集合返回到ResultSet中
5.使用while循環讀取結果
6.關閉數據庫資源
下面來看看具體操作Mysql數據庫的方法
准備工作
首先我們需要建立一個數據庫和一張簡單的表
mysql> create database person; Query OK, 1 row affected (0.00 sec) mysql> use person; Database changed mysql> create table student( -> id int, -> name varchar(20), -> birth year -> ) default charset=utf8; Query OK, 0 rows affected (0.10 sec)
然后往里面插入幾條數據
mysql> insert into student values -> (1,'張三',1990), -> (2,'李四',1991), -> (3,'王五',1992); Query OK, 3 rows affected (0.02 sec) Records: 3 Duplicates: 0 Warnings: 0
這樣一張簡單的表就建好了
mysql> select * from student; +------+--------+-------+ | id | name | birth | +------+--------+-------+ | 1 | 張三 | 1990 | | 2 | 李四 | 1991 | | 3 | 王五 | 1992 | +------+--------+-------+ 3 rows in set (0.00 sec)
接下來,去mysql官網下載數據庫連接器這個包
其中這個包里面含有一份文檔,里面列舉了基本的使用方法,可以參考
我們的操作也是按照這份文檔中的內容進行,然后最主要的地方就是導入這個jar包

為了操作方便,這里使用eclipse來導入
右鍵項目-->構件路徑-->添加外部歸檔,添加好了之后如下所示

現在我們正式開始使用java來操作mysql數據庫
JDBC操作
實例1:最簡單的查詢操作
import java.sql.*; public class Demo { //為了代碼緊湊性,暫時拋出所有異常 public static void main(String[] args) throws Exception { //注冊數據庫驅動 Class.forName("com.mysql.jdbc.Driver"); //建立數據庫連接 //參數一:jdbc:mysql//地址:端口/數據庫,參數二:用戶名,參數三:密碼 Connection conn = DriverManager.getConnection ("jdbc:mysql://localhost:3306/person","root","admin"); //創建SQL語句 Statement st = conn.createStatement(); //執行語句,返回結果 ResultSet rt = st.executeQuery("show tables"); //循環取出結果 while(rt.next()) { //獲取字段 System.out.println(rt.getString("Tables_in_person")); } //關閉資源,最先打開的最后關 rt.close(); st.close(); conn.close(); } }
運行結果:student
如此便可執行show tables語句查詢出當前數據庫含有多少張表
其中rt.getString()方法是獲取字段,這點需要注意
關閉資源的方式也與以往相反
不過,上面的操作方式靈活性不大,並且不嚴謹
實例2:優化的查詢操作
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Demo { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/person"; String user = "root"; String pwd = "admin"; String sql = "select * from student"; Connection conn = null; Statement st = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url,user,pwd); st = conn.createStatement(); //執行查詢語句,另外也可以用execute(),代表執行任何SQL語句 rs = st.executeQuery(sql); while(rs.next()) { System.out.println(rs.getObject(1) + " " + rs.getObject(2) + " " + rs.getInt("birth")); } //分別捕獲異常 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { //判斷資源是否存在 if(rs != null) { rs.close(); //顯示的設置為空,提示gc回收 rs = null; } if(st != null) { st.close(); st = null; } if(conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } } }
運行結果:

這里把異常給分別捕獲了,並且相關的字符串全部用變量定義
需要注意下循環取出數據里面的getInt()方法,此處必須知道類型和字段才能取出
如果不知道可以使用getObject(1)取出第一列,getObject(2)取出第二列,以此類推
實例3:自定義變量插入到數據庫
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class Demo { public static void main(String[] args) { //參數檢查 if (args.length != 3) { System.out.println("參數形式不對"); System.exit(0); } String id = args[0]; String name = args[1]; String birth = args[2]; String sql = "insert into student values(" + id + ",'" + name + "'," + "'" + birth + "')"; System.out.println(sql); String url = "jdbc:mysql://localhost:3306/person"; String user = "root"; String pwd = "admin"; Connection conn = null; Statement st = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url,user,pwd); st = conn.createStatement(); //注意,此處是excuteUpdate()方法執行 st.executeUpdate(sql); //分別捕獲異常 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if(st != null) { st.close(); st = null; } if(conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } } }
運行結果:

這里運行需要設置自變量,窗口中右鍵-->運行方式-->運行配置
然后在自變量里面寫4 susan 1993,我沒有寫中文,因為產生亂碼,目前還不清楚原因
需要注意的是,執行插入的SQL語句比較難寫,最好是打印出SQL語句用以檢查
實例4:PreparedStatement應用
從上面的Demo可以看到,插入數據的時候,SQL操作相當不便
這里可以使用PreparedStatement對象來簡化SQL語句的建立
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class Demo { public static void main(String[] args) { if (args.length != 3) { System.out.println("參數形式不對"); System.exit(0); } String id = args[0]; String name = args[1]; String birth = args[2]; String url = "jdbc:mysql://localhost:3306/person"; String user = "root"; String pwd = "admin"; Connection conn = null; //聲明PreparedStatement對象的引用 PreparedStatement pst = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url,user,pwd); //使用?代替變量 pst = conn.prepareStatement("insert into student values (?,?,?)"); //給指定參數的位置設定變量 pst.setString(1, id); pst.setString(2, name); pst.setString(3, birth); pst.executeUpdate(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if(pst != null) { pst.close(); pst = null; } if(conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } } }
運行結果:

實例5:Batch批處理
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class Demo { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/person"; String user = "root"; String pwd = "admin"; Connection conn = null; Statement st = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url,user,pwd); st = conn.createStatement(); //添加批處理 st.addBatch("insert into student values(6,'Jerry','1995')"); st.addBatch("insert into student values(7,'Greg','1996')"); st.addBatch("insert into student values(8,'Ryan','1997')"); //執行批處理 st.executeBatch(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if(st != null) { st.close(); st = null; } if(conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } } }
運行結果:

批處理比較簡單,只需先建立Statement對象,然后逐個添加批處理即可
最后使用executeBatch()方法執行批處理
此外,PreparedStatement對象也可以使用批處理
PreparedStatement ps = conn.prepareStatement("insert into student values(?,?,?)");
ps.setInt(1,8);
ps.setString(2,"GG");
ps.setString(3,"1996");
ps.addBatch();
ps.executeBatch();
實例6:Transaction事務處理
事務處理是要求sql以單元的形式更新數據庫,要求其確保一致性
如銀行的轉賬業務,一方轉出后,另一方則增加
如果出現異常,那么所有的操作則會回滾
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class Demo { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/person"; String user = "root"; String pwd = "admin"; Connection conn = null; Statement st = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url,user,pwd); //取消自動提交 conn.setAutoCommit(false); st = conn.createStatement(); st.addBatch("insert into student values(6,'Jerry','1995')"); st.addBatch("insert into student values(7,'Greg','1996')"); st.addBatch("insert into student values(8,'Ryan','1997')"); st.executeBatch(); //提交后設置自動提交 conn.commit(); conn.setAutoCommit(true); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); if(conn != null) { try { //出現異常則回滾操作,然后設置自動提交 conn.rollback(); conn.setAutoCommit(true); } catch (SQLException e1) { e1.printStackTrace(); } } } finally { try { if(st != null) { st.close(); st = null; } if(conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } } }
運行結果:

