真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JDBC02利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

1 使用Statement執(zhí)行含有動態(tài)信息的SQL語句時有幾個不足:

  1.1 由于需要將動態(tài)數(shù)據(jù)拼接到SQL語句中,這導(dǎo)致程序復(fù)雜度高,容易出錯
  1.2 拼接的數(shù)據(jù)若含有SQL語法內(nèi)容就會導(dǎo)致拼接后的SQL語法含義改變而出現(xiàn)SQL注入***
  1.3 當(dāng)大批量執(zhí)行語義相同,但是含有動態(tài)數(shù)據(jù)的SQL時效率很差

 

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:主機域名、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、南湖網(wǎng)站維護、網(wǎng)站推廣。

2 使用Statement執(zhí)行SQL語句不好的原因

  2.1 當(dāng)執(zhí)行一條SQL語句發(fā)送到數(shù)據(jù)庫時,數(shù)據(jù)庫先將該SQL解析并生成一個執(zhí)行計劃(這個過程會消耗資源和性能),如果多次執(zhí)行一樣的SQL語句,數(shù)據(jù)庫會重用執(zhí)行計劃,但是若多次執(zhí)行語義相同但是含有動態(tài)數(shù)據(jù)的SQL時,數(shù)據(jù)庫會生成不同的執(zhí)行計劃,嚴重影響數(shù)據(jù)庫的開銷
  2.2 例如

執(zhí)行 SELECT * FROM userifo_fury 生成一個執(zhí)行計劃再次執(zhí)行SELECT * FROM userifo_fury 就會重用上面的執(zhí)行計劃(因為這是靜態(tài)的SQL語句 

但是,執(zhí)行INSERT INTO userifo VALUES(1, 'JACK','122314','141234@QQ.COM','FURY',15600) ) 生成一個執(zhí)行計劃,再執(zhí)行執(zhí)行INSERT INTO userifo VALUES(2, 'rose','122314','141234@QQ.COM','FURY',15600)由于內(nèi)容不同,會再次生成另外一個執(zhí)行計劃,若執(zhí)行1000次上述情況的INSERT,數(shù)據(jù)庫會產(chǎn)生1000個執(zhí)行計劃,這樣就嚴重影響了數(shù)據(jù)庫的效率
    因此,Statement只適合執(zhí)行靜態(tài)的SQL語句,不適合執(zhí)行動態(tài)的SQL語句

3 利用PreparedStatement代替Statement

  編寫簡單

  沒有SQL注入問題

  批量執(zhí)行語義相同的SQL語句會重用執(zhí)行計劃

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 1 package cn.xiangxu.entity; 2  3 import java.io.Serializable; 4  5 public class User implements Serializable { 6  7     private static final long serialVersionUID = -5109978284633713580L; 8      9     private Integer id;10     private String name;11     private String pwd;12     public User() {13         super();14         // TODO Auto-generated constructor stub15     }16     public User(Integer id, String name, String pwd) {17         super();18         this.id = id;19         this.name = name;20         this.pwd = pwd;21     }22     @Override23     public int hashCode() {24         final int prime = 31;25         int result = 1;26         result = prime * result + ((id == null) ? 0 : id.hashCode());27         return result;28     }29     @Override30     public boolean equals(Object obj) {31         if (this == obj)32             return true;33         if (obj == null)34             return false;35         if (getClass() != obj.getClass())36             return false;37         User other = (User) obj;38         if (id == null) {39             if (other.id != null)40                 return false;41         } else if (!id.equals(other.id))42             return false;43         return true;44     }45     public Integer getId() {46         return id;47     }48     public void setId(Integer id) {49         this.id = id;50     }51     public String getName() {52         return name;53     }54     public void setName(String name) {55         this.name = name;56     }57     public String getPwd() {58         return pwd;59     }60     public void setPwd(String pwd) {61         this.pwd = pwd;62     }63     @Override64     public String toString() {65         return "User [id=" + id + ", name=" + name + ", pwd=" + pwd + "]";66     }67     68     69 70 }

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 1 package testJDBC; 2  3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.util.ArrayList; 9 import java.util.List;10 11 import org.junit.Test;12 13 import cn.xiangxu.entity.User;14 15 public class TestCase {16     @Test17     public void test01() {18         Connection conn = null;19         PreparedStatement ps = null;20         ResultSet rs = null;21         try {22             Class.forName("com.MySQL.jdbc.Driver"); // 加載數(shù)據(jù)庫驅(qū)動23             24             conn = DriverManager.getConnection( // 初始化連接對象25                     "jdbc:mysql://localhost:3306/test", "root", "182838");26             27             28             String sql = "SELECT * FROM user WHERE pwd = ? "; // 拼接SQL語句,位置參數(shù)用?代替29             30             ps = conn.prepareStatement(sql); // 初始化預(yù)編譯執(zhí)行對象31             32             ps.setString(1, "182838"); // 設(shè)置SQL語句中的位置位置參數(shù)(注意:是從1開始數(shù)不是從0開始數(shù))33             34             rs = ps.executeQuery(); // 執(zhí)行SQL語句35             36             List users = new ArrayList(); // 創(chuàng)建一個集合來存放記錄對象37             while(rs.next()) { // 遍歷結(jié)果集38 //                System.out.println("====================");39 //                System.out.println(rs.getInt("id"));40 //                System.out.println(rs.getString("name"));41 //                System.out.println(rs.getString("pwd"));42                 User user = new User();43                 user.setId(rs.getInt("id"));44                 user.setName(rs.getString("name"));45                 user.setPwd(rs.getString("pwd"));46                 users.add(user); // 向集合中添加元素47             }48             49             System.out.println(users); // 打印輸出集合50             for(User user : users) {51                 System.out.println(user);52             }53             54             // 釋放資源55             rs.close();56             ps.close(); 
57             conn.close();58             59         } catch (Exception e) {60             // TODO Auto-generated catch block61             e.printStackTrace();62         } finally {63             if(rs != null) {64                 try {65                     rs.close();66                 } catch (SQLException e) {67                     // TODO Auto-generated catch block68                     e.printStackTrace();69                 }70             }71             if(ps != null) {72                 try {73                     ps.close();74                 } catch (SQLException e) {75                     // TODO Auto-generated catch block76                     e.printStackTrace();77                 }78             }79             if(conn != null) {80                 try {81                     conn.close();82                 } catch (SQLException e) {83                     // TODO Auto-generated catch block84                     e.printStackTrace();85                 }86             }87         }88         89     }90     91 }

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 

4 利用Properties對象讀取properties配置文件中的信息

  4.1 Properties繼承了Hashtable類,Properties對象也是使用鍵值對的方式來保存數(shù)據(jù),但是Properties對象的鍵和值都是字符串類型

class Properties extends Hashtable

  4.2 Properties 類中的主要方法

    4.2.1 public synchronized void load(InputStream inStream) throws IOException

將properties屬性文件的文件輸入流加載到Properties對象

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

    4.2.2 public void store(OutputStream out, String comments) throws IOException

       將Properties對象中的屬性列表保存到輸出流文件中

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

注意:第二個參數(shù)表示注釋信息(注意:properties文件中不能用中文),在注釋信息后面會自動添加一個時間信息

注意:新創(chuàng)建的文件在項目的根目錄下面(問題:為什么在eclipse中沒有,但是到文件夾中卻能找到???)

    4.2.3 public String getProperty(String key)

獲取屬性值,參數(shù)是屬性的鍵

     4.2.4 public synchronized Object setProperty(String key, String value)

修改屬性值,參數(shù)1是屬性的鍵,參數(shù)2是屬性的新值

  4.3 案例

要求:讀取properties配置文件總的屬性值,將讀取到的屬性值進行修改后保存到另外一個properties配置文件中

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 1 package cn.xiangxu.entity; 2  3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.InputStream; 6 import java.util.Iterator; 7 import java.util.Properties; 8  9 public class Test {10     public static void main(String[] args) {11         try {12             Properties prop = new Properties(); // 創(chuàng)建Properties對象13             14 //            prop.load(new FileInputStream("config.properties")); // 使用這種方式時,配置文件必須放在項目的根目錄下15             InputStream  is = Test.class.getClassLoader().getResourceAsStream("config/config.properties"); // 讀取屬性文件16             17             prop.load(is); // 加載屬性列表18             19             Iterator it=prop.stringPropertyNames().iterator(); // 將配置文件中的所有key放到一個可迭代對象中20             while(it.hasNext()){ // 利用迭代器模式進行迭代21                 String key=it.next(); // 讀取下一個迭代對象的下一個元素22                 System.out.println(key+":"+prop.getProperty(key)); // 根據(jù)key值獲取value值(獲取屬性信息)23             }24             25             is.close(); // 關(guān)閉輸入流,釋放資源26             27             FileOutputStream oFile = new FileOutputStream("b.properties", true);//創(chuàng)建一個輸出流文件,true表示追加打開28             prop.setProperty("maxactive", "33"); // 修改屬性信息29             prop.store(oFile, "zhe shi yi ge xin de shu xing pei zhi wen jian."); // 將Properties對象中的內(nèi)容放到剛剛創(chuàng)建的文件中去30             oFile.close(); // 關(guān)閉輸出流,釋放資源31             32         } catch (Exception e) {33             // TODO Auto-generated catch block34             e.printStackTrace();35         } 
36     }37 }

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

等待讀取的properties配置文件的位置如下圖所示

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 

5 數(shù)據(jù)庫連接池

  5.1 什么是數(shù)據(jù)庫連接池

程序啟動時就創(chuàng)建足夠多的數(shù)據(jù)庫連接,并將這些連接組成一個連接池,由程序自動地對池中的連接進行申請、使用、釋放

  5.2 數(shù)據(jù)庫連接池的運行機制

》程序初始化時創(chuàng)建連接池

》需要操作數(shù)據(jù)庫時向數(shù)據(jù)庫連接池申請一個可用的數(shù)據(jù)庫連接

》使用完畢后就將數(shù)據(jù)庫連接還給數(shù)據(jù)庫連接池(注意:不是關(guān)閉連接,而是交給連接池)

》整個程序退出時,斷開所有連接,釋放資源(即:管理數(shù)據(jù)庫連接池的那個線程被殺死后才關(guān)閉所有的連接)

     JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

  5.3 數(shù)據(jù)庫連接池的編程步驟

    5.3.1 導(dǎo)包

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

    5.3.2 聲明ThreadLocal、BasicDataSource成員變量(注意:這兩個成員變量是靜態(tài)的)

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

    5.3.3 在靜態(tài)代碼塊中實例化那兩個成員變量,并通過Properties對象讀取配置文件信息,利用這些配置文件信息給BasicDataSource對象進行初始化處理

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

    5.3.4 編寫創(chuàng)建連接靜態(tài)方法

利用BasicDataSource對象實例化一個連接對象

將這個連接對象放到ThreadLocal對象中

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

    5.3.5 編寫釋放連接靜態(tài)方法

從ThreadLocal對象中獲取連接對象

清空ThreadLocal對象

判斷連接對象是否釋放

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 

6 利用數(shù)據(jù)庫連接池操作數(shù)據(jù)庫

項目結(jié)構(gòu)圖

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

1 # zhe shi zhu shi , yi ban bu yong zhong wen 
2 # deng hao liang bian mei you kong ge, mo wei mei you fen hao3 # hou mian bu neng you kong ge4 driverClassName=com.mysql.jdbc.Driver5 url=jdbc:mysql://localhost:3306/test6 username=root7 password=1828388 maxActive=1009 maxWait=3000

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 1  2   4.0.0 3   cn.xiangxu 4   testJDBC 5   0.0.1-SNAPSHOT 6    7        8           mysql 9           mysql-connector-java10           5.1.3711       12       13           junit14           junit15           4.1216       17       18           commons-dbcp19           commons-dbcp20           1.421       22   23 

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 1 package cn.xiangxu.tools; 2  3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.sql.Connection; 6 import java.sql.SQLException; 7 import java.util.Properties; 8  9 import org.apache.commons.dbcp.BasicDataSource;10 11 public class DBUtil {12     /*13      * ThreadLocal用于線程跨方法共享數(shù)據(jù)使用14      * ThreadLocal內(nèi)部有一個Map,  key為需要共享數(shù)據(jù)的線程本身,value就是其需要共享的數(shù)據(jù)15      */16     private static ThreadLocal tl; // 聲明一個類似于倉庫的東西17     private static BasicDataSource dataSource; // 聲明一個數(shù)據(jù)庫連接池對象18     19     // 靜態(tài)代碼塊,在類加載的時候執(zhí)行,而且只執(zhí)行一次20     static {21         tl = new ThreadLocal(); // 實例化倉庫對象22         dataSource = new BasicDataSource(); // 實例數(shù)據(jù)庫連接池對象23 24         Properties prop = new Properties(); // 創(chuàng)建一個Properties對象用(該對象可以用來加載配置文件中的屬性列表)25         InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("config/mysql.properties"); // 讀取配置文件信息26         try {27             prop.load(is); // 加載配置文件中的屬性列表28             29             String driverClassName = prop.getProperty("driverClassName"); // 獲取屬性信息30             String url = prop.getProperty("url");31             String username = prop.getProperty("username");32             String password = prop.getProperty("password");33             Integer maxActive = Integer.parseInt(prop.getProperty("maxActive"));34             Integer maxWait = Integer.parseInt(prop.getProperty("maxWait"));35             36             dataSource.setDriverClassName(driverClassName); // 初始化數(shù)據(jù)庫連接池(即:配置數(shù)據(jù)庫連接池的先關(guān)參數(shù))37             dataSource.setUrl(url);38             dataSource.setUsername(username);39             dataSource.setPassword(password);40             dataSource.setMaxActive(maxActive);41             dataSource.setMaxWait(maxWait);42             43             is.close(); // 關(guān)閉輸入流,釋放資源44         } catch (IOException e) {45             // TODO Auto-generated catch block46             e.printStackTrace();47         } 
48         49     }50     51     /**52      * 創(chuàng)建連接對象(注意:靜態(tài)方法可以直接通過類名來調(diào)用)53      * @return 連接對象54      * @throws Exception55      */56     public static Connection getConnection() throws Exception { 
57         try {58             Connection conn = dataSource.getConnection(); // 創(chuàng)建連接對象(利用數(shù)據(jù)庫連接池進行創(chuàng)建)59             tl.set(conn); // 將連接對象放到倉庫中60             return conn; 
61         } catch (Exception e) {62             // TODO Auto-generated catch block63             e.printStackTrace();64             throw e;65         }66     }67     68     /**69      * 關(guān)閉連接對象(注意:靜態(tài)方法可以通過類名直接調(diào)用)70      * @throws Exception71      */72     public static void closeConnection() throws Exception {73         Connection conn = tl.get(); // 從倉庫中取出連接對象74         tl.remove(); // 清空倉庫75         if(conn != null) { // 判斷連接對象是否釋放資源76             try {77                 conn.close();78             } catch (Exception e) {79                 // TODO Auto-generated catch block80                 e.printStackTrace();81                 throw e;82             }83         }84     }85 86 }

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

JDBC02 利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】

 1 package testJDBC; 2  3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6  7 import org.junit.Test; 8  9 import cn.xiangxu.tools.DBUtil;10 11 public class TestDBUtil {12     @Test13     public void test01() {14         try {15             Connection conn = DBUtil.getConnection(); // 創(chuàng)建連接對象16             String sql = "SELECT * FROM user "; // 拼接SQL語句17             PreparedStatement ps = conn.prepareStatement(sql); // 創(chuàng)建執(zhí)行對象18             ResultSet rs = ps.executeQuery(sql); // 執(zhí)行SQL語句19             while(rs.next()) { // 遍歷結(jié)果集20                 System.out.println(rs.getString("name"));21             }22         } catch (Exception e) {23             e.printStackTrace();24         } finally {  // 關(guān)閉連接,釋放資源25             try {26                 DBUtil.closeConnection();27             } catch (Exception e) {28                 e.printStackTrace();29             }30         }31     }32 }

分享標題:JDBC02利用JDBC連接數(shù)據(jù)庫【使用數(shù)據(jù)庫連接池】
標題網(wǎng)址:http://weahome.cn/article/pjdgoc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部