什么是JDBC?
解釋:JDBC全稱 Java DataBase Connectivity框喳,是使用java語言操作關(guān)系型數(shù)據(jù)庫的一套標準接口嫁蛇,可以適應(yīng)多種關(guān)系型數(shù)據(jù)庫锨并,比如oracle和DB2。
一睬棚、執(zhí)行流程:
- 編寫Java代碼
- 將內(nèi)嵌的SQL發(fā)送到MySQL服務(wù)端
- MySQL服務(wù)端接收SQL語句并且執(zhí)行該SQL語句
- 將SQL語句執(zhí)行結(jié)果返回給Java代碼
二第煮、根據(jù)執(zhí)行流程,連接過程為:
1抑党、注冊驅(qū)動
Class.forname("com.mysql.jdbc.Driver")
2包警、獲取連接
Connection connection=DriverManager.getConnection(url,username,password);
3、定義SQL語句
String sql="select* from xxx";
4底靠、獲取執(zhí)行SQL對象
Statement statement = conn.createStatement();
5害晦、執(zhí)行SQL
Statement statement=statement.createStatement();
三、涉及到的API
DriverManger:工具類
(1)注冊驅(qū)動
(2)獲取數(shù)據(jù)庫的連接
Statement:
public class Jdbc01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.注冊驅(qū)動暑中,可以省略不寫
Class.forName("com.mysql.jdbc.Driver");
//2.構(gòu)建數(shù)據(jù)庫連接對象的參數(shù)壹瘟,url,username鳄逾,password
String url="jdbc:mysql:///xxx";
String username="root";
String password="root";
//3.獲取數(shù)據(jù)庫連接對象
Connection connection = DriverManager.getConnection(url,username,password);
//4.定義SQL語句
String sql="update xxx set ordered=1111 where id=1";
//5.獲取執(zhí)行SQL對象稻轨,執(zhí)行SQL
Statement statement = connection.createStatement();
//6.返回結(jié)果集
int resultSet = statement.executeUpdate(sql);
System.out.println("受影響的行數(shù)"+resultSet);
statement.close();
connection.close();
}
}
Connection:數(shù)據(jù)庫連接對象
(1)獲取執(zhí)行SQL對象
- 普通執(zhí)行SQL對象
Statement createStatement() - 預(yù)編譯SQL的執(zhí)行SQL對象,防止SQL注入
PreparedStatement prepareStatement(sql) - 執(zhí)行存儲過程對象
CallableStatement prepareCall(sql)
(2)管理事務(wù) - Mysql中對事物進行控制的語句
事物開啟:
BEGIN/START TRANSA;
事物提交:
COMMIT;
事物回滾:
ROLLBACK;
- 對應(yīng)JDBC事物管理
事物開啟
setAutoCommit(false|true); true為自動提交事物雕凹,false為手動提交事務(wù)
事物提交
commit();
事物回滾
rollback();
模擬事物開啟殴俱,提交以及回滾
public class Jdbc02 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//jdbc的事務(wù)管理,開啟枚抵、提交线欲、回滾,connection支持對事物的管理
//mysql是默認提交的事務(wù)
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql:///xxx";
String username="root";
String pasword="root";
//獲取連接
Connection connection = DriverManager.getConnection(url,username,pasword);
//定義sql
String sql1="update tb_xxx set ordered=1111 where id=1";
String sql2="update tb_ xxx ordered=1111 where id=2";
//獲取執(zhí)行SQL的對象
Statement statement = connection.createStatement();
try {
//開啟事物,true為自動提交事物俄精,false為手動
connection.setAutoCommit(false);
int count1 = statement.executeUpdate(sql1);
int i=3/0;
System.out.println("影響的行數(shù)"+count1);
int count2 = statement.executeUpdate(sql2);
System.out.println("影響的行數(shù)"+count2);
//成功的時候進行事物的提交
connection.commit();
} catch (Exception e) {
e.printStackTrace();
//失敗的時候進行回滾事物
connection.rollback();
}finally {
//無論成功還是失敗询筏,這里都需要關(guān)閉相應(yīng)的資源
statement.close();
connection.close();
}
}
}
Statement:
(1)執(zhí)行sql語句
- excuteUpdate 返回的是int類型榕堰,操作的行數(shù)
- excuteQuery 返回值為結(jié)果集
ResultSet
(1)獲取查詢結(jié)果竖慧,使用游標:返回false,當前行為無效行逆屡,沒有數(shù)據(jù)圾旨,返回則有效。
(2)獲取數(shù)據(jù):getXxx
public class Jdbc03 {
public static void main(String[] args) throws SQLException {
String url="jdbc:mysql:///xxx";
String userName="root";
String password="root";
Connection connection = DriverManager.getConnection(url, userName, password);
String sql="select * from xxx";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println(id);
System.out.println(name);
}
resultSet.close();
statement.close();
connection.close();
}
}
SQL注入
為什么要使用PreparedStatement魏蔗?
createStatement存在SQL注入問題砍的,preparedStatement可以預(yù)防SQL注入問題
SQL注入:SQL注入是通過操作輸入來修改事先定義好的SQL語句,用以達到執(zhí)行代碼對服務(wù)器進行攻擊的方法莺治。
模擬簡單的SQL注入:首先新建一張sql表廓鞠,只有username和password就行帚稠,隨意插入兩條數(shù)據(jù)。
public class Jdbc04 {
//模擬SQL注入問題
public static void main(String[] args) throws SQLException {
String url="jdbc:mysql:///xxx";
String username="root";
String password="root";
Connection connection = DriverManager.getConnection(url,username,password);
//模擬登陸,接收到賬號和密碼
String name="張三";
String pwd="' or '1'='1 ";
//定義SQL
String sql="select * from tb_user where username='"+name+"' and password='"+pwd+"'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
//判斷是否登陸成功
if (resultSet.next()){
System.out.println("登陸成功");
System.out.println(sql);
}else {
System.out.println("登錄失敗");
}
//釋放資源
resultSet.close();
statement.close();
connection.close();
}
}
結(jié)果是登錄成功床佳,因為or 1=1恒成立滋早,SQL語句是這樣的:
select * from tb_user where username='張三' and password='' or '1'='1 '
preparedStatement的使用:
(1)獲取preparedStatement對象
(2)設(shè)置參數(shù)值
(3)執(zhí)行SQL
public class Jdbc05 {
@Test
public void jdbcPrepareStatement() throws SQLException {
String url="jdbc:mysql:///xxx";
String username = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url, username, password);
String name="張三";
String pwd="' or '1'='1 ";
String sql="select * from tb_user where username=? and password=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setString(2,pwd);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){
System.out.println("登陸成功!");
} else{
System.out.println("登錄失斊雒恰杆麸!");
}
resultSet.close();
preparedStatement.close();
connection.close();
}
}
總結(jié):preparedStatement的性能更好,而且將敏感字符進行轉(zhuǎn)義浪感。