jdbc的五大常見應用場景

 

在實際開發工做中,有關於jdbc的應用,常常性地會出現如下五個問題:java

 

業務場景一:過濾條件比較弱,一次性可能讀出較多記錄

增長或修改查詢語句來優化查詢結果mysql

業務場景二:須要統計的記錄比較多

eg.:讀取數據庫表中全部的記錄,千萬級的記錄的讀取可能會出現java的內存溢出異常OutOfMemoryErrorsql

緣由分析:java程序是運行在java虛擬機中的,jvm是有內存大小限制的,當咱們把大量的記錄一次性地讀入jvm的內存中的時候,讀出的數據若是超出了jvm所規定的內存最大值的時候就會出現內存溢出的錯誤。數據庫

解決辦法:既然內存容量是有限的,咱們能夠讀取一部分數據進行處理,處理完畢以後在進行下一部分數據的讀取,這樣避免一次性地載入過多的數據致使內存的溢出。jvm

在jdbc中是如何具體實現的呢?優化

使用遊標:

遊標的開啓:編碼

須要在加載驅動後,得到與數據庫的鏈接的同時需啊喲啊在url後面加上?useCursorFetch=trueurl

表示咱們對這個數據庫的讀取須要使用遊標spa

要是使用有標的話,必須使用PreparedStatement 的setFetchSize();code

入參爲int型的整數,表示jdbc從數據庫中一次讀取記錄的數量,須要在查詢executeQuery以前須要設置一次查詢的記錄的數量。

import java.sql.*;

public class Test001 {
	private String driver = "com.mysql.jdbc.Driver";
	private String url = "jdbc:mysql://host:port/dataBaseName";
	private String userName = "xxx";
	private String passWord = "xxx";
	
	public void Test() {
		Connection connection = null;
		String sql = null;
		PreparedStatement prepareStatement = null;
		ResultSet rs = null;
		try {
			//裝載驅動
			Class.forName(driver);	
			//獲取鏈接
			connection = DriverManager.getConnection(url,userName,passWord);
			//變動url設置
			url = url + "userCursorFecth = true";
			//sql語句
			sql = "select * from tableName where sex = Female";
			//執行sql語句
			prepareStatement = connection.prepareStatement(sql);
			//設置遊標讀取參數
			prepareStatement.setFetchSize(1);
			//執行查詢語句,返回結果集
			rs = prepareStatement.executeQuery();
			//取結果集
			while(rs.next()) {
				System.out.println(rs.getString(1));
			}
			//此時的執行結果的按照設置的參數進行結果的操做,一條條地處理
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != connection) 
				connection.close();
				if (null != rs) 
					rs.close();
				if (null != prepareStatement)
					prepareStatement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

 

業務場景三:大對象讀取

讀取的每一條記錄中包含大字段的內容,在實際開發過程當中,爲了方便管理,每每數據記錄會包含大字段的內容,讀取可能會出現內存溢出。

處理方式:流方式讀取

jdbc的實現:

ResultSet.getBinaryStream()獲取流

 

rs = prepareStatement.executeQuery();
			//取結果集
			while(rs.next()) {
				System.out.println(rs.getString(1));
				
				InputStream in = rs.getBinaryStream(1);
				File file = new File(File_URL);
				OutputStream out = null;
				out = new FileOutputStream(file);
				int temp = 0;
				while ((temp = in.read()) != -1) {
					out.write(temp);
				}
				in.close();
				out.close();
			}

 

業務場景四:大量數據插入

海量的數據插入,若是一條條的插入,每一次的sql語句的發送與接收都須要時間

 

更加高效的使用方式爲

批處理:

發送一次sql 插入多條語句

Statement提供了三個接口:

addbatch()

executeBatch()

clearBatch()

遍歷須要插入的元素,將其放入batch中,而後執行executeBatch最後執行clearBatch()。

Set<String> users = new HashSet<String>();  
			String user1 = "zhangsan";
			String user2 = "lisi";
			String  user3 = "zhaowu";	
			users.add(user1);
			users.add(user2);
			users.add(user3);
			
			Statement statement = connection.createStatement();
			String sql2 = "insert into tableName(user)values(";
			for (String user : users) {
				statement.addBatch(sql + user + ")");
			}
			statement.executeBatch();
			statement.clearBatch();

 

業務場景五:字符編碼問題

涉及到中文,須要注意可能出現的亂碼問題

能夠設置不一樣級別的代碼:server級別,database級別,table級別, 字段級別,

優先級依次增大,好比設置列級別的編碼,那麼其餘三個就不會生效。

Server-->Database-->Table-->column

咱們須要設置jdbc的編碼方式來適應數據庫的編碼方式,設置方式也很簡單,須要在url中增長

例如 :      url = url +"characterEncoding=utf8";

相關文章
相關標籤/搜索