認識 JDBC
JDBC (Java DataBase Connectivity) 是 Java 數據庫連接技術的簡稱,用于連接常用數據庫。
Sun 公司提供了 JDBC API ,供程序員調用接口和類,集成在 java.sql 和 javax.sql 包中。
Sun 公司還提供了 DriverManager 類用來管理各種不同的JDBC驅動。
不同數據庫廠商提供各自的JDBC驅動,所以我們想要連接數據庫除了要了解 JDBC API 還需要下載各數據庫廠商的驅動 jar 包。
JDBC API
JDBC API主要用于與數據庫建立連接、執行SQL語句、處理結果,其中核心類和接口如下:
- DriverManager:依據數據庫的不同,管理JDBC驅動
- Connection:負責連接數據庫并擔任傳送數據的任務
- Statement:由 Connection 產生、負責執行SQL語句
- ResultSet:負責保存 Statement 執行后所產生的查詢結果
JDBC 編碼模板
1、與數據庫建立連接并獲取連接
Connection connection=DriverManager.getConnection(URL,數據庫用戶名,密碼);
2、發送SQL語句,得到執行結果
Statement stmt=connection.createStatement();
ResultSet rs=stmt.executeQuery(SQL語句);
3、處理返回結果
while(rs.next()){int a=rs.getInt("a");String b=rs.getString("b");Date d=rs.getDate("d");……
}
4、釋放資源
rs.close();
stmt.close();
connection.close();
使用 JDBC 連接到 MySQL 數據庫
本例適合已經會使用 MySQL 數據庫的同學,首先我們下載 JDBC 的驅動 jar 包。這個網址提供了 MySQL 各種語言連接數據庫的驅動 https://www.mysql.com/products/connector/,MySQL Connector / J 8.0與從MySQL 5.5開始的所有MySQL版本兼容。
8.0下載地址
下載完成后解壓,后將jar添加依賴到項目中。
連接到MySQL數據庫
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;public class DemoConnectMySQL {public static void main(String[] args) {//連接MySQL的URLString url="jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";//MySQL數據庫用戶名String user="root";//MySQL數據庫的密碼String password="1234";Connection connection=null;try {connection=DriverManager.getConnection(url, user, password);System.out.println("連接成功");} catch (SQLException e) {e.printStackTrace();}finally {try {connection.close();System.out.println("連接關閉");} catch (SQLException e) {e.printStackTrace();}}}
}
url指定數據庫的連接字符串,格式為:
jdbc:數據庫://ip或域名:端口號?參數&參數……
這里的參數 useUnicode=true 使用Unicode字符,characterEncoding=utf8 設置編碼防止中文亂碼,serverTimezone=UTC 設置時區,useSSL=false 不使用SSL
jdbc4.0不需要加載驅動
PreparedStatement 增刪改
PreparedStatement 繼承了 Statement 接口,表示預編譯的 SQL 語句對象,SQL 語句被預編譯并存儲在 PreparedStatement 對象中,可以使用此對象多次高效地執行該語句。(還避免了 SQL 注入的隱患)
先準備好數據庫 books
表 book
字段 | 類型 | 屬性 |
---|---|---|
id | 整數 | 主鍵,自增 |
bName | 字符串 | 非空 |
price | 小數 | 非空 |
腳本也準備好了
#創建數據庫
CREATE DATABASE books;
USE books;
#創建表
CREATE TABLE book ( id INT primary key auto_increment, bName VARCHAR ( 255 ) NOT NULL, price FLOAT NOT NULL
);
PreparedStatement添加數據
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class TestInsert {public static void main(String[] args) {Connection connection=null;PreparedStatement pstmt=null;String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";String user="root";String password="1234";try {connection=DriverManager.getConnection(url,user,password);//sql語句String sql="insert into book(bName,price) values (?,?)";pstmt=connection.prepareStatement(sql);//傳入參數pstmt.setString(1, "《java入門到改行》");pstmt.setFloat(2, 11.11f);int result=pstmt.executeUpdate();System.out.println("受影響行數:"+result);} catch (SQLException e) {e.printStackTrace();}finally {if (pstmt!=null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
說明:
1、連接字符串要修改數據庫名字為 books
String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
2、插入數據庫的數據不能拼接而是要用 ?
代替
String sql="insert into book(bName,price) values (?,?)";
3、?
代替的參數要通過 set類型(位置,值)
傳入
pstmt.setString(1, "《java入門到改行》");
pstmt.setFloat(2, 11.11f);
pstmt.setXxx()的位置從 1 開始!
4、增刪改的SQL語句都使用這個方法,返回受影響行數
int result=pstmt.executeUpdate();
刪除數據
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class TestDelete {public static void main(String[] args) {Connection connection=null;PreparedStatement pstmt=null;String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";String user="root";String password="1234";try {connection=DriverManager.getConnection(url,user,password);//sql語句String sql="delete from book where id=?";pstmt=connection.prepareStatement(sql);//傳入參數 要刪除idpstmt.setInt(1, 1);int result=pstmt.executeUpdate();System.out.println("受影響行數:"+result);} catch (SQLException e) {e.printStackTrace();}finally {if (pstmt!=null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
修改數據
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class TestUpdate {public static void main(String[] args) {Connection connection=null;PreparedStatement pstmt=null;String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";String user="root";String password="1234";try {connection=DriverManager.getConnection(url,user,password);//sql語句String sql="update book set bName=?,price=? where id=?";pstmt=connection.prepareStatement(sql);//傳入參數 要刪除idpstmt.setString(1, "《MySQL從刪庫到跑路》");pstmt.setFloat(2, 16.66f);pstmt.setInt(3, 2);int result=pstmt.executeUpdate();System.out.println("受影響行數:"+result);} catch (SQLException e) {e.printStackTrace();}finally {if (pstmt!=null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
增、刪、改操作的寫法都一樣,都調用 executeUpdate() 方法返回一個受影響行數,唯一不同的 SQL語句。
PreparedStatement 查詢數據
查詢數據需要用到 ResultSet 類保存返回的結果集,我們獲取數據要操作 ResultSet 獲取。
ResultSet 常用方法
方法名 | 說明 |
---|---|
boolean next() | 將游標從當前位置向下移動一行 |
void close() | 關閉 ResultSet 對象 |
int getInt(int colIndex) | 以int形式獲取結果集當前行指定列號值 |
int getInt(String colLabel) | 以int形式獲取結果集當前行指定列名值 |
float getFloat(String colLabel) | 以float形式獲取結果集當前行指定列名值 |
String getString(String colLabel) | 以 String 形式獲取結果集當前行指定列名值 |
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class TestSelect {public static void main(String[] args) {Connection connection=null;PreparedStatement pstmt=null;ResultSet rs=null;String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";String user="root";String password="1234";try {connection=DriverManager.getConnection(url,user,password);//sql語句String sql="select bName,price,id from book where id=?";pstmt=connection.prepareStatement(sql);//傳入查詢條件pstmt.setInt(1, 2);rs=pstmt.executeQuery();while(rs.next()) {//通過列名獲取列的值int id=rs.getInt("id");//通過位置獲取列的值String bName=rs.getString(1);float price=rs.getFloat("price");System.out.println(id+" "+bName+" "+price);}} catch (SQLException e) {e.printStackTrace();}finally {if(rs!=null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (pstmt!=null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
關閉對象時注意關閉的順序,后使用的先關閉:rs.close()->pstmt.close()->connection.close()
ResultSet 對象存在一個光標,光標所指行為當前行。想要獲取列的數據需要先指向一行,所以要先指定 next() 方法用于指向一行,如果沒有數據next()方法返回false,有數據返回true。
使用 getXxx() 方法獲取列的數據時建議寫列名,這樣好識別