1. 程式人生 > >Jdbc進階(四)

Jdbc進階(四)

***************************資料庫的隔離級別****************************

mysql 資料庫 這4種隔離級別都支援 預設的隔離級別 可重複讀

oracle 只支援 讀已提交、序列化 預設的隔離級別是 讀已提交

 

一.讀未提交

會出現髒讀


客戶端A 修改了資料 沒提交 ,其他客戶端也可以讀到,讀未提交....


髒讀: 經理(客戶端A)發工資 本來要發5000,不小心多打1個0,發了50000,但是沒提交,

客戶端B(楊帆)一查,可以查到,挺高興,剛準備去消費,消費的路上,經理馬上反應過來了,立馬回滾


從新插入一條5000的記錄,楊帆再一查5000,資料不一致, 這種不一致的現象叫做髒讀...


讀的是臨時的不準確的資料!!!

 

***************************批量更新****************************


每次呼叫 executeUpdate() 執行一條SQL語句 都要通過網路 把sql語句傳送到資料庫伺服器 再返回

效率比較低


可以把多條語句 加入到 Batch裡, executeBatch() 就把這些sql語句 都發送伺服器端一起執行了,效率高


返回值是int[]


JDK8.0新增的功能

long count = stmt.executeLargeUpdate();//如果一條sql語句影響行數比較多 超過int型別的表數範圍 使用這個方法

同樣批量更新時 如果每條sql語句 影響的行數 都超過int型別表數範圍 使用

long[] longArr = stmt.executeLargeBatch();


演示程式碼:


public void testBatchUpdate() {

Statement stmt = null;
try {

String sql1 = "insert into account values(1,'楊帆1',1000)";
String sql2 = "insert into account values(2,'楊帆2',2000)";

String sql3 = "insert into account values(3,'楊帆3',3000)";
String sql4 = "insert into account values(4,'楊帆4',4000)";

stmt = conn.createStatement();
boolean autoCommit = conn.getAutoCommit();

conn.setAutoCommit(false);
// 收集多條SQL語句 等待一起傳送
stmt.addBatch(sql1);
stmt.addBatch(sql2);
stmt.addBatch(sql3);
stmt.addBatch(sql4);

int[] countArr = stmt.executeBatch();

for (int i = 0; i < countArr.length; i++) {
System.out.println("第" + i + "條SQL語句受影響的行數為:" + countArr[i]);
}

conn.commit();

conn.setAutoCommit(autoCommit);
System.out.println("批量更新成功");
} catch (SQLException e) {
try {
conn.rollback();

System.out.println("批量更新失敗");
} catch (SQLException e1) {

e1.printStackTrace();
}
System.out.println("建立通道失敗");
e.printStackTrace();
} catch (Exception e) {
try {
conn.rollback();

System.out.println("批量更新失敗");
} catch (SQLException e1) {

e1.printStackTrace();
}
System.out.println("建立通道失敗");
e.printStackTrace();
} finally {
// 五.關閉
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
System.out.println("關閉pstmt通道失敗");
e.printStackTrace();
}
}

if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("關閉資料庫連線失敗");
e.printStackTrace();
}
}
}


***************************資料庫連線池****************************


一.為什麼使用資料庫連線池


每次執行增刪改查操作的時候 都要從新建立連線、關閉連線,比較耗時,效率低.為了提高效率,有了資料庫連線池的概念


二.什麼是資料庫連線池


在應用程式(或web伺服器)啟動的時候, 事先建立好n個數據庫連線物件,並把這些物件放到一個容器中,以備使用.這個容器

叫做資料庫連線池. 使用者用的時候 不需要建立連線,直接從連線池中取出一個Connection物件來用就可以了,用完以後也不需要

關閉,直接把Connection物件 還到資料庫連線池中..大大的減少了頻繁建立、關閉連線所浪費的時間.


javax.sql.DataSource 資料來源 它是一個介面 不同產生有對該介面的不同實現,常見的第三方資料來源

1.DBCP

2.C3P0

三.如何使用

DBCP

匯入兩個jar包

commons-dbcp.jar
commons-pool.jar

commons-dbcp.jar 依賴於 commons-pool.jar

 

 

package com.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbcp.BasicDataSource;

/**
* 公司:藍橋軟體學院
* 作者:zhangzy
* 時間:2017年9月1日 下午5:31:26
* 功能:資料庫連線池 DBCP實現
*/
public class ConnOracleDataSource {

private static BasicDataSource dataSource = new BasicDataSource();


private static String driverClassName = "oracle.jdbc.OracleDriver";
private static String url = "jdbc:oracle:thin:@localhost:1521:orcl";
private static String username = "scott";
private static String password = "tiger";


static{

dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);

//1.設定Conn物件的初始個數
dataSource.setInitialSize(5);
//2.設定最大的活動連線數
dataSource.setMaxActive(20);
//3.設定最少空閒數
dataSource.setMinIdle(2);
}

public static Connection getConnection(){
Connection conn = null;

try {
conn = dataSource.getConnection();
} catch (SQLException e) {
System.out.println("建立連線失敗");
e.printStackTrace();
}


return conn;
}

public static void closeConnection(ResultSet rs,Statement stmt,Connection conn){

if(rs!=null){
try {
rs.close();
} catch (SQLException e) {

e.printStackTrace();
}
}

if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
System.out.println("關閉通道失敗");
e.printStackTrace();
}
}

if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
System.out.println("關閉資料庫連線失敗");
e.printStackTrace();
}
}

}

public static void main(String[] args) {
System.out.println(ConnOracleDataSource.getConnection());
}
}

 

測試效率:


public static void main(String[] args) {
long startTime = System.currentTimeMillis();

for (int i = 1; i <= 100; i++) {

CategoryDaoImpl dao = new CategoryDaoImpl();

Category category = new Category();

category.setCname("手機");
category.setCdesc("通訊工具");

dao.addCategory(category);
}

long endTime = System.currentTimeMillis();

System.out.println("總共使用了" + (endTime - startTime) + "毫秒");

}