1.簡(jiǎn)介
JDBC 指 Java 數(shù)據(jù)庫連接,是一種標(biāo)準(zhǔn)Java應(yīng)用編程接口( JAVA API),用來連接 Java 編程語言和廣泛的數(shù)據(jù)庫。
常見的 JDBC 組件
DriverManager :這個(gè)類管理一系列數(shù)據(jù)庫驅(qū)動(dòng)程序。匹配連接使用通信子協(xié)議從 JAVA 應(yīng)用程序中請(qǐng)求合適的數(shù)據(jù)庫驅(qū)動(dòng)程序。識(shí)別 JDBC 下某個(gè)子協(xié)議的第一驅(qū)動(dòng)程序?qū)⒈挥糜诮?shù)據(jù)庫連接。
Driver : 這個(gè)接口處理與數(shù)據(jù)庫服務(wù)器的通信。你將很少直接與驅(qū)動(dòng)程序互動(dòng)。相反,你使用 DriverManager 中的對(duì)象,它管理此類型的對(duì)象。它也抽象與驅(qū)動(dòng)程序?qū)ο蠊ぷ飨嚓P(guān)的詳細(xì)信息。
Connection : 此接口具有接觸數(shù)據(jù)庫的所有方法。該連接對(duì)象表示通信上下文,即,所有與數(shù)據(jù)庫的通信僅通過這個(gè)連接對(duì)象進(jìn)行。
Statement ( 傳輸器對(duì)象 ): 使用創(chuàng)建于這個(gè)接口的對(duì)象將 SQL 語句提交到數(shù)據(jù)庫。除了執(zhí)行存儲(chǔ)過程以外,一些派生的接口也接受參數(shù)。
executeQuery(String sql)--用于向數(shù)據(jù)庫發(fā)送查詢類型的sql語句,返回一個(gè) ResultSet對(duì)象中。
executeUpdate(String sql)--用于向數(shù)據(jù)庫發(fā)送更新(增加、刪除、修改)類型的sql語句,返回一個(gè)int值,表示影響的記錄行數(shù)。
ResultSet ( 結(jié)果集對(duì)象 ): 在你使用語句對(duì)象執(zhí)行 SQL 查詢后,這些對(duì)象保存從數(shù)據(jù)獲得的數(shù)據(jù)。它作為一個(gè)迭代器,讓您可以通過它的數(shù)據(jù)來移動(dòng)。
next()--遍歷數(shù)據(jù)行的方法,使指向數(shù)據(jù)行的箭頭向下移動(dòng)一行,如果返回true則表示箭頭指向的行有數(shù)據(jù)(記錄),如果返回 false,則表示箭頭指向的行沒有數(shù)據(jù)(記錄)。
SQLException : 這個(gè)類處理發(fā)生在數(shù)據(jù)庫應(yīng)用程序的任何錯(cuò)誤。
2.入門案例
package JDBC.day1;
import java.sql.*;
//JBDC快速入門程序
//查詢account表中的所有數(shù)據(jù),將查詢結(jié)果輸出到控制臺(tái)
public class JBDC_1 {
public static void main(String[] args) throws Exception {
//注冊(cè)數(shù)據(jù)庫驅(qū)動(dòng)
Class.forName("com.mysql.cj.jdbc.Driver");
//獲取數(shù)據(jù)鏈接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jt_db?serverTimezone=GMT&characterEncoding=utf-8","root","root");
//獲取傳輸器
Statement stat = conn.createStatement();
//發(fā)送sql到服務(wù)器執(zhí)行并返回執(zhí)行結(jié)果
String sql = "select * from account";
ResultSet rs = stat.executeQuery(sql);
//處理結(jié)果
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+":"+name+":"+money);
}
//釋放資源-越先執(zhí)行的越晚釋放
rs.close();
stat.close();
conn.close();
}
}
3.增刪改查
先添加JDBC工具類:實(shí)現(xiàn)注冊(cè)驅(qū)動(dòng)并獲取鏈接對(duì)象,以及釋放jdbc程序中的資源
package JDBC.day1;
import java.sql.*;
//jdbc工具類
public class JdbcUtil {
/*
* 注冊(cè)驅(qū)動(dòng)并獲取鏈接對(duì)象
* @return conn連接對(duì)象
* */
public static Connection getConn(){
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jt_db?serverTimezone=GMT&characterEncoding=utf-8","root","root");
return conn;
} catch (Exception throwables) {
throwables.printStackTrace();
}
return null;
}
/*
* 釋放jdbc程序中的資源
* @param conn連接對(duì)象
* @param stat傳輸器對(duì)象
* @param rs結(jié)果集對(duì)象
*/
public static void close(ResultSet rs, Statement stat, Connection conn){
if(rs != null){
try {
rs.close();
}catch (SQLException E){
E.printStackTrace();
}finally {
rs = null;
}
}
if(stat != null){
try {
stat.close();
}catch (SQLException E){
E.printStackTrace();
}finally {
stat = null;
}
}
if(conn != null){
try {
conn.close();
}catch (SQLException E){
E.printStackTrace();
}finally {
conn = null;
}
}
}
}
新增
@Test
public void testInsert() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注冊(cè)驅(qū)動(dòng)并獲取連接
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql:///jt_db?characterEncoding=utf-8",
"root", "root");
//獲取傳輸器
stat = conn.createStatement();
//發(fā)送sql到服務(wù)器執(zhí)行,并返回結(jié)果
String sql = "insert into account values(null, 'john', 3500)";
int rows = stat.executeUpdate( sql );
//處理結(jié)果
System.out.println( "影響行數(shù):"+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
JdbcUtil.close(conn, stat, rs);
}
}
修改
@Test
public void testUpdate() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注冊(cè)驅(qū)動(dòng)并獲取鏈接
conn = JdbcUtil.getConn();
//獲取傳輸器,發(fā)送sql到服務(wù)器執(zhí)行,返回結(jié)果
stat = conn.createStatement();
String sql = "update account set money = 1500 where name='john'";
int rows = stat.executeUpdate( sql );
System.out.println( "影響行數(shù): "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
JdbcUtil.close(conn, stat, rs);
}
}
刪除
@Test
public void testDelete() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注冊(cè)驅(qū)動(dòng)并獲取鏈接
conn = JdbcUtil.getConn();
//獲取傳輸器,發(fā)送sql到服務(wù)器執(zhí)行,返回結(jié)果
stat = conn.createStatement();
String sql = "delete from account where name='john'";
int rows = stat.executeUpdate( sql );
System.out.println( "影響行數(shù): "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
JdbcUtil.close(conn, stat, rs);
}
}
查詢
@Test
public void testFind() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConn();
stat = conn.createStatement();
String sql = "select * from account where name='john'";
rs = stat.executeQuery( sql );
while( rs.next() ) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+" : "+name+" : "+money);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(conn, stat, rs);
}
}
4.用戶登錄案例
SQL注入攻擊:由于后臺(tái)的SQL語句是拼接而來的, 其中的參數(shù)是用戶提交過來:String sql = "select * from user where username='"+user+"' and password='"+pwd+"'";不輸入密碼只輸入用戶名也可以登陸成功。這就是SQL注入攻擊。
防止SQL注入攻擊:
(1)使用正則表達(dá)式對(duì)用戶提交的參數(shù)進(jìn)行校驗(yàn)。
(2)使用PreparedStatement對(duì)象來替代Statement對(duì)象。
package JDBC.day1;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;
//模擬用戶登錄
public class LonginUser {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請(qǐng)登錄:");
System.out.println("請(qǐng)輸入用戶名:");
String user = sc.nextLine();
System.out.println("請(qǐng)輸入密碼:");
String pwd = sc.nextLine();
login(user,pwd);//調(diào)用login方法實(shí)現(xiàn)登錄
}
//根據(jù)用戶名和密碼查詢user表,如果能夠查詢到數(shù)據(jù)規(guī)則允許登錄,否則登錄失敗
private static void login(String user, String pwd) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConn();//注冊(cè)驅(qū)動(dòng)并獲取連接
//獲取傳輸器并發(fā)送到sql服務(wù)器執(zhí)行,返回執(zhí)行結(jié)果
String sql = "select * from user where username=? and password=?";//一個(gè)?一個(gè)參數(shù)
ps = conn.prepareStatement(sql);
ps.setString(1,user);//設(shè)置sql參數(shù)
ps.setString(2,pwd);
rs = ps.executeQuery();//執(zhí)行sql語句
if(rs.next()){//處理結(jié)果
System.out.println("登錄成功!");
}else System.out.println("登錄失??!");
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtil.close(rs,ps, conn);
}
}
}