1. 程式人生 > >JavaEE_ JDBC操作MySQL資料庫 (進階篇)

JavaEE_ JDBC操作MySQL資料庫 (進階篇)


JDBC連線資料庫   

•建立一個以JDBC連線資料庫的程式,包含7個步驟:   

 1、載入JDBC驅動程式:     

         在連線資料庫之前,首先要載入想要連線的資料庫的驅動到JVM(Java虛擬機器),   

 這通過java.lang.Class類的靜態方法forName(String  className)實現。  

例如:

try{   
	//載入MySql的驅動類   
	Class.forName("com.mysql.jdbc.Driver") ;   
}catch(ClassNotFoundException e){   
	System.out.println("找不到驅動程式類 ,載入驅動失敗!");   
	e.printStackTrace() ;   
} 

成功載入後,會將Driver類的例項註冊到DriverManager類中。 


 2、提供JDBC連線的URL   

•連線URL定義了連線資料庫時的協議、子協議、資料來源標識。   

•書寫形式:協議:子協議:資料來源標識   

        協議:在JDBC中總是以jdbc開始   

        子協議:是橋連線的驅動程式或是資料庫管理系統名稱。   

        資料來源標識:標記找到資料庫來源的地址與連線埠。   

例如:(MySql的連線URL  jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk ;   

         useUnicode=true:表示使用Unicode字符集。

        characterEncoding=gbk:字元編碼方式。

        如果characterEncoding設定為 gb2312或GBK,本引數必須設定為true 。

     
 3、建立資料庫的連線 

•要連線資料庫,需要向java.sql.DriverManager請求並獲得Connection物件, 該物件就代表一個數據庫的連線。   

•使用 DriverManager的getConnectin( String url , String username , String password )方法

        傳入指定的欲連線的資料庫的路徑、資料庫的使用者名稱和密碼來獲得。

例如:

//連線MySql資料庫,使用者名稱和密碼都是root   
	String url = "jdbc:mysql://localhost:3306/test" ;    
	String username = "root" ;   
	String password = "root" ;   
	try{   
		Connection con = DriverManager.getConnection(url , username , password ) ;   
	}catch(SQLException se){   
		System.out.println("資料庫連線失敗!");   
		se.printStackTrace() ;   
	} 
 4、建立一個Statement   

•要執行SQL語句,必須獲得java.sql.Statement例項,Statement例項分為以下3 種類型:   

      1、執行靜態SQL語句。通常通過Statement例項實現。   

      2、執行動態SQL語句。通常通過PreparedStatement例項實現。   

      3、執行資料庫儲存過程。通常通過CallableStatement例項實現。   

 具體的實現方式:   

Statement stmt = con.createStatement() ;   
PreparedStatement pstmt = con.prepareStatement(sql) ;   
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;   
 5、執行SQL語句   

Statement介面提供了三種執行SQL語句的方法:executeQuery 、executeUpdate  和execute。   

1、ResultSet executeQuery(String sqlString):執行查詢資料庫的SQL語句 ,返回一個結果集(ResultSet)物件。   

2、int executeUpdate(String sqlString):用於執行INSERT、UPDATE或   DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等   

3、execute(sqlString):用於執行返回多個結果集、多個更新計數或二者組合的 語句。   

具體實現的程式碼:

	ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;   
	int rows = stmt.executeUpdate("INSERT INTO ...") ;   
	boolean flag = stmt.execute(String sql) ;   


 6、處理結果   

兩種情況:   

     1、執行更新返回的是本次操作影響到的記錄數。   

      2、執行查詢返回的結果是一個ResultSet物件。   

• ResultSet包含符合SQL語句中條件的所有行,並且它通過一套get方法提供了對這些行中資料的訪問。

• 使用結果集(ResultSet)物件的訪問方法獲取資料:   

while(rs.next()){   
	String name = rs.getString("name") ;   
	String pass = rs.getString(1) ; // 此方法比較高效   
} 

(列是從左到右編號的,並且從列1開始) 

 7、關閉JDBC物件    

操作完成以後要把所有使用的JDBC物件全都關閉,以釋放JDBC資源,關閉順序和聲 明順序相反:   

     1、關閉記錄集   

     2、關閉宣告   

     3、關閉連線物件

if(rs != null){   // 關閉記錄集   
	try{   
		rs.close() ;   
	}catch(SQLException e){   
		e.printStackTrace() ;   
	}   
}   
if(stmt != null){   // 關閉宣告   
	try{   
		stmt.close() ;   
	}catch(SQLException e){   
		e.printStackTrace() ;   
	}   
}   
if(conn != null){  // 關閉連線物件   
	try{   
		conn.close();   
	}catch(SQLException e){   
		e.printStackTrace() ;   
	}   
} 

一個簡單的示例:

進一步的封裝:

package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;


public class MysqlUtilNew {
	
	private static String driver = "com.mysql.cj.jdbc.Driver";
	private static String dbName = "test";
	private static String passwrod = "test";
	private static String userName = "test";
	private static String url = "jdbc:mysql://dxx.xxxx.cn:3610/" + dbName;

	private static Connection conn = null;

	private PreparedStatement ps = null;
	private ResultSet rs = null;

	static {
		initConn();
	}

	private static void initConn() {
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, userName, passwrod);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void closeConn() {
		// 關閉連結物件
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public MysqlUtilNew() {

	}

	public void releaseRes() {
		try {
			if (rs != null) {
				this.rs.close();
			}
			if (ps != null) {
				this.ps.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			// 關閉記錄集
			if (this.rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			// 關閉宣告
			if (this.ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void prePareQuery(String sql) {
		try {
			this.ps = conn.prepareStatement(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public ResultSet execPreQueryWithParms(Object... objs) {

		try {
			for (int i = 0; i < objs.length; i++) {
				if (objs[i] instanceof Integer) {
					int it = ((Integer) objs[i]).intValue();
					this.ps.setInt(i + 1, it);
				} else if (objs[i] instanceof String) {
					String s = (String) objs[i];
					this.ps.setString(i + 1, s);
				} else if (objs[i] instanceof Double) {
					double d = ((Double) objs[i]).doubleValue();
					this.ps.setDouble(i + 1, d);
				} else if (objs[i] instanceof Float) {
					float f = ((Float) objs[i]).floatValue();
					this.ps.setFloat(i + 1, f);
				} else if (objs[i] instanceof Long) {
					long l = ((Long) objs[i]).longValue();
					this.ps.setLong(i + 1, l);
				} else if (objs[i] instanceof Boolean) {
					boolean b = ((Boolean) objs[i]).booleanValue();
					this.ps.setBoolean(i + 1, b);
				} else if (objs[i] instanceof Date) {
					Date d = (Date) objs[i];
					java.sql.Date date = new java.sql.Date(d.getTime());
					this.ps.setDate(i + 1, (java.sql.Date) date);
				}
			}
			this.rs = ps.executeQuery();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}

	public ResultSet execQuery(String sql, Object... objs) {
		this.prePareQuery(sql);
		this.rs = this.execPreQueryWithParms(objs);
		return rs;
	}

	public static void main(String[] args) {
		MysqlUtilNew test = new MysqlUtilNew();
		Object[] params = { 14089 };
		ResultSet rs = test.execQuery(
				"SELECT * FROM conf_location WHERE country = ? LIMIT 1", params);
		try {
			while (rs.next()) {
				System.out.println("country_name : "
						+ rs.getString("country_name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		test.releaseRes();

		MysqlUtilNew test2 = new MysqlUtilNew();
		Object[] params2 = { 14089 };
		ResultSet rs2 = test.execQuery(
				"SELECT * FROM conf_location WHERE region = ? LIMIT 1", 0);
		try {
			while (rs2.next()) {
				System.out.println("region_name : "
						+ rs2.getString("region_name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		test2.releaseRes();
	}
}


Maven 依賴:

 <dependencies>
	<dependency>
	  <groupId>commons-io</groupId>
	  <artifactId>commons-io</artifactId>
	  <version>2.4</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
	<dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>6.0.6</version>
	</dependency>
  </dependencies>


遇到的問題:

Java與mysql資料庫程式設計中遇見“Before start of result set at com.mysql.jdbc.SQLError.createSQLException” 

        這個Bug是因為在取出ResultSet物件,對其進行操作時,沒有采用.next()方法將ResultSet物件的游標移至指定行,

不管Statement物件執行SQL語句是否十分確定能搜出記錄,也不可以在沒有ResultSet的next()方法之前直接對 ResultSet物件進行取值

相關推薦

JavaEE_ JDBC操作MySQL資料庫

JDBC連線資料庫    •建立一個以JDBC連線資料庫的程式,包含7個步驟:     1、載入JDBC驅動程式:               在連線資料庫之前,首先要載入想要連線的資料庫的驅動到JVM(Java虛擬機器),     這通過java.lang.Clas

JAVA通過JDBC操作MySQL資料庫:PreparedStatement介面操作資料庫

JAVA通過JDBC操作MySQL資料庫(三):PreparedStatement介面操作資料庫 Statement介面的問題 PreparedStatement介面操作資料庫 Statement介面的問題 在文章JAVA通過JDBC操作

jdbc操作mysql資料庫防止注入攻擊版本

package TestJDBC; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.

Mysql 入門,增刪改查

bsp com pre sco height name 數據 mysql from 主要已以下兩個表students與students_score,進行數據的增刪改查操作! 1、SELECT 1)select id,tel from students

史上最簡單MySQL教程詳解之儲存引擎介紹及預設引擎設定

什麼是儲存引擎? 與其他資料庫例如Oracle 和SQL Server等資料庫中只有一種儲存引擎不同的是,MySQL有一個被稱為“Pluggable Storage Engine Architecture”(可替換儲存引擎架構)的特性,也就意味著My

freenas的CIFS/SMB的使用

img 大小 ifs 退出 freenas 什麽 數據 用戶名 鏡像 這裏是對freenas的進一步使用,關於freenas的介紹與安裝請查看上一篇隨筆:http://www.cnblogs.com/hjc4025/p/7079364.html 我們先來看一下如何使用fre

Python---面向對象第三彈

python對象 one iss pri each super left connect ext  Python對象中一些方法 一、__str__ class Teacher: def __init__(self,name,age): self.name

編碼原則實例------c++程序設計原理與實踐

組類型 運算 奇怪 head 不能 gui 簡單的 版本 布局 編碼原則: 一般原則 預處理原則 命名和布局原則 類原則 函數和表達式原則 硬實時原則 關鍵系統原則 (硬實時原則、關鍵系統原則僅用於硬實時和關鍵系統程序設計) (嚴格原則都用一個大寫字母R及其編號標識,而

有符號數和無符號數------c++程序設計原理與實踐

效果 進階 str 二進制位 bsp () 都是 有符號 重新 有符號數與無符號數的程序設計原則: 當需要表示數值時,使用有符號數(如 int)。 當需要表示位集合時,使用無符號數(如unsigned int)。 有符號數和無符號數混合運算有可能會帶來災難性的後果。例如

動態內存分配存在的問題內存空洞------c++程序設計原理與實踐

我們 程序 動態 height ++ idt 很多 alt 空間 new的問題究竟在哪裏呢?實際上問題出在new和delete的結合使用上。考察下面程序中內存分配和釋放過程: while(1){ Big* p=new big;  //...... Smal

數值限制------c++程序設計原理與實踐

c++程序 its positive size true 設置 malle 設計原理 硬件 每種c++的實現都在<limits>、<climits>、<limits.h>和<float.h>中指明了內置類型的屬性,因此程序

實現求解線性方程矩陣、高斯消去法------c++程序設計原理與實踐

ipy 類型 cat sys sca solution gaussian 拷貝 img 步驟: 其中A是一個n*n的系數方陣 向量x和b分別是未知數和常量向量: 這個系統可能有0個、1個或者無窮多個解,這取決於系數矩陣A和向量b。求解線性系統的方法有很多,這裏使用一種經典

c++11隨機數------c++程序設計原理與實踐

ber linear 而在 希望 double 元素 light eal 區間   隨機數既是一個實用工具,也是一個數學問題,它高度復雜,這與它在現實世界中的重要性是相匹配的。在此我們只討論隨機數哦最基本的內容,這些內容可用於簡單的測試和仿真。在<random>

python 面向對象

關心 __iter__ nvi class nic 詳情 mit remove 類名 類的成員 類的成員可以分為三大類:字段、方法和屬性 註:所有成員中,只有普通字段的內容保存對象中,即:根據此類創建了多少對象,在內存中就有多少個普通字段。而其他的成員,則都是保存在類中,

iOS開發者如何在枯燥的工作中尋求技術的提升

調用 loaded 剛才 高可用 package 如果 sql 讀寫 大牛 技術成長是很多同學面臨的問題,一些工作了幾年的同學會遇到成長瓶頸,覺得自己進步緩慢,無論是公司業務的原因還是個人原因,覺得自己的技術水平得不到成長了。或者一些剛工作沒多久的同學和在找工作的同學,都想

Python開發【第七】:面向物件

上一篇《Python 面向物件(初級篇)》文章介紹了面向物件基本知識: 面向物件是一種程式設計方式,此程式設計方式的實現是基於對 類 和 物件 的使用 類 是一個模板,模板中包裝了多個“函式”供使用(可以講多函式中公用的變數封裝到物件中) 物件,根據模板

spring Security4 和 oauth2整合 註解+xml混合使用

Spring Security4 和 oauth2整合使用者密碼授權模式 上篇已經可以正常運行了,不過拿來測試還不夠,下面介紹如何測試oauth2的使用者密碼模式,授權碼模式下一篇說。 不想看這些亂七八糟的,可以直接把程式碼拉下來。 git地址:https://gitee.com/x

HenCoder Android 自定義 View 1-7:屬性動畫 Property Animation

這期是 HenCoder 自定義繪製的第 1-7 期:屬性動畫(進階篇) 簡介 上期的內容,對於大多數簡單的屬性動畫場景已經夠用了。這期的內容主要針對兩個方面: 針對特殊型別的屬性來做屬性動畫; 針對複雜的屬性關係來做屬性動畫。 TypeEvaluator

python 面向物件

本篇將詳細介紹Python 類的成員、成員修飾符、類的特殊成員。 類的成員 類的成員可以分為三大類:欄位、方法和屬性 注:所有成員中,只有普通欄位的內容儲存物件中,即:根據此類建立了多少物件,在記憶體中就有多少個普通欄位。而其他的成員,則都是儲存在類中,即:無論物件

無業務不伸縮之二,雲監控搭配SLB及ESS

雲端計算ESS彈性伸縮課程 無業務不伸縮之二,雲監控搭配SLB及ESS(進階篇) 連載雲端計算文章主題 後續的連載如下1、 無業務不伸縮之一,雲端計算有ESS2、 無業務不伸縮之二,雲監控搭配SLB及ESS3、無互動不加速,雲端計算有CDN4、無對像不儲存,雲端計算有OSS5、無檔案不儲存,雲端計算有”