JDBC是鏈接數據庫和Java程序的橋樑,經過JDBC API能夠方便地實現對各類主流數據庫的操做。本篇將介紹一下如何使用JDBC操做數據庫(以MySQL爲例)。java
JDBC制定了統一訪問各種關係數據庫的標準接口,爲各個數據庫廠商提供了標準接口的實現。mysql
JDBC規範將驅動程序歸結爲如下幾類(選自Core Java Volume Ⅱ——Advanced Features):sql
咱們須要訪問數據庫時,首先要加載數據庫驅動,只需加載一次,而後在每次訪問數據庫時建立一個Connection實例,獲取數據庫鏈接,獲取鏈接後,執行須要的SQL語句,最後完成數據庫操做時釋放與數據庫間的鏈接。數據庫
Java加載數據庫驅動的方法是調用Class類的靜態方法forName(),語法格式以下:緩存
Class.forName(String driverManager)
例如加載MySQL數據庫驅動以下:服務器
try { Class.forName("com.mysql.jdbc.Driver"); } catch(ClassNotFoundException e) { e.printStackTrace(); }
若是加載成功,會將加載的驅動類註冊給DriverManager;若是加載失敗,會拋出ClassNotFoundException異常。mybatis
須要注意的是,要在項目中導入mysq-connection-java的jar包,方法是在項目中創建lib目錄,在其下放入jar包。sqlserver
右鍵jar包 Build Path->Add to Build Path。測試
以後會多出一個Referenced Libraries,導入成功。ui
加載完數據庫驅動後,就能夠創建數據庫的鏈接了,須要使用DriverManager類的靜態方法getConnection()方法來實現。以下:
Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/database_name"; String user = "root"; Strign password = "root" //創建鏈接 Connection conn = DriverManager.getConnection(url, user, password);
url是數據庫的url,其中mysql指定數據庫爲mysql數據庫,localhost是本地計算機,能夠換成IP地址127.0.0.1,3306爲MySQL數據庫的默認端口號,database_name是所要鏈接的數據庫名;user和password對應數據庫的用戶名和密碼;最後再經過getConnection創建鏈接。
創建了鏈接以後,就可使用Connection接口的createStatement()方法來獲取Statement對象,也能夠調用prepareStatement()方法得到PrepareStatement對象,經過executeUpdate()方法來執行SQL語句。
先看一個查詢的。
1 import java.sql.Statement; 2 import java.sql.Connection; 3 import java.sql.DriverManager; 4 import java.sql.ResultSet; 5 import java.sql.SQLException; 6 7 public class JDBCTest { 8 9 public static void main(String[] args) throws ClassNotFoundException, SQLException { 10 //鏈接數據庫 11 Class.forName("com.mysql.jdbc.Driver"); 12 String url = "jdbc:mysql://127.0.0.1:3306/mybatis_test"; 13 String user = "root"; 14 String password = "123456"; 15 16 //創建數據庫鏈接 17 Connection conn = DriverManager.getConnection(url, user, password); 18 19 String sql = "select * from user"; 20 Statement stmt = conn.createStatement(); //建立一個statement對象 21 ResultSet rs = stmt.executeQuery(sql); //執行查詢 22 23 int id, sex; 24 String username, address; 25 System.out.println("id\t姓名\t性別\t地址\t"); 26 27 while(rs.next()) { //遍歷結果集 28 id = rs.getInt("id"); 29 username = rs.getString("username"); 30 sex = rs.getInt("sex"); 31 address = rs.getString("address"); 32 System.out.println(id + "\t" + username + "\t" + sex + "\t" + address); 33 } 34 } 35 36 }
運行結果以下:
通常在數據庫中咱們將性別寫爲數字,而後用Java語言進行轉換,好比上述運行結果,1表明男性、2表明女性、0表明未知,咱們修改sex = rs.getInt("sex");這行代碼以下:
sex = rs.getInt("sex"); if(sex == 1) { _sex = "男"; } else if(sex == 2) { _sex = "女"; } else { _sex = "未知"; }
首先在while循環的外面加上String _sex,在輸出中將sex改成_sex便可,運行結果以下:
對於插入,咱們可使用Statement接口中的executeUpdate()方法,以下:
String sql = "insert into user(username, sex, address) values('張三','1','陝西西安')"; Statement stmt = conn.createStatement(); //建立一個Statement對象 stms.executeUpdate(sql); //執行SQL語句 conn.close(); //關閉數據庫鏈接對象
還可使用PreparedStatement接口中的executeUpdate()方法,以下:
String sql = "insert into user(username, sex, address) values(?,?,?)"; PreparedStatement ps = conn.preparedStatement(sql); ps.setString(1, "張三"); //爲第一個問號賦值 ps.setInt(2, 2); //爲第二個問號賦值 ps.setString(3, "陝西西安"); //爲第三個問號賦值 ps.executeUpdate(); conn.close();
修改同插入,也有上述兩種方法,只需更改sql語句便可。
刪除也是一個很經常使用的操做,使用executeUpdate()方法執行用來作刪除的SQL語句,方法同上方Statement接口的操做。
下面給一個完整的例子,該例子的數據庫配置文件在外部的properties中,該例子以SQL Server爲例,其它的數據庫都是一樣的道理。
用於編寫數據庫配置文件,不直接寫在程序中的好處是提升了靈活性,若是須要修改數據庫名稱或配置等信息,能夠在這裏修改,無需改動程序。
1 driver = com.microsoft.sqlserver.jdbc.SQLServerDriver 2 url = jdbc:sqlserver://127.0.0.1:1433;DatabaseName=TTMS 3 username = root 4 password = root
編寫JDBC代碼。
1 import java.io.*; 2 import java.sql.Connection; 3 import java.sql.DriverManager; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.Properties; 9 10 public class DBUtil { 11 private final String dbConnFile = "resource/database/jdbc.properties"; 12 private Connection conn=null; 13 private String dbDriver; //定義驅動 14 private String dbURL; //定義URL 15 private String userName; //定義用戶名 16 private String password; //定義密碼 17 18 //從配置文件取數據庫連接參數 19 private void loadConnProperties(){ 20 Properties props = new Properties(); 21 try { 22 props.load(new FileInputStream(dbConnFile));//根據配置文件路徑Conf加載配置文件 23 } catch (FileNotFoundException e) { 24 e.printStackTrace(); 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 this.dbDriver = props.getProperty("driver");//從配置文件中取得相應的參數並設置類變量 29 this.dbURL = props.getProperty("url"); 30 this.userName = props.getProperty("username"); 31 this.password = props.getProperty("password"); 32 33 } 34 35 public boolean openConnection(){ 36 try { 37 loadConnProperties(); 38 Class.forName(dbDriver); 39 this.conn = DriverManager.getConnection(dbURL,userName,password); 40 return true; 41 } catch(ClassNotFoundException classnotfoundexception) { 42 classnotfoundexception.printStackTrace(); 43 System.err.println("db: " + classnotfoundexception.getMessage()); 44 } catch(SQLException sqlexception) { 45 System.err.println("db.getconn(): " + sqlexception.getMessage()); 46 } 47 return false; 48 } 49 50 51 protected void finalize() throws Exception{ 52 try { 53 if(null!=conn) 54 conn.close(); 55 }catch (SQLException e) { 56 e.printStackTrace(); 57 } 58 59 } 60 61 // 查詢並獲得結果集 62 public ResultSet execQuery(String sql) throws Exception { 63 ResultSet rstSet = null; 64 try { 65 if (null == conn) 66 throw new Exception("Database not connected!"); 67 Statement stmt = conn.createStatement(); 68 rstSet = stmt.executeQuery(sql); 69 } catch (SQLException e) { 70 e.printStackTrace(); 71 } 72 return rstSet; 73 } 74 75 // 插入一條新紀錄,並獲取標識列的值 76 public ResultSet getInsertObjectIDs(String insertSql) throws Exception{ 77 ResultSet rst = null; 78 try { 79 if(null==conn) 80 throw new Exception("Database not connected!"); 81 82 Statement stmt = conn.createStatement(); 83 84 stmt.executeUpdate(insertSql, Statement.RETURN_GENERATED_KEYS); 85 rst = stmt.getGeneratedKeys(); 86 87 } catch (SQLException e) { 88 e.printStackTrace(); 89 } 90 return rst; 91 } 92 93 //以參數SQL模式插入新紀錄,並獲取標識列的值 94 public ResultSet getInsertObjectIDs(String insertSql, Object[] params) throws Exception { 95 ResultSet rst = null; 96 PreparedStatement pstmt = null ; 97 try { 98 if (null == conn) 99 throw new Exception("Database not connected!"); 100 pstmt = conn.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS); 101 102 if(null != params){ 103 for (int i = 0; i < params.length; i++) { 104 pstmt.setObject(i + 1, params[i]); 105 } 106 } 107 pstmt.executeUpdate(); 108 rst = pstmt.getGeneratedKeys(); 109 } catch (SQLException e) { 110 e.printStackTrace(); 111 } 112 return rst; 113 } 114 115 116 117 // 插入、更新、刪除 118 public int execCommand(String sql) throws Exception{ 119 int flag = 0; 120 try { 121 if(null==conn) 122 throw new Exception("Database not connected!"); 123 124 Statement stmt = conn.createStatement(); 125 flag = stmt.executeUpdate(sql); 126 127 stmt.close(); 128 } catch (SQLException e) { 129 e.printStackTrace(); 130 } 131 return flag; 132 } 133 134 /* // 存儲過程調用 135 public void callStordProc(String sql, Object[] inParams, SqlParameter[] outParams) throws Exception { 136 CallableStatement cst = null ; 137 try { 138 if (null == conn) 139 throw new Exception("Database not connected!"); 140 cst = conn.prepareCall(sql); 141 142 if(null != inParams){ 143 for (int i = 0; i < inParams.length; i++) { 144 cst.setObject(i + 1, inParams[i]); 145 } 146 } 147 148 if (null!=outParams){ 149 for (int i = 0; i < inParams.length; i++) { 150 cst.registerOutParameter(outParams[i].getName(), outParams[i].getType()); 151 } 152 } 153 cst.execute(); 154 } catch (SQLException e) { 155 e.printStackTrace(); 156 } 157 } 158 */ 159 // 釋放資源 160 public void close(ResultSet rst) throws Exception { 161 try { 162 Statement stmt = rst.getStatement(); 163 rst.close(); 164 stmt.close(); 165 } catch (SQLException e) { 166 e.printStackTrace(); 167 } 168 } 169 170 public PreparedStatement execPrepared(String psql) throws Exception { 171 PreparedStatement pstmt = null ; 172 try { 173 if (null == conn) 174 throw new Exception("Database not connected!"); 175 pstmt = conn.prepareStatement(psql); 176 } catch (SQLException e) { 177 e.printStackTrace(); 178 } 179 return pstmt; 180 } 181 182 183 // 釋放資源 184 public void close(Statement stmt) throws Exception { 185 try { 186 stmt.close(); 187 } catch (SQLException e) { 188 e.printStackTrace(); 189 } 190 } 191 192 // 釋放資源 193 public void close() throws SQLException, Exception{ 194 if(null!=conn){ 195 conn.close(); 196 conn=null; 197 } 198 } 199 200 public Connection getConn() { 201 return conn; 202 } 203 204 205 public static void main(String[] args) { 206 207 } 208 }
測試程序。
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.InputStream; 5 import java.sql.ResultSet; 6 7 import java.sql.Blob; 8 9 10 public class DBUtil_TestDriver { 11 12 //測試通常數據寫入 13 private static void test_insert(){ 14 DBUtil db = new DBUtil(); 15 db.openConnection(); 16 String sql = "insert into studio(studio_name, studio_row_count, studio_col_count, studio_introduction )" 17 + " values(?,?, ?, ?)"; 18 Object [] params = new Object[4]; 19 params[0]=new String("test2"); 20 params[1]=new Integer(2); 21 params[2]=new Integer(2); 22 params[3]=new String("just a test"); 23 try { 24 ResultSet rst= db.getInsertObjectIDs(sql, params); 25 26 if (rst!=null && rst.first()) { 27 System.out.println(rst.getInt(1)); 28 } 29 30 db.close(rst); 31 db.close(); 32 33 } catch (Exception e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 } 37 38 } 39 40 //測試lob數據寫入 41 private static void test_insert_lob(){ 42 43 String sql = "insert into play(play_type_id, play_lang_id, play_name, play_ticket_price, play_image )" 44 + " values(?,?, ?, ?, ?)"; 45 Object [] params = new Object[5]; 46 params[0]=null; 47 params[1]=null; 48 params[2]=new String("just a test"); 49 params[3]=new Float(5); 50 51 FileInputStream fis = null; 52 File file = new File("resource/image/header.jpg"); //測試寫圖片 53 54 try { 55 DBUtil db = new DBUtil(); 56 db.openConnection(); 57 fis = new FileInputStream(file); 58 params[4]=fis; 59 60 ResultSet rst= db.getInsertObjectIDs(sql, params); 61 62 if (rst!=null && rst.first()) { 63 System.out.println(rst.getInt(1)); 64 } 65 66 db.close(rst); 67 db.close(); 68 69 } catch (Exception e) { 70 // TODO Auto-generated catch block 71 e.printStackTrace(); 72 } 73 74 } 75 76 //測試lob數據讀取 77 private static void test_read_lob(){ 78 String sql = "select * from play"; 79 80 FileInputStream fis = null; 81 82 try { 83 DBUtil db = new DBUtil(); 84 db.openConnection(); 85 ResultSet rst = db.execQuery(sql); 86 if (rst!=null) { 87 while(rst.next()){ 88 System.out.println(rst.getString("play_name")); 89 System.out.println(rst.getFloat("play_ticket_price")); 90 int playID=rst.getInt("play_id"); 91 92 byte[] buf = new byte[256]; 93 Blob blob = rst.getBlob("play_image"); 94 if(blob!=null ){ 95 //須要在在工程目錄下創建路徑Cache/Play_Image/,而後將照片緩存到該路徑下 96 File file = new File("Cache/Play_Image/"+ playID + ".jpg"); 97 FileOutputStream sout = new FileOutputStream(file); 98 InputStream in = blob.getBinaryStream();//獲取BLOB數據的輸入數據流 99 100 for (int i = in.read(buf); i != -1;) { 101 sout.write(buf); 102 i = in.read(buf); 103 } 104 in.close(); 105 sout.close(); 106 } 107 108 } 109 } 110 111 db.close(rst); 112 db.close(); 113 114 } catch (Exception e) { 115 // TODO Auto-generated catch block 116 e.printStackTrace(); 117 } 118 119 } 120 121 public static void main(String[] args) { 122 // TODO Auto-generated method stub 123 //test_insert(); 124 test_insert_lob(); 125 test_read_lob(); 126 } 127 128 }
至於數據庫sql文件可自行設計,這裏就再也不編寫了。