目錄
前言
1、Java的數(shù)據(jù)庫編程:JDBC??
?2、使用JDBC(項目中導入數(shù)據(jù)庫驅(qū)動包)
2.1、獲取驅(qū)動包
2.2、將數(shù)據(jù)庫驅(qū)動包導入Java項目中
2.3、使用JDBC編寫代碼
2.3.1、創(chuàng)建并初始化一個數(shù)據(jù)源
2.3.2、 和數(shù)據(jù)庫服務(wù)器建立鏈接
2.3.3、構(gòu)建SQL語句?
2.3.4、執(zhí)行SQL語句?
2.3.4、釋放資源
2.3.5、JDBC的方式插入數(shù)據(jù)(insert)
2.3.6、JDBC的方式查詢數(shù)據(jù)(select)
前言
- 我們使用的數(shù)據(jù)庫有多種多樣的,有MySQL、Oracle、SQL sever等等、這些數(shù)據(jù)庫在開發(fā)的時候,都會提供一組程序接口(API).
- API(Application Programming Interface):我們就舉一個更簡單一點的例子。軟件開發(fā)員甲開發(fā)了一款軟件,但是這款軟件里面某些功能軟件開發(fā)員乙也想使用,這個時候甲就可以把軟件里面的這些功能打包成一個函數(shù),開放給乙進行使用,乙自然也就不需要進行源碼的查看,那么這個函數(shù)也就是api。我們基于api提供的功能來實現(xiàn)一些其他的代碼。
- JDBC存在兩種寫法,一種是DataSource的方式來編寫的(這種是現(xiàn)在使用比較多的,也是這個博客中介紹的方法);還有一種是DriverManager方式編寫,這個是通過反射的方式加載驅(qū)動包中的類,進一步進行后續(xù)的操作。這里更建議使用第一種方法。
1、Java的數(shù)據(jù)庫編程:JDBC??
上面說到的MySQL、Oracle、SQL sever等等這些數(shù)據(jù)庫,都會提供一個api接口,但是不同的數(shù)據(jù)庫存在自己的數(shù)據(jù)庫api,這樣就導致程序員的學習成本太高。沒使用一種數(shù)據(jù)庫還要學習它的api。如果有一個東西可以規(guī)范這些接口,那么學習成本就降低了很多,這里我們就要說到JDBC。
- JDBC(Java Database Connectivity),他是一套統(tǒng)一的、基于Java語言的關(guān)系數(shù)據(jù)庫編程接口的規(guī)范。
- 對于這些數(shù)據(jù)庫的api,這些數(shù)據(jù)庫的廠商需要自己提供一個封裝自己數(shù)據(jù)庫的原生api的程序與JDBC對齊,這個程序就叫做數(shù)據(jù)庫驅(qū)動包。
?
?文章來源地址http://www.zghlxwxcb.cn/news/detail-431190.html
對于Java程序員想要進行數(shù)據(jù)庫的開發(fā),就需要在項目中導入對應(yīng)的數(shù)據(jù)庫驅(qū)動包,才能進行編寫代碼。
?這里解釋一下驅(qū)動的意思:驅(qū)動這個詞我們在硬件中常會聽到,硬件的驅(qū)動是讓操作系統(tǒng)認識新的硬件設(shè)備。而我們這里的數(shù)據(jù)庫的驅(qū)動就是讓JDBC能夠認識數(shù)據(jù)庫的api.
?2、使用JDBC(項目中導入數(shù)據(jù)庫驅(qū)動包)
2.1、獲取驅(qū)動包
三種途徑?
- MySQL的官方網(wǎng)站上獲取
- 因為MySQL是開源的所以可以在github中找
- maven中央倉庫中獲取。
maven就像我們使用手機的應(yīng)用商店一樣。手機上下載軟件可以去官網(wǎng)也可以在手機的應(yīng)用商店上找。maven中央倉庫上面托管了各種軟件程序包。進入mavem中央倉庫使用鏈接https://mvnrepository.com
1??下面這兩種都可以
2?? 在點擊進入之后,讓我們選擇使用的版本,這里注意,選的版本要與我們自己裝的數(shù)據(jù)庫版本匹配。大版本一定要匹配,小版本可以隨便選。
?
3?? 點擊選擇需要的版本進入之后,點擊jar下載即可。
?4??得到j(luò)ar包
?在javase的博客中說到Java程序通過.java 源文件編譯成.class文件,再使用jvm來解釋執(zhí)行成?.class文件。我們想要發(fā)布一個程序讓別人使用,我們可以將這些.class文件拷貝給對方,使用它的jvm運行就行。但是又有一個問題,當我們的程序有很多的.class 文件,這樣一起拷貝給對方,總顯得不太好用,這個時候我們可以使用壓縮包的形式,將多個.class文件以壓縮包的形式發(fā)給對方。這就是Java中最常用的發(fā)布程序的方式,形成.jar包。
2.2、將數(shù)據(jù)庫驅(qū)動包導入Java項目中
???每創(chuàng)建一個項目需要這樣操作一次
1??創(chuàng)建一個新的項目,并在這個項目中創(chuàng)建一個新的目錄lib,將數(shù)據(jù)庫驅(qū)動包導入
?2??把lib這個目錄標記成項目的庫
將這個目錄標記成庫,idea就能識別這個目錄里的jar包了。我們就可以調(diào)用里面的類來寫代碼了。
2.3、使用JDBC編寫代碼
2.3.1、創(chuàng)建并初始化一個數(shù)據(jù)源
數(shù)據(jù)源:我們的數(shù)據(jù)從數(shù)據(jù)庫中來,所以數(shù)據(jù)源就是用來描述數(shù)據(jù)庫服務(wù)器在哪里的。JDBC中用DataSource這個接口來進行描述。
這里有兩種寫法。
1??使用DataSource接口的引用接收MysqlDataSource對象
DataSource dataSource = new MysqlDataSource();//向上轉(zhuǎn)型 ((MysqlDataSource)dataSource).setUrl();//向下轉(zhuǎn)型,因為DataSource中沒有setUrl()這個方法,而MysqlDataSource這個類中有這個方法
2??或者直接使用MysqlDataSource類來寫也可以
MysqlDataSource mysqlDataSource = new MysqlDataSource(); mysqlDataSource.setUrl();
setUrl()方法表示設(shè)置資源所在的位置。這里URL是計算機里的一個常見術(shù)語——唯一資源定位符,描述網(wǎng)絡(luò)上的某個資源所在的位置。?這個方法的參數(shù)形式很特別
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
對他的參數(shù)大概了解一下
jdbc是固定的。
MySQL:是看你使用什么數(shù)據(jù)庫,這是一個數(shù)據(jù)庫名。
MySQL數(shù)據(jù)庫是一個“客戶端-服務(wù)器”結(jié)構(gòu)的程序,客戶端和服務(wù)器之間通過網(wǎng)絡(luò)來通信,網(wǎng)絡(luò)上確定主機的位置就是通過IP地址來確定的,現(xiàn)在我們學習的時候客戶端和服務(wù)器在同一臺電腦上,我們使用的是環(huán)回地址。
127.0.0.1:是環(huán)回地址,表示當前主機地址
3306:是端口號,數(shù)據(jù)庫服務(wù)器默認端口就是3306.端口是用來區(qū)分應(yīng)用程序的。區(qū)分將數(shù)據(jù)個那個應(yīng)用程序。
people_2:表示的數(shù)據(jù)庫名,我們創(chuàng)建了很多數(shù)據(jù)庫,到底想訪問哪一個。
characterEncoding:表示的是參數(shù)
utf8:字符集
SSL:是一個加密協(xié)議,此處設(shè)置成false表示不加密
?設(shè)置用戶名和密碼
((MysqlDataSource)dataSource).setUser("root");//設(shè)置用戶的時候,都是root
((MysqlDataSource)dataSource).setPassword("991218zf");//設(shè)置密碼的時候,安裝數(shù)據(jù)庫的時候密碼是什么就是什么
上述這些步驟合起來就是設(shè)置數(shù)據(jù)源的基本操作,只有將這三個都設(shè)置了,才能夠訪問數(shù)據(jù)庫服務(wù)器
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
public class JDBCInsert {
public static void main(String[] args) {
//1、創(chuàng)建并初始化一個數(shù)據(jù)源
DataSource dataSource = new MysqlDataSource();//向上轉(zhuǎn)型
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("991218zf");
???提示:上述的代碼只是設(shè)置了數(shù)據(jù)源,描述數(shù)據(jù)庫服務(wù)器在哪,還沒有和數(shù)據(jù)庫服務(wù)器真正的鏈接。
2.3.2、 和數(shù)據(jù)庫服務(wù)器建立鏈接
我們使用DataSource接口的getConnection方法來實現(xiàn)鏈接。
Connection connection = dataSource.getConnection() ;
在使用connection用來接收的時候,我們要選擇第一個,第一個是JDBC提供的,第二個是MySQL數(shù)據(jù)包提供的,不能使用。
但是當我們將這個寫了之后,編譯器會報錯。
?所以我們需要將這個異常進行處理,異常有受查異常和非受查異常
受查異常必須要顯示處理,處理方式有兩種
1??在調(diào)用這個方法的方法體開始throws這個異常
?2??或者通過try-catch處理這個異常
非受查異??梢圆挥蔑@示處理。
2.3.3、構(gòu)建SQL語句?
String sql = "insert into student values(1,'張三')";
PreparedStatement statement = connection.prepareStatement(sql);//進行預(yù)編譯
通過第一句代碼可以看見即使我們使用代碼來操作數(shù)據(jù)庫,還是靠sql語句,只不過是換成代碼來構(gòu)造sql。
???第二句代碼的作用是提前預(yù)編譯sql語句,為什么要進行預(yù)編譯呢?
???數(shù)據(jù)庫客戶端給服務(wù)器發(fā)送一個請求時SQL字符串,服務(wù)器是可以處理的,服務(wù)器需要對SQL經(jīng)行解析,理解這里的含義并執(zhí)行,這對于服務(wù)器的壓力就比較大了,如果是一個客戶端,那沒有什么問題,但是一個服務(wù)器同時可以接收很多客戶端發(fā)送的請求,都是以這樣的形式發(fā)送的,那么服務(wù)器的壓力就非常大了。這里我們通過在客戶端這里將這個SQL字符串進行預(yù)編譯,轉(zhuǎn)換成sql語句,這樣數(shù)據(jù)庫服務(wù)器的壓力就非常小了。
上述構(gòu)造SQL語句的這種寫法存在問題。直接將代碼寫死了,只能插入一條數(shù)據(jù),但是用戶在使用的時候,要插入的數(shù)據(jù)肯定不止一條。我們要實現(xiàn)寫一個插入的SQL語句,進行多條數(shù)據(jù)的插入。我們可以通過scanner類來實現(xiàn)讓用戶插入數(shù)據(jù)。
構(gòu)造sql語句時存在多種寫法
1??比較直接的寫法,通過字符串拼接的方法實現(xiàn)。
String sql = "insert into student values("+id+",'"+name+"')";
這種寫法是下策,它存在兩個問題
- name這里添加單引號和雙引號的位置很容易寫錯,可讀性很低
- 很容易被SQL注入,sql注入是網(wǎng)絡(luò)安全中的典型攻擊方式,指web應(yīng)用程序?qū)τ脩糨斎霐?shù)據(jù)的合法性沒有判斷或過濾不嚴,攻擊者可以在web應(yīng)用程序中事先定義好的查詢語句的結(jié)尾上添加額外的SQL語句,這就導致在程序員不知情的情況下,將數(shù)據(jù)庫中的數(shù)據(jù)刪除或者修改。
2??更好的寫法,借助PreparedStatement的拼裝功能來實現(xiàn)。
String sql = "insert into student values(?,?)";//這里的?表示的意思是占位符,表示先這個位置占住,用別的東西替換。 PreparedStatement statement = connection.prepareStatement(sql);//進行預(yù)編譯 statement.setInt(1,id);//表示將第一個?替換成id的值 statement.setString(2,name);//表示將第二個?替換成name的值
? 這個方法好處就是看起來更加直觀了,并且可以自動的對sql注入的攻擊的行為作為校驗。
2.3.4、執(zhí)行SQL語句?
int ret = statement.executeUpdate();
System.out.println("ret = "+ret);
這里通過executeUpdate方法把sql語句(預(yù)編譯過的)發(fā)送給數(shù)據(jù)庫服務(wù)器,由服務(wù)器做出響應(yīng)。
executeUpdate方法返回int類型的指用ret接收,這里ret接收到的值表示為執(zhí)行sql語句后影響到的行數(shù)。與數(shù)據(jù)庫中的這個表示的同一個意思
?這里執(zhí)行insert、delete、update這些操作的時候都使用executeUpdate這個方法。
2.3.4、釋放資源
statement.close();
connection.close();
數(shù)據(jù)庫的客戶端和服務(wù)器之間通信的時候,是要消耗一定的系統(tǒng)資源(這里的資源不限于CPU、內(nèi)存、硬盤、帶寬)。 對客戶端來說罷了,但是對服務(wù)器來說,同一時刻要處理很多個客戶端,給一個客戶端提供服務(wù),需要消耗一定的資源,給1000個、一萬個呢???這個時候消耗的資源就越來越多,服務(wù)器的資源就那么多,如何更好的利用這些資源?客戶端就得省著點用(不用的時候就將資源釋放)。
???注意:釋放的順序和創(chuàng)建的順序是相反的。在下面的代碼中鏈接(connection)是先創(chuàng)建的,語句(statement)是后創(chuàng)建的。所以釋放的時候statement先釋放,?connection后釋放
2.3.5、JDBC的方式插入數(shù)據(jù)(insert)
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
public class JDBCInsert {
public static void main(String[] args) throws SQLException{
Scanner scan = new Scanner(System.in);
//1、創(chuàng)建并初始化一個數(shù)據(jù)源
DataSource dataSource = new MysqlDataSource();//向上轉(zhuǎn)型
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("991218zf");
//2、和數(shù)據(jù)庫服務(wù)器建立聯(lián)接
Connection connection= dataSource.getConnection() ;
//3、構(gòu)造SQL語句
System.out.println("請輸入學生姓名:");
String name = scan.next();
System.out.println("請輸入學生的學號:");
int id = scan.nextInt();
String sql = "insert into student values(?,?)";
PreparedStatement statement = connection.prepareStatement(sql);//進行預(yù)編譯
statement.setInt(1,id);//表示將第一個?替換成id的值
statement.setString(2,name);//表示將第二個?替換成name的值
//這個打印需要加到拼接數(shù)據(jù)之后
System.out.println(statement);
//4、執(zhí)行SQL語句
int ret = statement.executeUpdate();
System.out.println("ret = "+ret);
//5、釋放必要的資源
statement.close();
connection.close();
}
}
?這里修改(update)和刪除(delete)這兩個操作在JDBC中的代碼和插入相同只需要將sql語句改變一下就行。
2.3.6、JDBC的方式查詢數(shù)據(jù)(select)
對查詢來說,返回結(jié)果不是單純的int了,而是ResultSet對象,表示的就是結(jié)果集合,相當于我們使用MySQL時,在客戶端查詢產(chǎn)生結(jié)果得到的臨時表。
?當光標指向哪一行,就通過getXXX方法將哪一行的數(shù)據(jù)獲取。
代碼示例
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.*;
import java.util.logging.Logger;
public class JDBCSelect {
public static void main(String[] args) throws SQLException{
//1、創(chuàng)建并初始化數(shù)據(jù)源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("991218zf");
//2、建立鏈接
Connection connection = dataSource.getConnection();
//3、構(gòu)造SQL
String sql = "select * from student";
PreparedStatement statement = connection.prepareStatement(sql);
//4、執(zhí)行SQL
ResultSet resultSet = statement.executeQuery();
//5、遍歷結(jié)果集合
while(resultSet.next()){
//把resultSet想象成一個表格,同時這個這個表格上方有一個光標,初始情況下光標指向表的最上面
//沒調(diào)用一次next,光標往下走一行
//當光標指向某一行的時候,就可以通過 getxxx 方法來獲取到當前這行里的數(shù)據(jù)
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("id = "+ id +",name = "+name);
}
//6、釋放資源
statement.close();
connection.close();
}
}
文章來源:http://www.zghlxwxcb.cn/news/detail-431190.html
?
到了這里,關(guān)于【數(shù)據(jù)庫】Java的JDBC編程(idea鏈接數(shù)據(jù)庫)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!