Java開發系列--JDBC


經過對前面代碼的分析,會發現如下幾個問題:java

Url、User、Password直接在代碼中定義,若是數據庫服務器稍做變更,怎麼辦?mysql

一個項目基本針對一個底層數據庫,難道每次操做數據庫,都要註冊一次驅動程序嘛?是否能夠只註冊一次?sql

獲取數據庫鏈接時,每次都須要Url、User、Password,一旦改動其中一個數據,意味着要修改全部此處的代碼。數據庫

釋放資源,每次數據庫操做後,都須要釋放資源,難道每次操做後都要寫三次try close catch代碼嘛?緩存


若是要解決上面的幾個問題,那麼就要對剛纔的代碼實現封裝,而且把數據庫的配置放到配置文件(Properties)中,具體作法以下:服務器

新建jdbc.properties,ide



內容以下:性能

[plain] view plain copyurl

  1. #數據庫鏈接配置  spa

  2. driverClassName=com.mysql.jdbc.Driver  

  3. url=jdbc:mysql://127.0.0.1:3306/lcma?characterEncoding=utf-8  

  4. user=root  

  5. password=iflytek  


新建一個JdbcUtil類,實現代碼以下:

[java] view plain copy

  1. import java.io.InputStream;  

  2. import java.sql.Connection;  

  3. import java.sql.DriverManager;  

  4. import java.sql.ResultSet;  

  5. import java.sql.SQLException;  

  6. import java.sql.Statement;  

  7. import java.util.Properties;  

  8.   

  9. public class JdbcUtil {  

  10.   

  11.     private static String url;  

  12.     private static String user;  

  13.     private static String password;  

  14.       

  15.     static{  

  16.         //使用properties加載屬性文件  

  17.         Properties prop = new Properties();  

  18.         try {  

  19.             InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("com/iflytek/jdbc.properties");  

  20.             prop.load(is);  

  21.             //註冊驅動(獲取屬性文件中的數據)  

  22.             String driverClassName = prop.getProperty("driverClassName");  

  23.             Class.forName(driverClassName);  

  24.             //獲取屬性文件中的url,username,password  

  25.             url = prop.getProperty("url");  

  26.             user = prop.getProperty("user");  

  27.             password = prop.getProperty("password");  

  28.         } catch (Exception e) {  

  29.             e.printStackTrace();  

  30.         }  

  31.     }  

  32.       

  33.     //獲取數據庫鏈接  

  34.     public static Connection getConnection(){  

  35.         Connection conn = null;  

  36.         try {  

  37.             conn = DriverManager.getConnection(url, user, password);  

  38.         } catch (SQLException e) {  

  39.             e.printStackTrace();  

  40.         }  

  41.         return conn;  

  42.     }  

  43.       

  44.     //釋放資源  

  45.     public static void close(Connection conn, Statement stat, ResultSet rs){  

  46.          if(conn != null){  

  47.              try {conn.close();} catch (SQLException e) {e.printStackTrace();}  

  48.          }  

  49.          if(stat != null){  

  50.              try {stat.close();} catch (SQLException e) {e.printStackTrace();}  

  51.          }  

  52.          if(rs != null){  

  53.              try {rs.close();} catch (SQLException e) {e.printStackTrace();}  

  54.          }  

  55.     }  

  56. }  


在加載配置文件的時候使用了靜態代碼塊,代表類一加載,配置文件就會立馬加載,屬性被保存在靜態變量中(url,user,password)。

獲取數據庫鏈接和釋放資源都採用了靜態方法,經過類直接調用改方法,實現了公用代碼的封裝,下降的代碼的耦合性。

這時候咱們再來看JDBC獲取數據庫數據代碼:

[java] view plain copy

  1. Connection conn = null;  

  2. Statement stat = null;  

  3. ResultSet rs = null;  

  4. try{  

  5.     //經過JdbcUtil獲取數據庫連接  

  6.     conn = JdbcUtil.getConnection();  

  7.     stat = conn.createStatement();  

  8.     rs = stat.executeQuery("select * from student");  

  9.     while(rs.next()){  

  10.          System.out.println(rs.getString("name"));  

  11.     }  

  12. }catch(Exception e){  

  13.     e.printStackTrace();  

  14. }finally {  

  15.     //經過JdbcUtil關閉資源  

  16.     JdbcUtil.close(conn, stat, rs);  

  17. }  

經過如今的代碼能夠看出,代碼簡介了不少,沒有出現容易出錯的配置,獲取鏈接,加載配置文件,關閉資源咱們也不須要關心,大大下降了代碼的耦合性,提升了代碼重用性。

封裝事後的代碼仍是有些問題,就是採用了Statement對數據庫操做,若是如今SQL語句須要傳入變量,只有採用拼接的方式,這樣作有不少缺點,例如拼接容易出錯或容易產生SQL注入等。

經過PreparedStatement對數據庫操做能夠解決Statement帶來的缺點,PreparedStatement和Statement區別以下:

Statement的缺點:

一樣的SQL語句,每次都要發送,不能進行有效的緩存。

拼接SQL字符串很是容易出現錯誤。

不能防止惡意數據,易產生SQL注入。

升級後的新接口PreparedStatement(推薦):

預編譯SQL語句,並進行有效的緩存,性能更好。

容許使用問號佔位符參數,而且該參數必須得到值後才能夠執行。

無需拼接SQL語句。

問號佔位符參數:INSERTINTO User(id,name,age,birthday)VALUES(?,?,?,?); 

來看一下經過PreparedStatement對數據庫操做的代碼:

[java] view plain copy

  1. Connection conn = null;  

  2. PreparedStatement stat = null;  

  3. ResultSet rs = null;  

  4. try{  

  5.         //經過JdbcUtil獲取數據庫連接  

  6.     conn = JdbcUtil.getConnection();  

  7.     stat = conn.prepareStatement("select * from student where name like ? and age = ? ");  

  8.     stat.setString(1"%小%");  

  9.     stat.setInt(222);  

  10.     rs = stat.executeQuery();  

  11.     while(rs.next()){  

  12.            System.out.println(rs.getString("name"));  

  13.     }  

  14.     }catch(Exception e){  

  15.            e.printStackTrace();  

  16.     }finally {  

  17.         //經過JdbcUtil關閉資源  

  18.         JdbcUtil.close(conn, stat, rs);  

  19.     }  

  20. }  


注意如下兩點:


1.問號佔位符不能加引號。

2.佔位符參數設置值從下標從1開始。


轉載url:http://blog.csdn.net/mlc1218559742/article/details/52216895

相關文章
相關標籤/搜索