JDBC編程步驟
下面以mysql數據庫為例,
1.加載驅動
首先需要下載數據庫的驅動jar文件,並且在eclipse包中加入到class path中去, 例如mysql的驅動文件 mysql-connector-java-5.1.23-bin.jar
然后就可以在java程序中用反射加載驅動
1 Class.forName("com.mysql.jdbc.Driver");
2.獲取數據庫連接,即Connectiond對象
使用java.sql.DriverManager的getConnection(String url, String user, String pass)方法獲取數據庫連接Connectiond對象
1 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/dedecms","root","");
3.通過Connectiond創建statement對象,用來執行SQL
通常有三種statement對象,
- createStatement() , 創建普通的statement對象,可以直接執行sql語句
- prepareStatement(String sql) , 創建預編譯的statement對象,支持sql語句帶參數
- prepareCall(String sql) , 創建能執行存儲過程的statement對象
4.執行SQL語句,所有statement對象都有三個執行sql的方法
- execute()可執行任何SQL語句返回boolean,表示是否返回了數據,需要通過statement對象的getResultSet()方法才能獲取結果集,通過statement的getUpdateCount()方法獲取影響條數
- executeQuery()返回ResultSet
- executeUpdate()執行SQL語句返回受影響記錄數
5.操作結果集ResultSet
next(), previous(), first(), last(), beforeFirst(), afterLast(), absolute() 可以進行行移動
getXxx(...)可以在具體行上面,獲取指定列的值,參數可以是數字索引或者是列名
6.回收數據庫資源
關閉ResultSet, Statement, Connection
下面演示一下JDBC的常用編程步驟,
1 package db; 2 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 9 public class ConnMySQL { 10 public static void connMySQL() throws ClassNotFoundException, SQLException { 11 Class.forName("com.mysql.jdbc.Driver"); 12 try ( 13 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/dedecms","root",""); 14 Statement stmt = conn.createStatement(); 15 /* 16 * Statement有三種執行SQL的方法 17 * 1.execute()可執行任何SQL語句返回boolean 18 * 2.executeQuery()返回ResultSet 19 * 3.executeUpdate()執行DML語句返回受影響記錄數 20 */ 21 ResultSet rs = stmt.executeQuery("select * from dede_addoninfos")) { 22 //ResultSet通過next()能向前迭代,通過各種getXxx()方法獲取對應字段值 23 while(rs.next()) { 24 System.out.println(rs.getInt(1)+"\t | "+rs.getInt(2) + "\t | "+rs.getInt(3) + "\t |"+rs.getString("title")); 25 } 26 } 27 } 28 29 public static void main(String[] args) throws SQLException, ClassNotFoundException { 30 connMySQL(); 31 } 32 }
上面程序的第14行,可以使用createStatement() 或者prepareStatement()兩種方式創建statement對象,其中第二種支持帶參數sql的預編譯
在第21行,則可以使用execute(), executeQuery(), executeUpdate()三種方式執行SQL,只不過第一種返回boolean,第二種返回結果集,第三種返回記錄數
在第24行,既可以用rs.getString(7)這種方式取值,也可以用rs.getString("title")這種方式取值
上面執行結果如下,
1 99 | 9 | -8 |武漢地區招聘dedecms網頁美工 2 100 | 9 | -8 |吉林地區 禮聘 PHP程序員 網頁設計師 系統運維工程師 薪酬面議 3 101 | 9 | -8 |4000每月 招聘dede二次開發程序一名 4 102 | 9 | -8 |尊米網誠聘全職PHP程序員(廣州) 5 103 | 9 | -8 |《每日商報》招聘PHP程序員、網頁設計師 6 104 | 9 | -8 |招聘PHP程序員3名底薪3000起 +獎金 (包吃住) 7 105 | 9 | -8 |佰邦達科技(北京)有限公司招聘PHP開發工程師
下面演示兩種Statement對比以及兩種執行SQL的用法,
mysql的jdbc配置如下,
1 driver=com.mysql.jdbc.Driver 2 url=jdbc:mysql://127.0.0.1:3306/dedecms?useUnicode=true&characterEncoding=utf8 3 user=root 4 pass=
1 package db; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 import java.sql.PreparedStatement; 9 import java.sql.ResultSet; 10 import java.sql.ResultSetMetaData; 11 import java.sql.SQLException; 12 import java.sql.Statement; 13 import java.util.Properties; 14 15 public class ExecuteSQL { 16 private String driver; 17 private String url; 18 private String user; 19 private String pass; 20 public void initParam(String paramFile) throws FileNotFoundException, IOException, ClassNotFoundException { 21 //用Properties類加載屬性文件 22 Properties prop = new Properties(); 23 prop.load(new FileInputStream(paramFile)); 24 driver = prop.getProperty("driver"); 25 url = prop.getProperty("url"); 26 user = prop.getProperty("user"); 27 pass = prop.getProperty("pass"); 28 Class.forName(driver); 29 } 30 public void createTable(String sql) throws SQLException, ClassNotFoundException { 31 try ( 32 Connection conn = DriverManager.getConnection(url, user, pass); 33 Statement stmt = conn.createStatement()) { 34 //執行DDL語句,創建數據表 35 stmt.executeUpdate(sql); 36 } 37 38 } 39 public int insertData(String sql) throws SQLException, ClassNotFoundException { 40 try ( 41 Connection conn = DriverManager.getConnection(url, user, pass); 42 Statement stmt = conn.createStatement()) { 43 //執行DML語句,插入數據 44 return stmt.executeUpdate(sql); 45 } 46 } 47 48 public void executeSQL(String sql) throws ClassNotFoundException, SQLException { 49 try ( 50 Connection conn = DriverManager.getConnection(url, user, pass); 51 Statement stmt = conn.createStatement()) { 52 //execute()返回boolean,true表示有ResultSet, falseb表示沒有 53 boolean hasResultSet = stmt.execute(sql); 54 if (hasResultSet) { 55 try ( 56 // 獲取結果集 57 ResultSet rs = stmt.getResultSet()) { 58 //ResultSetMetaData是用於分析結果集的接口 59 ResultSetMetaData rsmd = rs.getMetaData(); 60 int columnCount = rsmd.getColumnCount(); 61 while(rs.next()) { 62 for(int i = 0; i < columnCount; i++) { 63 System.out.print(rs.getString(i + 1) + "\t"); 64 } 65 System.out.print("\n"); 66 } 67 } 68 } else { 69 System.out.println("該SQL執行結果影響的記錄條數有 "+ stmt.getUpdateCount() + " 條"); 70 } 71 } 72 } 73 74 public void insertUseStatement() throws SQLException, ClassNotFoundException { 75 long start = System.currentTimeMillis(); 76 try ( 77 Connection conn = DriverManager.getConnection(url, user, pass); 78 Statement stmt = conn.createStatement()) { 79 for (int i = 0 ; i < 10 ; i++) { 80 stmt.executeUpdate("insert into jdbc_test values(" 81 + " null ,'title"+i+"','content"+i+"')"); 82 } 83 System.out.println("使用Statement費時:"+(System.currentTimeMillis()-start)); 84 } 85 } 86 87 public void insertUsePrepare() throws ClassNotFoundException, SQLException { 88 long start = System.currentTimeMillis(); 89 try ( 90 Connection conn = DriverManager.getConnection(url, user, pass); 91 PreparedStatement pstmt = conn.prepareStatement("insert into jdbc_test values(null,?,?)")) { 92 93 94 for (int i = 0 ; i < 10 ; i++) { 95 //序號1,2表示sql中第幾個參數 96 pstmt.setString(1, "title"+i); 97 pstmt.setString(2, "content"+i); 98 pstmt.executeUpdate(); 99 } 100 101 System.out.println("使用PreparedStatement費時:"+(System.currentTimeMillis()-start)); 102 } 103 } 104 105 public static void main(String[] args) throws ClassNotFoundException, SQLException, FileNotFoundException, IOException { 106 ExecuteSQL es = new ExecuteSQL(); 107 es.initParam("mysql.ini"); 108 /* 109 es.createTable("create table jdbc_test " 110 + "(jdbc_id int auto_increment primary key, " 111 + "jdbc_name varchar(255), " 112 + "jdbc_desc text) CHARSET=utf8;"); 113 System.out.println("=================建表成功================="); 114 */ 115 116 /* 117 int result = es.insertData("insert into jdbc_test (jdbc_name, jdbc_desc) " 118 + " select title, body from dede_addoninfos;"); 119 System.out.println("====共有 "+result+" 條記錄受影響==="); 120 */ 121 122 //es.executeSQL("select * from jdbc_test"); 123 es.insertUseStatement(); 124 es.insertUsePrepare(); 125 } 126 }
上面程序的insertUseStatement()和insertUsePrepare()分別用了普通的statement和preparestatement,
preparestatement可以支持參數形式,因此不需要拼接參數,省去了麻煩而且更安全(SQL注入)
多次執行程序會發現preparestatement的性能要高很多。