Mysql(五) JDBC

1、JDBCjava

    JDBC(Java DataBase Connectivity) Java 數據庫鏈接API
    JDBC完成三件事: 與一個數據庫鏈接          向數據庫發送SQL語句                處理數據庫返回的結果 
    Java.sql包提供了JDBC API,聲明瞭訪問數據庫的接口和類, 能夠經過它編寫訪問數據庫的程序。 
    JDBC API只是定義了相關的規範(提供相應的接口),並不 能直接訪問數據庫,它依賴於數據庫廠商提供具體的實現。 
   
mysql

     一、相關實現sql

        

    二、Java.sql包中的接口和類 :
數據庫

       Driver接口和DriverManager
       Connection接口
       Statement接口
       PreparedStatement接口
       ResultSet接口
服務器

       (1)Driver接口和DriverManager
oracle

全部JDBC驅動程序都必須實現Driver接口, JDBC驅動程序由 數據庫廠商提供。
DriverManager用來創建和數據庫的鏈接已經管理JDBC驅動 程序。
getConnection(String url,String user,String pwd):創建和 數據庫的鏈接,返回Connection對象 
app

     (2)Connection接口
sqlserver

Connection接口表明Java程序和數據庫的鏈接, Connection接口經常使用方法:
createStatement():建立並返回Statement對象
prepareStatement(String sql):建立並返回 PreparedStatement對象 
性能

    (3)Statement接口
ui

Statement用來執行SQL語句。 
對於insertupdatedelete語句,能夠調用 executeUpdate(String sql)方法,該方法返回一個int型數據, 表示受影響的記錄數。
對於select語句,能夠調用executeQuery(String sql)方法, 該方法返回一個ResultSet對象(查詢結果集) 

    (4)PreparedStatement接口

PreparedStatement也用來執行SQL語句,不一樣的是,其可使 用動態的參數(?)。
在訪問數據庫時,若是某條SQL語句被屢次執行,但每次都參 數不一樣,在這種狀況下,使用PreparedStatementStatement 更方便, PreparedStatement容許sql語句中包含參數。

    (5)ResultSet接口
ResultSet接口表示select語句查詢獲得的記錄結果集合,ResultSet接口的記錄行號從1開始,一個Statement對象在同 一時刻只能打開一個ResultSet對象。
調用ResultSetnext()方法,能夠進行順序查詢,可使遊 標定位到下一條記錄,該方法返回一個boolean型數據,當 遊標移動到最後一行以後返回false
調用ResultSetgetXXX()方法,能夠獲取某個字段的值。 XXX爲字段的類型。 

    三、JDBC程序訪問數據庫的步驟

    四、驅動類名

驅動類的名稱由數據庫廠商提供,不一樣的數據庫廠商類名也不 相同。 

MySQL驅動類: com.mysql.jdbc.Driver
Oracle驅動類: oracle.jdbc.driver.OracleDriver
SqlServer驅動類: com.microsoft.sqlserver.jdbc.SQLServerDriver

   五、創建與數據庫的鏈接

Connection con = DriverManager.getConnection(url,user,password);
url表示鏈接數據庫的地址,不一樣的數據庫, url也不相同。
userpassword分別表示鏈接數據庫的用戶名和密碼。
url的通常形式爲:
jdbc:drivertype:driversubtype://parameters
drivertype表示驅動程序的類型, driversubtype是子類型, parameter一般用來設定數據庫服務器的IP地址、端口號和數據 庫的名稱
 

  六、事務處理
在數據庫操做中,一項事務是指由一條或多條對數據庫更新 的SQL語句所組成的不可分割的工做單元。 

只有當事務中的全部操做都正常完成,整個事務才能被提交 到數據庫。若是有一項操做沒有完成,則必須撤銷整個事務。 

事務的原則:要麼所有完成,要麼什麼都不作。


Connection類中提供了3個控制事務的方法:

setAutoCommit(boolean autoCommit):設置是否自動提交事 務
commit():提交事務
rollback():撤銷事務
默認狀況下,事務爲自動提交。即每一條數據庫更新的SQL 語句表明一項事務,操做成功後,系統將自動調用commit() 來提交,不然將調用rollback()來撤銷事務。 
能夠經過調用setAutoCommit(false)來禁止自動提交事務。 能夠把多條更新數據庫的SQL語句做爲一個事務,在全部操 做完成後,調用commit()來進行總體提交。若其中一項SQL操做失敗,就不會執行commit(),而是產生相應的SQLException,此時就能夠在捕獲異常的代碼塊中調用rollback()方法撤銷事務。 

   七、數據庫鏈接池

以前的數據庫鏈接方式,是在須要時建立一個鏈接,當訪問 數據庫結束後,即將建立的鏈接銷燬。 

數據庫的鏈接池的基本思想:在數據源中爲數據庫鏈接創建 多個鏈接,保存在鏈接池(connect pool)中;預先在鏈接池 中放入必定數量的鏈接,當Java程序訪問數據庫時,只需從 鏈接池中取出一個空閒狀態的數據庫鏈接。當程序訪問數據 庫結束,再將數據庫鏈接放回鏈接池。這樣就能夠提升訪問
數據庫的效率,由於鏈接池只是將鏈接回收,而不是銷燬。 要清楚,數據庫鏈接的建立與銷燬是很是耗費資源的。 

2、

一、

/*
 * 經過Java鏈接MySQL數據庫。
 */
package day23;

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

public class ConnectionTest {
	public static void main(String[] args) {
		Connection con = null;
		Statement st = null;
		try {
			// 能夠建立驅動類的對象來令驅動類初始化,只是建立
			// 的對象是多餘的(根本不使用該對象)
			// new com.mysql.jdbc.Driver();
			// 加載並初始化驅動類。
			Class.forName("com.mysql.jdbc.Driver");
			// 得到數據庫的鏈接,返回Connection接口類型的對象。
			con = DriverManager.getConnection("jdbc:mysql://000.0.0.0:3306/test?useSSL=false", "root", "");
			// System.out.println(con);
			// 建立可執行的sql語句。
			st = con.createStatement();
			// 執行更新語句。返回受影響的記錄數。
			int count = st.executeUpdate("insert into student(id, name) values (8, '新增')");
			System.out.println(count);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 資源釋放的順序:
			// 先建立的後釋放,後建立的先釋放。
			if (st != null) {
				try {
					st.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

  

二、TryWithResources:

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

public class TryWithResources {
	public static void main(String[] args) {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try (Connection con = DriverManager.getConnection("jdbc:mysql://***.0.0.1:3306/test?useSSL=false", "root", "");
				Statement st = con.createStatement();
				ResultSet rs = st.executeQuery("select id, name, age, sex from student");) {

                                              // 判斷是否有下一條記錄,若是存在,返回true,同時
                                              // 移動遊標(指針),使其指向下一條記錄。若是不存在,
                                              // 返回false。

			while (rs.next()) {

                                                // 根據字段的索引得到當前記錄該字段的值。索引從1開始。
                                                  // int id = rs.getInt(1);
                                               // 根據字段的名字得到當前記錄該字段的值。
                                                int id = rs.getInt("id");
                                                String name = rs.getString("name");
                                                 int age = rs.getInt("age");
                                                 String sex = rs.getString("sex");

			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}

  三、PreparedStatement

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

public class DBUtil {
	public static Connection getConnection() {
		Connection con = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useSSL=false", "root", "");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return con;
	}

	public static void release(ResultSet rs, Statement st, Connection con) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (con != null) {
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

  

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

public class PreparedTest {

	public static void main(String[] args) {

	}

	public void insert(int id, String name, int age, String sex) {
		try (Connection con = DBUtil.getConnection(); Statement st = con.createStatement();) {
			String sql = "insert into student(id, name, age, sex) values (" + id + ", '" + name + "'," + age + ",'"
					+ sex + "')";
			StringBuilder bu = new StringBuilder();
			bu.append("insert into student(id, name, age, sex) values (").append(id).append(",'").append(name)
					.append("',").append(age).append(",'").append(sex).append("')");
			st.executeUpdate(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	/*
	 * PreparedStatement與Statement
	 * PreparedStatement是預處理的SQL語句對象,當重複
	 * 執行時,PreparedStatement在性能上可能會好於
	 * Statement(這要取決於底層數據庫是否支持預處理)。
	 * PreparedStatement在程序的可讀性上,也好於
	 * Statement,所以,咱們應該老是有限的考慮使用
	 * PreparedStatement。
	 */
	public void insert2(int id, String name, int age, String sex) {
		try (Connection con = DBUtil.getConnection();
				PreparedStatement ps = con
						.prepareStatement("insert into student(id, name, age, sex) values(?,?,?,?)")) {
			ps.setInt(1, id);
			ps.setString(2, name);
			ps.setInt(3, age);
			ps.setString(4, sex);
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}

  四、Transaction

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Transaction {

	public static void main(String[] args) {
		Connection con = DBUtil.getConnection();
		try (PreparedStatement ps1 = con.prepareStatement("update account set money = money - 100 where id = 1");
				PreparedStatement ps2 = con
						.prepareStatement("updatedd account set money = money + 100 where id = 2");) {
			// 將自動提交設置爲假。
			con.setAutoCommit(false);
			ps1.executeUpdate();
			ps2.executeUpdate();
			// 事務執行完畢,沒有異常,提交。
			con.commit();
			con.setAutoCommit(true);
		} catch (SQLException e) {
			try {
				// 失敗,進行回滾操做。恢復到事務執行以前的
				// 狀態。
				con.rollback();
				con.setAutoCommit(true);
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}

}
相關文章
相關標籤/搜索