1. 程式人生 > >day01(後端實習技能) JDBC知識學習歸納總結

day01(後端實習技能) JDBC知識學習歸納總結

1、JDBC的簡介

JDBC全稱為java database connectivity,是sun公司指定的java資料庫連線技術的簡稱。

SUN公司提供的一種資料庫訪問規則、規範, 由於資料庫種類較多,並且java語言使用比較廣泛,sun公司就提供了一種規範,讓其他的資料庫提供商去實現底層的訪問規則。 我們的java程式只要使用sun公司提供的jdbc驅動即可。

2、JDBC常用的幾個包

我們需要熟悉包java.sql.*中定義的類(class),介面(interface),例外(expection),並且能夠靈活使用他們,就能夠發揮出JDBC強大的功能。

包java.sql.*中幾個核心的類和介面:

① java.sql.DriverManager用來載入不同資料庫廠商的JDBC驅動,併為建立新的資料庫連線提供支援

② java.sql.Driver指定資料庫的驅動入口,DriverManager將通過該類作為連線資料的引數

③ java.sql.Connection完成針對某指定資料庫的連線功能

④ java.sql.Statement在一個已經建立的連線中,作為SQL語句執行的容器,它有兩個子類:

java.sql.CallableStatement 用於執行資料庫中已經建立好的儲存過程。

java.sql.preparedStatement用於執行預編譯的SQL語句。

⑤ java.sql.ResultSet用於儲存執行特定SQL語句後返回的結果集。

3、JDBC的開發步驟

*註冊驅動(不同的資料庫驅動不一樣,具體問度娘)

  Class.forName("com.mysql.jdbc.Driver");

*獲取連線

connection conn = DriverManager.getConnection(url, "root", "123456");
String url="jdbc:mysql://localhost:3306/student?";

此處解釋一下url:jdbc是協議,mysql是子協議,表示資料庫系統管理名稱,ocalhost:3306是你資料庫來源的地址和目標埠,student表示你的資料庫具體的名稱。

*建立statement語句物件

Statement stmt=conn.createStatement();

此處又對statment進行詳細的解釋與說明:

JDBC核心API提供了三種向資料庫傳送SQL語句的類:

Statement:使用createStatement()建立;
PreparedStatement:經過預編譯並存儲在PreparedStatement物件中的SQL語句,使用prepareStatement()方法建立。
CallableStatement:用於執行SQL儲存過程,使用prepareCall()方法建立。

三種不同物件的比較:

第一種:statement
Statement物件用於執行靜態SQL語句和獲得SQL產生的結果。定義了三種執行SQL語句的方法,用來處理返回不同結果的SQL命令:

executeUpdate(String sql):執行SQL INSERT,UPDATE或DELETE 語句,返回受影響行的數目或零;
返回值為int型

executeQuery(String sql):執行返回單個ResultSet的SQL語句;
返回型別ResultSet

execute(String sql):執行可以返回多個結果的SQL語句。
返回型別為boolean,如果返回的是更新的數目,則返回false,如果返回ResultSet,則返回true。

第二種: PreparedStatement語句

PreparedStatement是java.sql包下面的一個介面,用來執行SQL語句查詢,通過呼叫connection.preparedStatement(sql)方法可以獲得PreparedStatment物件。

資料庫系統會對sql語句進行預編譯處理(如果JDBC驅動支援的話),預處理語句將被預先編譯好,這條預編譯的sql查詢語句能在將來的查詢中重用,這樣一來,它比Statement物件生成的查詢速度更快。

PreparedStatement僅僅是預編譯語句。可以使用佔位符。

*執行sql並返還結束

ResultSet rs=stmt.executeQuery(querySql);

4、舉實際例子加深認識

**介紹的是
(1)簡單粗暴的例子:

  package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Maintest {
	public static void main(String[] args) {
	//定義全域性變數
		Statement stmt = null;
		ResultSet rs = null;
		Connection conn = null;
		try {
			String querySql = "select * from student";
			//註冊驅動
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql://localhost:3306/student?";
			//獲取連線
			conn = DriverManager.getConnection(url, "root", "123456");
			// 建立statment語句物件
			stmt = conn.createStatement();
			//執行sql語句
			rs = stmt.executeQuery(querySql);
			//遍歷rs結果集
			while (rs.next()) {
				System.out.println("name:" + rs.getString("name") + "年齡:"+rs.getInt("age") +"性別:" +rs.getString("sex"));
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
	     //最後需要關閉資源,先判斷是否為空因為有可能資源未開啟,這時候會報空指標異常;不為空時候則需要關閉資源,不關閉則造成記憶體的浪費
			try {
				if (rs != null) {
					rs.close();
				}
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}    
	}
}

(2)下面這個例子對註冊驅動和獲取連線進行簡單優化:

因為每個程式獲取連線和註冊驅動都一個樣,所以可以抽取出來作為工具類使用

抽取出來的類:

package utils;

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

public class Conectionfactory {

	public static Connection Connection(String user, String pass) {
		Connection conn = null;// 宣告連線物件
		String driver = "com.mysql.jdbc.Driver";// 驅動程式類名
		String url = "jdbc:mysql://localhost:3306/student?" // 資料庫URL
				+ "useUnicode=true&characterEncoding=UTF8";// 防止亂碼
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, user, pass);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}

	// 關閉資料庫連線
	public static void closeConnection(Connection con, Statement stmt, ResultSet rs) throws SQLException {

		if (rs != null) {
			rs.close();
		}
		if (stmt != null) {
			stmt.close();
		}
		if (con != null) {
			con.close();
		}
	}   }

呼叫這個類:

package test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import utils.Conectionfactory;
public class Maintest3 {
	public static void main(String[] args) {

	 ResultSet rs=null;
	 Statement stmt=null;
	 Connection conn=null;
		try{
		//直接就呼叫工具類實現獲取連線
      conn=Conectionfactory.Connection("root", "123456");
	  stmt=conn.createStatement();     
      String querySql="select * from student";
	  rs=stmt.executeQuery(querySql);
	   while(rs.next())
	       {    
    System.out.println("人員編號:"+rs.getString("name")+"工資:"+rs.getInt("age")+"姓名:"+rs.getInt("sex"));//使用getString()方法獲取你表裡的資料名
		     }

	}catch (Exception e) 
	{
	// TODO Auto-generated catch block
	e.printStackTrace();
}
		finally {
			try {
			//呼叫連線關閉資源
				Conectionfactory.closeConnection(conn, stmt, rs);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	}
}

(3)在工具類的前提下,繼續優化工具類。
此處,我們需要達到的目的是工具類自動載入”註冊驅動,載入連線“
此處,需要一個配置檔案(配置檔案需要放在src目錄下)

jdbc

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student
name=root
password=123456

JDBCUtil工具類

package utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtil {
	static String driverClass = null;
	static String url = null;
	static String name = null;
	static String password= null;
	
	static{
		try {
			//1. 建立一個屬性配置物件
			Properties properties = new Properties();
		//	InputStream is = new FileInputStream("jdbc.properties");
			
			//使用類載入器,去讀取src底下的資原始檔。 後面在servlet
      	InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
			//匯入輸入流。
			properties.load(is);
			
			//讀取屬性
			driverClass = properties.getProperty("driverClass");
			url = properties.getProperty("url");
			name = properties.getProperty("name");
			password = properties.getProperty("password");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 獲取連線物件
	 * @return
	 */
	public static Connection getConn(){
		Connection conn = null;
		try {
			Class.forName(driverClass);
			//靜態程式碼塊 ---> 類載入了,就執行。 java.sql.DriverManager.registerDriver(new Driver());
			//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
			//DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
			//2. 建立連線 引數一: 協議 + 訪問的資料庫 , 引數二: 使用者名稱 , 引數三: 密碼。
			conn = DriverManager.getConnection(url, name, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	/**
	 * 釋放資源
	 * @param conn
	 * @param st
	 * @param rs
	 */
	public static void release(Connection conn , Statement st , ResultSet rs){
		closeRs(rs);
		closeSt(st);
		closeConn(conn);
	}

	
	private static void closeRs(ResultSet rs){
		try {
			if(rs != null){
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			rs = null;
		}
	}
	
	private static void closeSt(Statement st){
		try {
			if(st != null){
				st.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			st = null;
		}
	}
	
	private static void closeConn(Connection conn){
		try {
			if(conn != null){
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			conn = null;
		}
	} }

測試程式碼:

package test;

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

import utils.JDBCUtil;

public class tes {
	public static void main(String[] args) {
		Connection conn  = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			//1. 註冊驅動 
			conn = JDBCUtil.getConn();
			
			//3. 建立statement , 跟資料庫打交道,一定需要這個物件
			st = conn.createStatement();
			
			//4. 執行查詢 , 得到結果集
			String sql = "select * from student";
			rs = st.executeQuery(sql);
			//5. 遍歷查詢每一條記錄
			while(rs.next()){
				System.out.println("人員編號:"+rs.getString("name")+"工資:"+rs.getInt("age")+"姓名:"+rs.getInt("sex"));//使用getString()方法獲取你表裡的資料名
					
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			JDBCUtil.release(conn, st, rs);
		}
	}
}

PS:如果不註冊驅動也行,原始碼好像說會”自動載入驅動“

接著的例子是增刪改查:

在原來的測試類和工具類的基礎上,在測試類變動一下:
增加的例子

//3. 執行新增
			String sql = "insert into student values('ljq' , 18 , 19)";
			//影響的行數, ,如果大於0 表明操作成功。 否則失敗
			int result = st.executeUpdate(sql);
			
			if(result >0 ){
				System.out.println("新增成功");
			}else{
				System.out.println("新增失敗");
			}

刪除的例子

//4. 執行刪除
			String sql = "delete from student where name='ljq'";
			//影響的行數, ,如果大於0 表明操作成功。 否則失敗
			int result = st.executeUpdate(sql);
			
			if(result >0 ){
				System.out.println("刪除成功");
			}else{
				System.out.println("刪除失敗");
			}

Statement的安全問題:前面先拼接sql語句, 如果變數裡面帶有了 資料庫的關鍵字,那麼一併認為是關鍵字。 不認為是普通的字串。

所以,接下來我介紹一下 PrepareStatement。

相比較以前的statement, 預先處理給定的sql語句,對其執行語法檢查。 在sql語句裡面使用 ? 佔位符來替代後續要傳遞進來的變數。 後面進來的變數值,將會被看成是字串,不會產生任何的關鍵字。


           String sql = "select * from student where name=? and age=?";
			  ps = conn.prepareStatement(sql);
			 
			 //給佔位符賦值 從左到右數過來,1 代表第一個問號, 永遠你是1開始。
			  ps.setString(1, "meici");
			  ps.setInt(2, 11);

              rs = ps.executeQuery();
              while(rs.next())
              {
            	  System.out.println("人員編號:"+rs.getString("name")+"工資:"+rs.getInt("age")+"姓名:"+rs.getInt("sex"));
              }

JDBC的大概知識點就是這些,有更新的會繼續加進去!!!