回顧:
臟讀:未提交事務(wù)的數(shù)據(jù)
不可重復(fù)讀:已提交數(shù)據(jù) update
幻讀或者虛讀:已經(jīng)提交了數(shù)據(jù)的行數(shù) insert delete
JDBC介紹(掌握)
核心API
1.DriverManager 驅(qū)動(dòng)管理類
2.connection連接接口
3.Statement 發(fā)送SQL語句的接口 Statement的子接口PreparedStatement 預(yù)編譯接口,防止SQL注入問題
4.ResultSet 結(jié)果集 接收查詢的數(shù)據(jù)
JDBC編程六步(掌握)
注冊(cè)驅(qū)動(dòng)
?Class.forName("com.mysql.jdbc.Driver");
數(shù)據(jù)庫獲取連接
使用驅(qū)動(dòng)管理類DriverManager中的靜態(tài)方法:
??????? static Connection getConnection(String url, String user, String password)試圖建立到給定數(shù)據(jù)庫 URL 的連接掌实。
參數(shù):
??????????????????? url -連接數(shù)據(jù)庫的地址
??????????????????????? url整體格式:jdbc:mysql://連接數(shù)據(jù)庫服務(wù)器的ip地址:連接數(shù)據(jù)庫的端口號(hào)/具體的數(shù)據(jù)庫名
??????? ????????????user -數(shù)據(jù)庫用戶,root
??????????????????? password -用戶的密碼1234
?*/
//2.獲取和數(shù)據(jù)庫的連接String url = "jdbc:mysql://localhost:3306/day04_db";//連接數(shù)據(jù)庫的地址String user = "root";//數(shù)據(jù)庫用戶String password = "1234";//用戶的密碼Connection conn = DriverManager.getConnection(url, user, password);
獲取發(fā)送SQL語句對(duì)象
使用驅(qū)動(dòng)管理類DriverManager中的靜態(tài)方法:
??????? static Connection getConnection(String url, String user, String password)試圖建立到給定數(shù)據(jù)庫 URL 的連接贱鼻。
參數(shù):
??????????????????? url -連接數(shù)據(jù)庫的地址
??????????????????????? url整體格式:jdbc:mysql://連接數(shù)據(jù)庫服務(wù)器的ip地址:連接數(shù)據(jù)庫的端口號(hào)/具體的數(shù)據(jù)庫名
??????? ????????????user -數(shù)據(jù)庫用戶勇婴,root
??????????????????? password -用戶的密碼1234
?*/
//2.獲取和數(shù)據(jù)庫的連接String url = "jdbc:mysql://localhost:3306/day04_db";//連接數(shù)據(jù)庫的地址String user = "root";//數(shù)據(jù)庫用戶String password = "1234";//用戶的密碼Connection conn = DriverManager.getConnection(url, user, password);
3.獲取Statement對(duì)象
在java.sql.Connection接口中有如下方法獲取到Statement對(duì)象
Statement的API介紹
int executeUpdate(String sql)
根據(jù)執(zhí)行的DML(insert、update耕渴、delete)語句,發(fā)揮影響的行數(shù)
2.resultSet excuteQuery(String sql)
根據(jù)執(zhí)行的結(jié)果集橱脸,只能執(zhí)行select語句
注意:在MySQL中分苇,只要不是查詢就是修改。
executeUpdate:用于執(zhí)行增刪改
executeQuery:用于執(zhí)行查詢
使用步驟
1.注冊(cè)驅(qū)動(dòng)
2屁桑。獲取連接
3.獲取Statement對(duì)象
4.使用Statement對(duì)象執(zhí)行SQL語句
5.釋放資源
JDBC實(shí)現(xiàn)對(duì)單標(biāo)查詢
Result原理
1.ResultSet內(nèi)部有一個(gè)指針,開始記錄開始位置
2.調(diào)用next方法靖秩,ResultSet內(nèi)部指針就會(huì)移動(dòng)到下一行數(shù)據(jù)
3.我們可以通過ResultSet得到一行數(shù)據(jù)getXxx得到某列數(shù)據(jù)
public class Demo04 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql:///day04_db", "root", "1234");
Statement stmt = conn.createStatement();
SString sql = "select * from user";
ResultSet rs = stmt.executeQuery(sql);
// 內(nèi)部有一個(gè)指針,只能取指針指向的那條記錄
? ? ? ? while(rs.next()){// 指針移動(dòng)一行,有數(shù)據(jù)才返回true
int id = rs.getInt("id");
String name = rs.getString(2);
String pwd= rs.getString(3);
System.out.println(id+"+++"+name+"++++"+pwd);
}
// 關(guān)閉資源
rs.close();
stmt.close();
conn.close();
}
}
JDBC事務(wù)
開啟事務(wù)(coon.setAutoCommit(false))——>執(zhí)行一組SQL語句——>一切正常提交事務(wù) coon.commit();
開啟事務(wù)(coon.setAutoCommit(false))——>執(zhí)行一組SQL語句——> 出現(xiàn)異常竖瘾,回滾事務(wù)coon.rollback沟突;
Connection 接口中與事務(wù)有關(guān)的方法
void setAutoCommit(boolean autoCommit)throws SQLException;
false:開啟事務(wù)捕传,true:關(guān)閉事務(wù)
voidcommit()throwsSQLException;
提交事務(wù)
voidrollback()throwsSQLException;
回滾事務(wù)
注意:在jdbc事務(wù)操作中,事務(wù)的控制都是通過Connection對(duì)象完成的庸论,當(dāng)一個(gè)完整的業(yè)務(wù)操作前,我們首先使用coon.setAutoCommit(false)來開啟事務(wù)聂示。默認(rèn)情況下是true的,表示關(guān)閉事務(wù)鱼喉,那么一條SQL語句就是一個(gè)事務(wù),默認(rèn)提交事務(wù)蒲凶。如果設(shè)置為false拆内,那么表示開啟事務(wù)旋圆,所有的SQL語句就會(huì)都在一個(gè)事務(wù)中麸恍。
當(dāng)業(yè)務(wù)操作完成后灵巧,如果整個(gè)操作沒有問題抹沪,我們需要使用coon.commmit()來提交事務(wù)。當(dāng)然了融欧,如果出現(xiàn)了異常,我們需要使用coon.rollback()撤銷所有的操作噪馏,所以出現(xiàn)事務(wù)的異常绿饵,需要進(jìn)行事務(wù)的回滾。
使用步驟
1.注冊(cè)驅(qū)動(dòng)
2.獲取連接
3.開啟事務(wù)
4.獲取Statement
5.使用Statement執(zhí)行SQL
6.提交或回滾事務(wù)
7.關(guān)閉資源
package com.day04;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC {
public static void main(String[] args)throws SQLException, ClassNotFoundException {
/* DriverManager.registerDriver(new Driver());
使用 DriverManager.registerDriver(new Driver());拟赊,存在以下不足粹淋,注冊(cè)被注冊(cè)兩次
*/
? ? ? Class.forName("com.mysql.jdbc.Driver");//注冊(cè)驅(qū)動(dòng)
//獲取連接
? ? ? ? Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day04_db","root","root");
System.out.println(connection);
//從連接中拿到一個(gè)Statement對(duì)象
? ? ? ? Statement statement = connection.createStatement();
//1.插入記錄
/*String sql ="insert into user values(null,'zhaoliu','abc')";
int i=statement.executeUpdate(sql);
System.out.println("影響的行數(shù):"+i );*/
//2.修改記錄
/*? String? sql="update user set? username='tianqi'where username='zhaoliu'";
int? i=statement.executeUpdate(sql);
System.out.println("影響的行數(shù):"+i );*/
//刪除記錄
? ? ? ? String sql ="delete from user where id=4";
int i=statement.executeUpdate(sql);
System.out.println("影響的行數(shù):"+i );
statement.close();
connection.close();
}
}
編寫JDBC工具類
在目錄下創(chuàng)建jdbc.properties
jdbc.properties文件中的配置信息
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day04_db
user=root
password=root
如何讀取外部文件的內(nèi)容?
public static void main(String[]args) {
? ? ? ? // 需求: 通過properties對(duì)象讀取 外部配置的內(nèi)容
? ? ? ? Propertiesprop=newProperties();
? ? ? ? try{
//對(duì)于FileInputStream流相對(duì)的路徑是當(dāng)前模塊
FileInputStreamin=newFileInputStream("jdbc.properties");
? ? ? ? ? ? // 加載外部的配置文件
? ? ? ? ? ? prop.load(in);
? ? ? ? }catch(IOExceptione) {
? ? ? ? ? ? // TODO Auto-generated catch block
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? // 讀取外部配置文件的內(nèi)容
? ? ? ? StringdriverClass=prop.getProperty("driverClass");
? ? ? ? Stringurl=prop.getProperty("url");
? ? ? ? Stringuser=prop.getProperty("user");
? ? ? ? Stringpassword=prop.getProperty("password");
?
? ? ? ? System.out.println(driverClass);
? ? }
獲得連接的最終版
public class JDBCUtils {
static String driverClass = null;
static String url = null;
static String user = null;
static String password = null;
static {
// 需求: 通過properties對(duì)象讀取 外部配置的內(nèi)容
Properties prop = new Properties();
try {
FileInputStream in=new FileInputStream("jdbc.properties");
// 加載外部的配置文件
prop.load(in);
// 讀取外部配置文件的內(nèi)容
? ? driverClass = prop.getProperty("driverClass");
? ? url = prop.getProperty("url");
? ? user = prop.getProperty("user");
? ? password = prop.getProperty("password");
// 注冊(cè)驅(qū)動(dòng)
Class.forName(driverClass);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 獲得連接
public static Connection getConnection() {
Connection con = null;
? try? {
? ? ? ? ? con = DriverManager.getConnection(url, user, password);
? ? ? ? } catch (Exception e)
{
? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return con;
}
}
關(guān)閉資源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
// 釋放資源
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
優(yōu)化后的delete方法
@Test
? ? publicvoiddelete() {
? ? ? ? // 需求: 刪除id=3的記錄
? ? ? ? Connectionconn=null;
? ? ? ? Statementstmt=null;
?
? ? ? ? try{
? ? ? ? ? ? // 獲得連接
? ? ? ? ? ? conn=JDBCUtils.getConnection();
? ? ? ? ? ? // 獲得發(fā)送sql的對(duì)象
? ? ? ? ? ? stmt=conn.createStatement();
? ? ? ? ? ? // 執(zhí)行sql 獲得結(jié)果
? ? ? ? ? ? Stringsql="delete from user where id=3";
? ? ? ? ? ? intsum=stmt.executeUpdate(sql);
? ? ? ? ? ? // 處理結(jié)果
? ? ? ? ? ? System.out.println(sum);
? ? ? ? }catch(Exceptione) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }finally{
? ? ? ? ? ? // 釋放資源
? ? ? ? ? ? JDBCUtils.release(conn,stmt,null);
? ? ? ? }
? ? }