日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

jdbc连接mysql数据库的常用对象_JDBC常用对象

發布時間:2023/12/10 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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常用对象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。