您好,登錄后才能下訂單哦!
執行 SELECT * FROM userifo_fury 生成一個執行計劃再次執行SELECT * FROM userifo_fury 就會重用上面的執行計劃(因為這是靜態的SQL語句
但是,執行INSERT INTO userifo VALUES(1, 'JACK','122314','141234@QQ.COM','FURY',15600) ) 生成一個執行計劃,再執行執行INSERT INTO userifo VALUES(2, 'rose','122314','141234@QQ.COM','FURY',15600)由于內容不同,會再次生成另外一個執行計劃,若執行1000次上述情況的INSERT,數據庫會產生1000個執行計劃,這樣就嚴重影響了數據庫的效率
因此,Statement只適合執行靜態的SQL語句,不適合執行動態的SQL語句
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 }
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"); // 加載數據庫驅動23 24 conn = DriverManager.getConnection( // 初始化連接對象25 "jdbc:mysql://localhost:3306/test", "root", "182838");26 27 28 String sql = "SELECT * FROM user WHERE pwd = ? "; // 拼接SQL語句,位置參數用?代替29 30 ps = conn.prepareStatement(sql); // 初始化預編譯執行對象31 32 ps.setString(1, "182838"); // 設置SQL語句中的位置位置參數(注意:是從1開始數不是從0開始數)33 34 rs = ps.executeQuery(); // 執行SQL語句35 36 List<User> users = new ArrayList<User>(); // 創建一個集合來存放記錄對象37 while(rs.next()) { // 遍歷結果集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 }
class Properties extends Hashtable<Object,Object>
將properties屬性文件的文件輸入流加載到Properties對象
將Properties對象中的屬性列表保存到輸出流文件中
注意:第二個參數表示注釋信息(注意:properties文件中不能用中文),在注釋信息后面會自動添加一個時間信息
注意:新創建的文件在項目的根目錄下面(問題:為什么在eclipse中沒有,但是到文件夾中卻能找到???)
獲取屬性值,參數是屬性的鍵
修改屬性值,參數1是屬性的鍵,參數2是屬性的新值
要求:讀取properties配置文件總的屬性值,將讀取到的屬性值進行修改后保存到另外一個properties配置文件中
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(); // 創建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<String> it=prop.stringPropertyNames().iterator(); // 將配置文件中的所有key放到一個可迭代對象中20 while(it.hasNext()){ // 利用迭代器模式進行迭代21 String key=it.next(); // 讀取下一個迭代對象的下一個元素22 System.out.println(key+":"+prop.getProperty(key)); // 根據key值獲取value值(獲取屬性信息)23 }24 25 is.close(); // 關閉輸入流,釋放資源26 27 FileOutputStream oFile = new FileOutputStream("b.properties", true);//創建一個輸出流文件,true表示追加打開28 prop.setProperty("maxactive", "33"); // 修改屬性信息29 prop.store(oFile, "zhe shi yi ge xin de shu xing pei zhi wen jian."); // 將Properties對象中的內容放到剛剛創建的文件中去30 oFile.close(); // 關閉輸出流,釋放資源31 32 } catch (Exception e) {33 // TODO Auto-generated catch block34 e.printStackTrace();35 } 36 }37 }
等待讀取的properties配置文件的位置如下圖所示
程序啟動時就創建足夠多的數據庫連接,并將這些連接組成一個連接池,由程序自動地對池中的連接進行申請、使用、釋放
》程序初始化時創建連接池
》需要操作數據庫時向數據庫連接池申請一個可用的數據庫連接
》使用完畢后就將數據庫連接還給數據庫連接池(注意:不是關閉連接,而是交給連接池)
》整個程序退出時,斷開所有連接,釋放資源(即:管理數據庫連接池的那個線程被殺死后才關閉所有的連接)
利用BasicDataSource對象實例化一個連接對象
將這個連接對象放到ThreadLocal對象中
從ThreadLocal對象中獲取連接對象
清空ThreadLocal對象
判斷連接對象是否釋放
項目結構圖
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
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 2 <modelVersion>4.0.0</modelVersion> 3 <groupId>cn.xiangxu</groupId> 4 <artifactId>testJDBC</artifactId> 5 <version>0.0.1-SNAPSHOT</version> 6 <dependencies> 7 <dependency> 8 <groupId>mysql</groupId> 9 <artifactId>mysql-connector-java</artifactId>10 <version>5.1.37</version>11 </dependency>12 <dependency>13 <groupId>junit</groupId>14 <artifactId>junit</artifactId>15 <version>4.12</version>16 </dependency>17 <dependency>18 <groupId>commons-dbcp</groupId>19 <artifactId>commons-dbcp</artifactId>20 <version>1.4</version>21 </dependency>22 </dependencies>23 </project>
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用于線程跨方法共享數據使用14 * ThreadLocal內部有一個Map, key為需要共享數據的線程本身,value就是其需要共享的數據15 */16 private static ThreadLocal<Connection> tl; // 聲明一個類似于倉庫的東西17 private static BasicDataSource dataSource; // 聲明一個數據庫連接池對象18 19 // 靜態代碼塊,在類加載的時候執行,而且只執行一次20 static {21 tl = new ThreadLocal<Connection>(); // 實例化倉庫對象22 dataSource = new BasicDataSource(); // 實例數據庫連接池對象23 24 Properties prop = new Properties(); // 創建一個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); // 初始化數據庫連接池(即:配置數據庫連接池的先關參數)37 dataSource.setUrl(url);38 dataSource.setUsername(username);39 dataSource.setPassword(password);40 dataSource.setMaxActive(maxActive);41 dataSource.setMaxWait(maxWait);42 43 is.close(); // 關閉輸入流,釋放資源44 } catch (IOException e) {45 // TODO Auto-generated catch block46 e.printStackTrace();47 } 48 49 }50 51 /**52 * 創建連接對象(注意:靜態方法可以直接通過類名來調用)53 * @return 連接對象54 * @throws Exception55 */56 public static Connection getConnection() throws Exception { 57 try {58 Connection conn = dataSource.getConnection(); // 創建連接對象(利用數據庫連接池進行創建)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 * 關閉連接對象(注意:靜態方法可以通過類名直接調用)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 }
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(); // 創建連接對象16 String sql = "SELECT * FROM user "; // 拼接SQL語句17 PreparedStatement ps = conn.prepareStatement(sql); // 創建執行對象18 ResultSet rs = ps.executeQuery(sql); // 執行SQL語句19 while(rs.next()) { // 遍歷結果集20 System.out.println(rs.getString("name"));21 }22 } catch (Exception e) {23 e.printStackTrace();24 } finally { // 關閉連接,釋放資源25 try {26 DBUtil.closeConnection();27 } catch (Exception e) {28 e.printStackTrace();29 }30 }31 }32 }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。