JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別分析
一、概述
JDBC:Java Database Connectivity,它是代表一組獨(dú)立于任何數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)的API,聲明在java.sql與javax.sql包中,是SUN(現(xiàn)在Oracle)提供的一組接口規(guī)范。由各個(gè)數(shù)據(jù)庫(kù)廠商來(lái)提供實(shí)現(xiàn)類,這些實(shí)現(xiàn)類的集合構(gòu)成了數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar。

二、JDBC使用步驟

注冊(cè)驅(qū)動(dòng)
三部曲:
- 將DBMS數(shù)據(jù)庫(kù)管理軟件的驅(qū)動(dòng)jar拷貝到項(xiàng)目的libs目錄中
- 把驅(qū)動(dòng)jar添加到項(xiàng)目的build path中
- 將驅(qū)動(dòng)類加載到內(nèi)存中
注意:MySQL 8是這個(gè)Class.forName(“com.mysql.cj.jdbc.Driver”)不寫(xiě)cj會(huì)報(bào)錯(cuò);MySQL 5是這個(gè)Class.forName(“com.mysql.jdbc.Driver”);
獲取Connection連接對(duì)象
Connection conn = DriverManager.getConnection(url,username,password);
url:jdbc:mysql://localhost:3306/數(shù)據(jù)庫(kù)名?參數(shù)名=參數(shù)值
執(zhí)行sql并處理結(jié)果
- 編寫(xiě)sql
- 創(chuàng)建Statement或PreparedStatement對(duì)象
- 執(zhí)行sql 增刪改:調(diào)用executeUpate方法;查詢:調(diào)用executeQuery方法
處理結(jié)果
- 增刪改:返回的是整數(shù)值即影響的行數(shù)
- 查詢:返回ResultSet結(jié)果,需要使用next()和getXxx()結(jié)合進(jìn)行遍歷
釋放連接
示例代碼1:增、刪、改
public class TestJDBC {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1、注冊(cè)驅(qū)動(dòng)
//(1)方式一:Class.forName("驅(qū)動(dòng)類的全名稱")
Class.forName("com.mysql.cj.jdbc.Driver");
// (2)創(chuàng)建驅(qū)動(dòng)類的對(duì)象
// new com.mysql.cj.jdbc.Driver();//硬編碼
//(3)通過(guò)DriverManager注冊(cè)驅(qū)動(dòng)
// DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());//硬編碼
//2、獲取連接,連接數(shù)據(jù)庫(kù)
//TCP/IP協(xié)議編程,需要服務(wù)器的IP地址和端口號(hào)
//mysql的url格式:jdbc協(xié)議:子協(xié)議://主機(jī)名:端口號(hào)/要連接的數(shù)據(jù)庫(kù)名
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";//其中test是數(shù)據(jù)庫(kù)名;serverTimezone是時(shí)區(qū)不設(shè)置可能報(bào)錯(cuò)
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);
//3、執(zhí)行sql
//添加一個(gè)部門(mén)到數(shù)據(jù)庫(kù)的t_department表中
//(1)編寫(xiě)sql
String sql = "insert into t_department values(null,'計(jì)算部2','計(jì)算鈔票2')";
/*
* 回憶: TCP/IP程序時(shí)
* Socket代表連接
* socket.getOutputStream()來(lái)發(fā)送數(shù)據(jù),
* socket.getInputStream()來(lái)接收數(shù)據(jù)
*
* 可以把Connection比喻成Socket
* 把Statement比喻成OutputStream
*/
//(2)獲取Statement對(duì)象
Statement st = conn.createStatement();
//(3)執(zhí)行sql
int len = st.executeUpdate(sql);
//(4)處理結(jié)果
System.out.println(len>0?"成功":"失敗");
//4、關(guān)閉
st.close();
conn.close();
}
}
示例代碼2:查詢
public class TestSelect {
public static void main(String[] args) throws Exception{
// 1、注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.cj.jdbc.Driver");
// 2、連接數(shù)據(jù)庫(kù)
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC", "root", "123456");
// 3、執(zhí)行sql
String sql = "SELECT * FROM t_department";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);//ResultSet看成InputStream
while(rs.next()){//next()表示是否還有下一行
Object did = rs.getObject(1);//獲取第n列的值
Object dname = rs.getObject(2);
Object desc = rs.getObject(3);
/*
int did = rs.getInt("did");//也可以根據(jù)列名稱,并且可以按照數(shù)據(jù)類型獲取
String dname = rs.getString("dname");
String desc = rs.getString("description");
*/
System.out.println(did +"\t" + dname + "\t"+ desc);
}
// 4、關(guān)閉
rs.close();
st.close();
conn.close();
}
}
三、使用PreparedStatement處理CRUD
1、為什么使用PreparedStatement處理CRUD?
Statement的問(wèn)題:
sql拼接
String sql = "insert into t_employee(ename,tel,gender,salary) values('" + ename + "','" + tel + "','" + gender + "'," + salary +")";
Statement st = conn.createStatement();
int len = st.executeUpdate(sql);
sql注入
String sql = "SELECT * FROM t_employee where ename='" + ename + "'"; //如果我此時(shí)從鍵盤(pán)輸入ename值的時(shí)候,輸入:張三' or '1'= '1 //結(jié)果會(huì)把所有數(shù)據(jù)都查詢出來(lái) Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(sql);
無(wú)法處理blob等類型的數(shù)據(jù)
String sql = "insert into user(username,photo) values('chailinyan', 圖片字節(jié)流)";
//此時(shí)photo是blob類型的數(shù)據(jù)時(shí),無(wú)法在sql中直接拼接
2、PreparedStatement解決問(wèn)題
避免sql拼接
String sql = "insert into t_employee(ename,tel,gender,salary) values(?,?,?,?)"; PreparedStatement pst = conn.prepareStatement(sql);//這里要傳帶?的sql,然后mysql端就會(huì)對(duì)這個(gè)sql進(jìn)行預(yù)編譯 //根據(jù)字段來(lái)設(shè)置?的具體值 /*pst.setString(1, ename); pst.setString(2, tel); pst.setString(3, gender); pst.setDouble(4, salary);*/ pst.setObject(1, ename); pst.setObject(2, tel); pst.setObject(3, gender); pst.setObject(4, salary); int len = pst.executeUpdate();//此處不能傳sql System.out.println(len);
不會(huì)有sql注入
String sql = "SELECT * FROM t_employee where ename=?"; //即使輸入'張三' or '1'= '1'也沒(méi)問(wèn)題 PreparedStatement pst = conn.prepareStatement(sql); //中間加入設(shè)置?的值 pst.setObject(1, ename); ResultSet rs = pst.executeQuery();
處理blob類型的數(shù)據(jù)
String sql = "insert into user(username,photo) values(?,?)";
PreparedStatement pst = conn.prepareStatement(sql);
//設(shè)置?的值
pst.setObject(1, "xiaoyu");
FileInputStream fis = new FileInputStream("D:/QMDownload/img/15.jpg");
pst.setBlob(2, fis);
int len = pst.executeUpdate();
System.out.println(len>0?"成功":"失敗");
注意兩個(gè)問(wèn)題:
①my.ini關(guān)于上傳的字節(jié)流文件有大小限制,可以在my.ini中配置變量
? max_allowed_packet=16M
②每一種blob有各自大小限制:
tinyblob:255字節(jié)、blob:65k、mediumblob:16M、longblob:4G
到此這篇關(guān)于JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別分析的文章就介紹到這了,更多相關(guān)JDBC基本操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)簡(jiǎn)單的抽牌游戲
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單的抽牌游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
Java鎖競(jìng)爭(zhēng)導(dǎo)致sql慢日志原因分析
這篇文章主要介紹了Java鎖競(jìng)爭(zhēng)導(dǎo)致sql慢的日志原因分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-11-11
SpringBoot中使用Swagger的超簡(jiǎn)單方法
大家一致認(rèn)為springBoot使用swagger太麻煩了,每次都需要編寫(xiě)config,今天小編告訴大家一種超簡(jiǎn)單配置方法,教大家如何整合swagger,感興趣的朋友跟隨小編一起看看吧2021-07-07
Java的設(shè)計(jì)模式編程中迪米特法則的應(yīng)用示例
這篇文章主要介紹了Java的設(shè)計(jì)模式編程中迪米特法則的應(yīng)用示例,迪米特法則中主張創(chuàng)建和使用弱耦合的類,需要的朋友可以參考下2016-02-02
基于SpringBoot使用MyBatis插件的問(wèn)題
MyBatis-Plus并不能為我們解決所有問(wèn)題,例如一些復(fù)雜的SQL,多表聯(lián)查,我們就需要自己去編寫(xiě)代碼和SQL語(yǔ)句,我們?cè)撊绾慰焖俚慕鉀Q這個(gè)問(wèn)題呢,這個(gè)時(shí)候可以使用MyBatisX插件,今天小編給大家?guī)?lái)了SpringBoot使用MyBatis插件問(wèn)題,感興趣的朋友一起看看吧2022-03-03
Java 帶參數(shù)與帶返回值的方法的定義和調(diào)用
在java中,方法就是用來(lái)完成解決某件事情或?qū)崿F(xiàn)某個(gè)功能的辦法。方法實(shí)現(xiàn)的過(guò)程中,會(huì)包含很多條語(yǔ)句用于完成某些有意義的功能——通常是處理文本,控制輸入或計(jì)算數(shù)值,這篇文章我們來(lái)探究一下帶參數(shù)與帶返回值的方法的定義和調(diào)用2022-04-04
spring boot使用logback實(shí)現(xiàn)多環(huán)境日志配置詳解
這篇文章主要介紹了spring boot使用logback實(shí)現(xiàn)多環(huán)境日志配置詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08

