jdbc连接mysql数据库的常用对象_JDBC常用对象
主要作用:
注冊驅動 實際開發中使用Class.forName("com.mysql,jdbc.Drive");這種方式,因為之前的方式會導致注冊兩次驅動
獲得連接 Connection getConnection(String url,String username,String password)
url寫法:jdbc:mysql://localhost:3306/jdbctest
jdbc 協議
mysql 子協議
localhost 主機名
3306 端口號
jdbctest 數據庫名
如果連接的是本機,可以簡寫為jdbc:mysql:///jbdctest
Connection 連接對象
主要作用:
創建用來執行SQL語句的對象
Statement createStatement() 執行SQL語句,有SQL注入漏洞威脅
PrepareStatement prepareStatement(String sql) 預編譯SQL語句,解決SQL注入
CallableStatement prepareCall(String sql) 執行SQL中的存儲過程
事務的管理
setAutoCommit(boolean autoCommit) 設置事務是否自動提交
commit() 事務提交
rollback() 事務回滾
Statement 執行SQL
主要作用:
執行SQL語句
boolean execute(String sql) 執行SQL,執行查詢語句返回true,否則返回false
ResultSet execute(String sql) 執行SQL中的查詢語句
int executeUpdate(String sql) 執行SQL中的插入、更新、刪除語句
執行批處理操作
addBatch(String sql) 添加到批處理
executeBatch() 執行批處理
clearBatch() 清空批處理
ResultSet 結果集
主要作用:
獲取查詢到的結果
next() 判斷是否存在下一條記錄
針對不同類型的數據可以使用getXXX()獲取數據
getObject() 通用獲取數據,可以獲取任何類型的數據
JDBC的SQL注入漏洞問題
package com.kernel.test;
import org.junit.Test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* 演示JDBC注入漏洞
*/
public class JDBCDemo04 {
@Test
/**
* 測試SQL注入
*/
public void demo1() {
//boolean result = login("aaa", "11");
//boolean result = login("aaa' or '1=1", "5454545");
boolean result = login("aaa' -- ", "sjjkhnjkhnk");
System.out.println(result);
}
public boolean login(String username, String password) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
statement = connection.createStatement();
String sql = "select * from user where username='" + username + "' and password='" + password + "'";
resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtil.release(resultSet, statement, connection);
}
return false;
}
}
我們來看下這是什么原因,有這樣一行代碼
boolean result = login("aaa' or '1=1", "5454545");
這時,sql就變成了這樣
sql = "select * from user where username='aaa' or '1=1' and password='545445'";
SQL會首先判斷and這個語句,and的結果為false,username='aaa',結果為true,true or false返回true
再來看第二條
sql "select * from user where username='aaa' -- and password='sjjkhnjkhnk'
-- 是注釋的意思,意思就是注釋后面的password=xxx,肯定返回true
如何解決呢
PrepareStatement是Statement的子接口,它的實例對象可以通過調用Connection.prepareStatement(sql)方法獲得,相對于Statement對象而言:
PrepareStatement可以避免SQL注入漏洞的問題
Statement會使數據庫頻繁的編譯SQL,可能造成數據庫緩沖區溢出,而PrepareStatement可以對SQL進行預編譯,提高數據庫執行效率
PrepareStatement允許使用占位符替換SQL中的參數,簡化編寫
package com.kernel.test;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* 演示JDBC注入漏洞
*/
public class JDBCDemo04 {
@Test
/**
* 測試SQL注入
*/
public void demo1() {
//boolean result = login("aaa", "11");
//boolean result = login("aaa' or '1=1", "5454545");
boolean result = logon("aaa' -- ", "sjjkhnjkhnk");
System.out.println(result);
}
/**
* 避免SQL注入漏洞
* @param username
* @param password
* @return
*/
public boolean logon(String username, String password) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from user where username=? and password=?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtil.release(resultSet, (Statement) preparedStatement, connection);
}
return false;
}
/**
* 產生SQL注入漏洞
*
* @param username
* @param password
* @return
*/
public boolean login(String username, String password) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
statement = connection.createStatement();
String sql = "select * from user where username='" + username + "' and password='" + password + "'";
resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtil.release(resultSet, statement, connection);
}
return false;
}
}
為什么使用它就可以避免SQL注入漏洞呢?那是因為創建對象的時候就將sql傳遞進去,并進行了預編譯,即使后面通過變量傳遞了關鍵字進來,也會認為這是字符串
數據庫連接池
連接池是創建和管理一個連接的緩沖池的技術,這些連接準備好被任何需要它們的線程使用
應用程序直接獲得鏈接的缺點
用戶每次請求都需要向數據庫獲得連接,而數據庫創建連接通常需要消耗較大的資源,創建時消耗的事件也比較長,在高并發業務場景下,如果采用這種方式獲得連接,極大浪費數據庫的資源,并且容易造成數據庫服務器內存溢出
那么連接池是怎么解決這個問題的呢
連接池中默認存放了若干個數據庫連接對象,當用戶請求與數據庫進行連接時,直接從數據庫中取出,當用戶完成操作需要釋放數據庫連接資源時,銷毀的連接回到連接池繼續等待下一次用戶的請求
C3P0的使用
package com.kernel.test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
* 演示連接池
*/
public class DataSourseDemo01 {
@Test
/**
* 手動設置連接池
*/
public void demo1() {
//獲得連接
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//創建連接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//設置連接池參數
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jdbctest");
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setMaxPoolSize(20);
connection = dataSource.getConnection();
String sql = "select * from user";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("uid") + "\t"
+ resultSet.getString("username") + "\t"
+ resultSet.getString("password") + "\t"
+ resultSet.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtil.release(resultSet, preparedStatement, connection);
}
}
@Test
/**
* 讀取配置文件設置連接池,默認讀取src目錄下的c3p0-config.xml文件
*/
public void demo2() {
//獲得連接
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//創建連接池
connection = DBUtil.getConnection();
String sql = "select * from user";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("uid") + "\t"
+ resultSet.getString("username") + "\t"
+ resultSet.getString("password") + "\t"
+ resultSet.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DButil2.release(resultSet, preparedStatement, connection);
}
}
}
編寫C3P0的配置文件
com.mysql.jdbc.Driver
jdbc:mysql:///jdbctest
root
123456
5
20
?著作權歸作者所有:來自51CTO博客作者灰白世界的原創作品,如需轉載,請注明出處,否則將追究法律責任
總結
以上是生活随笔為你收集整理的jdbc连接mysql数据库的常用对象_JDBC常用对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员专用壁纸!!!
- 下一篇: mysql 客户服务号获取_《MySQL