JDBC 03
2019/8/1 9:51:41
筆記網站
全球加速: http://zaixianke.com
北京節點: http://itdage.cn
JDBC 事務 ***
在dos命令行操作oracle時 , 執行DML , 需要結束事務 (commit提交 或 rollback回退)
在JDBC中, 事務是自動提交的, 每執行一條DML語句, 事務就自動提交一次.
我們可以通過JDBC的事務API , 開始事務的手動提交, 將多條DML語句看作一個整體, 要么一起成功, 要么一起失敗.
JDBC事務操作格式:
注意: 開啟事務的手動提交 ,是通過連接對象完成的. 某個數據連接對象的事務開啟手動提交后, 這個連接對象的事務需要手動控制. 其他連接對象不受影響.
操作方法:
1. 開始事務的手動提交:
conn.setAutoCommit(boolean flag);
參數含義: true表示自動提交 . false表示手動提交.
2. 提交事務:conn.commit();3. 回退事務:rollback();
事務案例:
public class Demo {public static void main(String[] args) throws Exception {//1. 加載數據庫的驅動Class.forName("oracle.jdbc.OracleDriver");//2. 獲取數據庫連接對象Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "123");//2.1 設置連接對象的事務 為 手動提交conn.setAutoCommit(false);//3. 開始描述邏輯System.out.println("金剛: 轉賬中...");//3.1 減少金剛賬戶的余額 500 | 3.1.1 預編譯SQL執行環境PreparedStatement state = conn.prepareStatement("update user33 set money=500 where id=2");//3.1.2 執行SQL語句boolean success = state.executeUpdate()>0?true:false;if(success) {System.out.println("后臺邏輯: 金剛余額減少完畢.");if(1==2) {conn.rollback();throw new RuntimeException("后臺服務器... 停電了");}//3.2 增加豪杰賬戶的余額 500 //3.2.1 預編譯SQL執行環境PreparedStatement state2 = conn.prepareStatement("update user33 set money=600 where id=1");//3.2.2 執行SQ語句boolean success2 = state2.executeUpdate()>0?true:false;if(success2) {System.out.println("后臺邏輯: 豪杰余額增加完畢");conn.commit();}state2.close();}state.close();}
}
批處理 了解
將多條SQL語句 放到一起批量處理.
批處理將多次對于數據庫的操作次數 , 減少到了一次 ! 提高了大量SQL語句一起執行時的性能.
使用步驟:
批處理使用Statement類操作步驟1. 將一條SQ語句加入到批處理中statement.addBatch(String sql);步驟2. 執行批處理中的所有語句statement.executeBatch();
批處理案例:
//1. 加載數據庫的驅動Class.forName("oracle.jdbc.OracleDriver");//2. 獲取數據庫連接對象Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "123");//3. 創建SQL的執行環境Statement state = conn.createStatement();//4. 加入SQL語句 到批處理中for(int i=0;i<1000;i++) {state.addBatch("insert into user33 values(SEQ_USER33_ID.NEXTVAL,'name"+i+"',1000)");}//5. 執行批處理state.executeBatch();state.close();conn.close();System.out.println("執行完畢");
連接池 *
概述 熟悉
由連接池創建連接, 維護連接
我們需要使用連接時, 從連接池中獲取連接.
如果池中存在空閑連接, 則拿去使用.
如果不存在空閑連接, 且池未滿 , 則在連接池中創建新的連接使用.
如果不存在空閑連接, 且池已滿 , 則排隊等待空閑連接.
Properties 文件 與 類 熟悉
properties文件 常用于Java中的配置文件.
因為Properties文件 可以快速的 與 Properties類 進行轉換.
文件:
注釋: #開頭表示注釋行
鍵值對: 鍵與值之間使用等號連接, 多個鍵值對之間使用換行分割
如何將一個Properties文件, 轉換為java中的Map集合對象:
步驟:1. 創建Properties對象Properties ppt = new Properties(); 2. 得到Properties文件的字節輸入流InputStream is = //可以通過new FileInputStream , 也可以通過ClassLoader 等等3. 將流加載到Properties對象ppt.load(is);
使用步驟: *
1. 引入相關的jar文件- dbcp : 連接池的代碼- poll : 連接池的依賴庫
-
創建一個properties文件, 描述連接池的配置 , 內容如下:
#數據庫連接地址
url=jdbc:oracle:thin:@localhost:1521:XE
#數據庫驅動地址
driverClassName=oracle.jdbc.OracleDriver
#數據庫帳號
username=system
#數據庫密碼
password=123#擴展配置:
#初始化連接池時, 創建的連接數量:
initialSize=5
#最大允許存在的連接數量
maxActive=200
#空閑時允許保留的最大連接數量
maxIdle=10
#空閑時允許保留的最小連接數量
minIdle=5
#排隊等候的超時時間
maxWait=20000 -
將properties文件, 轉換為Properties對象.
Properties ppt = new Properties();
ppt.load(文件輸入流); -
通過連接池工廠類(BasicDataSourceFactory) , 創建連接池對象 (一次程序啟動, 創建一個連接池就夠了.)
DataSource ds = BasicDataSourceFactory.createDataSource(ppt); -
通過連接池對象, 獲取池中的連接
Connection conn = ds.getConnection(); -
正常JDBC操作
連接池案例:*
//3. 將properties文件 轉換為Properties對象Properties ppt = new Properties();//4. 加載文件的輸入流InputStream is = Demo.class.getClassLoader().getResourceAsStream("dbcp.properties");//空指針異常ppt.load(is);//5. 通過工廠類, 創建連接池DataSource ds = BasicDataSourceFactory.createDataSource(ppt);//6. 通過連接池, 獲取其中的連接 , 并使用Connection conn = ds.getConnection();//正常的JDBC操作PreparedStatement state = conn.prepareStatement("insert into user33 values(seq_user33_id.nextval,'嘿嘿嘿',188)");int count = state.executeUpdate();System.out.println(count>0?"數據插入成功":"數據插入失敗");
DBCPUtil工具類 *
public class DBCPUtil {
private static DataSource dataSource;static {//在類加載時, 讀取配置文件, 配置連接池//1. 創建Properites對象Properties ppt = new Properties();//2. 讀取配置文件, InputStream is = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcp.properties");//3. 將配置文件 加載到Properties對象中try {ppt.load(is);//4. 通過連接池工廠類, 創建連接池dataSource = BasicDataSourceFactory.createDataSource(ppt);} catch (Exception e) {e.printStackTrace();} }/*** 用于從連接池中 獲取一個連接對象* @return 連接對象 , 如果獲取失敗返回null*/ public static Connection getConnection() {try {return dataSource.getConnection();} catch (Exception e) {e.printStackTrace();return null;} } /*** 用于釋放資源* @param conn 連接對象* @param state 執行環境* @param result 結果集*/ public static void close(Connection conn , Statement state ,ResultSet result) {if(result!=null) {try {result.close();} catch (SQLException e) {e.printStackTrace();}}if(state!=null) {try {state.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn!=null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }
}
數據庫優化 *
1. 在進行表格查詢時 , where子句中的條件執行順序是從左至右 , 清除數據量較大的條件應該放在左邊.(特別注意: 笛卡爾積消除條件必須放在最左邊)
-
在進行表格查詢時 , 列名列表應避免使用號 ! 數據庫在執行查詢操作時, 會先將號展開, 轉換為所有的列名, 再進行查詢.
-
在進行表格查詢時 , 能使用where條件篩選的數據, 應盡量避免使用having子句來篩選. 因為where條件執行在having之前 , 在早期篩選掉大量數據, 可以讓程序執行的更順暢.
-
在進行多表查詢時 , 查詢的表順序是從右至左的. 應把表中數據量最少的表放在查詢的最右邊.
-
在進行多表查詢時 , 應盡可能的給所有的表添加別名, 能明確的區分有沖突的列.
-
在使用事務時 , 應盡量多的commit , 盡量早的commit ! 原因是: 事務在未提交時, 數據庫會耗費大量的內存 , 來緩存未提交的SQL結果 !
-
盡可能多的使用函數 來提高SQL執行的效率.
-
SQL語句編寫時, 除字符串以外 , 應使用大寫字母 ! 因為SQL語句執行時, 會先將小寫字母 轉換為 大寫字母, 再執行.
-
應盡可能少的訪問數據庫 (多次數據訪問的結果可能相同, 如果緩存起來 ,可以提高程序的執行效率)
-
在索引列上 , 盡可能避免使用not來判斷. not關鍵字如果判斷了索引列 , 會導致此次查詢索引失效 , 轉而使用全表掃描的方式查詢.
-
在索引列上, 不能使用算數運算 , 算數運算也會導致索引列使用, 使用全表掃描的方式進行查詢.
-
在查詢數據時, 如果需要使用>或<的條件, 應替換為>= 或 <= !
原因是>和<符號 , 查詢時, 是按照>= 和 <= 進行查詢, 然后在撇去=的結果.