概念∶Java DataBase Connectivity Java 數(shù)據(jù)庫連接, Java語言操作數(shù)據(jù)庫。
JDBC本質(zhì):其實是官方(sun公司)定義的一套操作所有關(guān)系型數(shù)據(jù)庫的規(guī)則,即接口。各個數(shù)據(jù)庫廠商去實現(xiàn)這套接口,提供數(shù)據(jù)庫驅(qū)動jar包。我們可以使用這套接口(DBC)編程,真正執(zhí)行的代碼是驅(qū)動jar包中的實現(xiàn)類。
- 步驟∶
- 導(dǎo)入驅(qū)動jar包
1,復(fù)制mysql-connector-java-5.1.37-bin.jar到項目的libs目錄下
2,右鍵-- >Add As Library(將jar包加載到項目中)
2.注冊驅(qū)動
Class.forName("com.mysql.jdbc.Driver");
3.獲取數(shù)據(jù)庫連接對象connection
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "123456");
4.定義sql
String sql="update account set balance=5000 where id=1";
5.獲取執(zhí)行sql語句的對象statement
Statement statement = conn.createStatement();
6.執(zhí)行sql,接受返回結(jié)果
int count = statement.executeUpdate(sql);
7.處理結(jié)果
System.out.println(count);//報錯:在libs加入版本低的jar包
8.釋放資源
statement.close(); conn.close();
- 詳解各個對象∶
- DriverManager:驅(qū)動管理對象
1.注冊驅(qū)動︰告訴程序該使用哪一個數(shù)據(jù)庫驅(qū)動jar
DriverManager方法:static void registerDriver(Driver driver) :注冊與給定的驅(qū)動程序 DriverManager
寫代碼使用:class.forName( "com.mysql.jdbc.Driver");
注意:mysql5之后的驅(qū)動jar包可以省略注冊驅(qū)動的步驟。
通過查看源碼發(fā)現(xiàn)∶在com.mysql.jdbc.Driver類中存在靜態(tài)代碼塊
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException( "can't register driver!");
}
2.獲取數(shù)據(jù)庫連接︰
方法:static Connection getConnection(string url,string user,string password
參數(shù):
url:idbc :mysql:/ /ip地址(域名):端口號/數(shù)據(jù)庫名稱("jdbc:mysql://localhost:3306/db3")
細(xì)節(jié)∶如果連接的是本機(jī)my sql服務(wù)器,并且mysql服務(wù)默認(rèn)端口是3306,則url可以簡寫為: jdbc:mysql:///
數(shù)據(jù)庫名稱user:用戶名(“root”)
password:密碼("123456")
- connection:數(shù)據(jù)庫鏈接對象
方法介紹:
獲取執(zhí)行sql 的對象:statement createstatement()Preparedstatement preparestatement(string sql)
開啟事務(wù):setAutoCommit(boolean autoCommit):調(diào)用該方法設(shè)置參數(shù)為false,即開后事務(wù)
提交事務(wù):commit()
回滾事務(wù):rollback()
- statement:sql執(zhí)行對象
方法介紹:
boolean execute(string sql);可以執(zhí)行任意的sql(了解)
int executeupdate(string sql) 執(zhí)行DML (insert、update、delete)語句、DOL(create,,alter、drop)語句
返回值:影響數(shù)據(jù)庫數(shù)據(jù)的行數(shù),可以通過這個影響的行數(shù)判斷DwL語句是否執(zhí)行成功返回值>0的則執(zhí)行成功,反之,則失敗。
Resultset executeQuery(string sql)︰執(zhí)行DQL (select)語句
- Resultset :結(jié)果集對象,封裝查詢結(jié)果
方法介紹:
next():游標(biāo)向下移動一行 類似指針 游標(biāo)向下移動一行,判斷當(dāng)前行是否是最后一行末尾(是否有數(shù)據(jù)),如果是,則返回false,如果不是則返回true
getxxx(參數(shù)):獲取數(shù)據(jù)
xxx:代表數(shù)據(jù)類型如: int getInt() , string getstring()
參數(shù)∶int :代表列的編號,從1開始如: getstring(1) string :代表列名稱。如: getDouble( "balance" )
注意:
使用步驟:
1,游標(biāo)向下移動一行 2,判斷是否有數(shù)據(jù) 3,獲取數(shù)據(jù)
//循環(huán)判斷游標(biāo)是否是最后一行末尾。
while(rs.next()){
int id = rs.getInt(1);
string name = rs.getstring( "name" );double balance = rs.getDouble(3);
system.out.println(id + "---" + name + "---" + balance);
}
- Preparedstatement :sql執(zhí)行對象
1.SQL注入問題∶在拼接sql時,有一些sql的特殊關(guān)鍵字參與字符串的拼接。會造成安全性問題
輸入用戶隨便,輸入密碼:a' or 'a' = 'a
sql : select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
2,解決sql注入問題:使用Preparedstatement對象來解決
3,預(yù)編譯的SQL:參數(shù)使用?作為占位符
4,步驟∶
1.導(dǎo)人驅(qū)動jar包mysql-connector-java-5.1.37-bin.jar
2.注冊驅(qū)動
3.獲取數(shù)據(jù)庫連接對象 connection
4.定義sql:
注意: sql的參數(shù)使用?作為占位符。如: select * from user where username = ? and password = ?;
5.獲取執(zhí)行sql語句的對象 PreparedStatement Connection.prepareStatement(string sql)
6.給?賦值:
*方法:setXxx(參數(shù)1[?的位置],參數(shù)2[?的值])
7.執(zhí)行sql,接受返回結(jié)果,不需要傳遞sql語句
8.處理結(jié)果
9.釋放資源
try {
//獲取數(shù)據(jù)庫連接
conn = JdbcUtils.getConnection();
//sql語句
String sql="select * from user where username=? and password=?";
//獲取sql執(zhí)行對象
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
//執(zhí)行sql
res = preparedStatement.executeQuery();
return res.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(res,preparedStatement,conn);
}
- 抽取JDBC工具類
package com.xjbt.Untis;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
//設(shè)置靜態(tài)資源,在靜態(tài)方法和靜態(tài)代碼塊上都可以使用可以直接使用
private static String url;
private static String user;
private static String password;
private static String driver;
static{//靜態(tài)代碼塊,隨著類的加載只加載一次
//讀取資源(JDBC.properties)文件獲取值
//1創(chuàng)建Properties集合類
Properties pro=new Properties();
try {
//獲取src路徑下的文件的方式-->ClassLoader類加載器(加載字節(jié)碼文件進(jìn)內(nèi)存,獲取src路徑下的資源文件)
ClassLoader classLoader = JdbcUtils.class.getClassLoader();//通過字節(jié)碼文件(JdbcUtils.class)的方法得到ClassLoader類加載器
URL res=classLoader.getResource("JDBC.properties");//獲取到資源文件的絕對路徑對象(URL統(tǒng)一資源定位符,定位一個文件的絕對地址)
String path=res.getPath();//轉(zhuǎn)化成字符串
//2,load方法可以加載properties文件
pro.load(new FileReader(path));
//3.獲取數(shù)據(jù),賦值
url = pro.getProperty ("url");
user = pro.getProperty("user");
password=pro.getProperty ("password");
driver=pro.getProperty ("driver");
try {
//4.注冊驅(qū)動
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//獲取連接對象
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
};
//釋放資源方法
public static void close(Statement statement,Connection conn){
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//釋放資源方法(重載)
public static void close(ResultSet res,Statement statement,Connection conn){
if(res!=null){
try {
res.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC控制事務(wù)︰
1,事務(wù):一個包含多個步驟的業(yè)務(wù)操作。如果這個業(yè)務(wù)操作被事務(wù)管理,則這多個步驟要么同時成功,要么同時失敗。
2.操作:1.開啟事務(wù)2.提交事務(wù)3.回滾事務(wù)
3.使用connection對象來管理事務(wù)
開啟事務(wù): setAutoCommit(boolean autoCommit) :調(diào)用該方法設(shè)置參數(shù)為false,即開后事務(wù)
提交事務(wù): commit()
回滾事務(wù): rollback()
package com.xjbt.jdbc;
import com.xjbt.Untis.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcAuto {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement preparedStatement1=null;
PreparedStatement preparedStatement2=null;
try {
conn=JdbcUtils.getConnection();
conn.setAutoCommit(false);//開啟事務(wù)
String sql1="update account set balance=balance-? where id=?";
String sql2="update account set balance=balance+? where id=?";
preparedStatement1= conn.prepareStatement(sql1);
preparedStatement2= conn.prepareStatement(sql2);
preparedStatement1.setDouble(1,500);
preparedStatement1.setInt(2,1);
preparedStatement2.setDouble(1,500);
preparedStatement2.setInt(2,2);
//執(zhí)行
preparedStatement1.executeUpdate();
//int i=3/0;
preparedStatement2.executeUpdate();
conn.commit();//提交事務(wù)
} catch (Exception e) {
try {
if(conn!=null){
conn.rollback();//回滾事務(wù)
}
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}finally {
JdbcUtils.close(preparedStatement1,conn);
JdbcUtils.close(preparedStatement1,null);
}
}
}