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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java学习笔记之JDBC和连接池

發(fā)布時間:2023/12/10 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java学习笔记之JDBC和连接池 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、JDBC概述
  • 二、JDBC使用
    • 1.JDBC驅動的注冊
    • 2.JDBC與數(shù)據(jù)庫建立連接
    • 3.Statement發(fā)送sql語句對象
    • 4.Result結果集對象
    • 5.Statement的不足以及PreparedStatement
      • 5.1 SQL注入分析
      • 5.2 PreparedStatement
    • 6.PreparedStatement和Statement的對比
    • 7.JDBC事務的處理
    • 8.JDBC連接工具類
  • 三、連接池
    • 1.C3P0連接池
    • 2.DRUID連接池
    • 3.連接池工具類

一、JDBC概述

jdbc是什么?

英文全稱:Java Database ConnectivIty

中文名稱:Java數(shù)據(jù)庫連接技術

作用:

使用Java代碼與數(shù)據(jù)庫建立連接,并對數(shù)據(jù)庫執(zhí)行操作

JDBC的組成:

由官方定義的接口(規(guī)范)組成:接口的實現(xiàn)類由數(shù)據(jù)庫廠商提供:(數(shù)據(jù)庫驅動)

數(shù)據(jù)庫驅動:包含實現(xiàn)操作數(shù)據(jù)庫接口的類

JDBC的好處:

代碼不依賴與任何數(shù)據(jù)庫

只需要修改少量配置就可以方便切換到其他廠商的數(shù)據(jù)庫

JDBC核心類和接口:

核心類和接口說明
DriverManager 工具類1.注冊數(shù)據(jù)庫驅動
2.獲得連接對象
Connection 接口連接對象
作用:與數(shù)據(jù)庫建立連接并形成數(shù)據(jù)通道
Statement 接口SQL語句發(fā)送對象
作用:將SQL語句發(fā)送給數(shù)據(jù)庫執(zhí)行并獲得執(zhí)行結果
ResultSet 接口結果集對象
作用:用來封裝滿足查詢條件的記錄信息
Driver 接口數(shù)據(jù)庫驅動對象

二、JDBC使用

步驟:

1.注冊驅動

2.建立連接

3.獲得sql語句發(fā)送對象

4.執(zhí)行sql語句

5.獲得執(zhí)行結果

6.關閉連接,釋放資源

1.JDBC驅動的注冊

注冊數(shù)據(jù)庫驅動的兩種方式:

public static void main(String[] args) throws Exception{//方式1:存在問題:驅動會被注冊兩次//創(chuàng)建驅動對象(Driver是mysql廠商提供Driver接口的實現(xiàn)類)Driver driver = new Driver();//注冊驅動DriverManager.registerDriver(driver);//方式二:利用反射觸發(fā)Driver實現(xiàn)類的加載實現(xiàn)驅動注冊Class.forName("com.mysql.jdbc.Driver"); } 注冊驅動方法說明
static registerDriver(Driver driver)驅動會注冊兩次
Class.forName(“com.mysql.jdbc.Driver”)只會注冊一次

2.JDBC與數(shù)據(jù)庫建立連接

與數(shù)據(jù)庫建立連接:

數(shù)據(jù)庫連接字符串格式:完整格式:JDBC協(xié)議:子協(xié)議://數(shù)據(jù)庫服務器地址:端口號/數(shù)據(jù)庫名? JDBC協(xié)議:固定值:jdbc? 子協(xié)議:一般是數(shù)據(jù)庫廠商的名字,比如mysql、oracle省略格式:JDBC協(xié)議:子協(xié)議:/// 數(shù)據(jù)庫名? 前提:操作的是本機的數(shù)據(jù)庫,且端口號是3306 DriverManager類與數(shù)據(jù)庫建立連接的方法說明
static Connection getConnetion(
String url,
String username,
String password)
獲得連接對象
url:連接字符串
username:用戶名
password:密碼
static Connection getConnection(
String url, Properties info)
獲得連接對象
public class getConnect {public static void main(String[] args) {//傳入配置信息,獲得連接對象Class.forName("com.mysql.jdbc.Driver");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root", "123456");//讀取配置文件獲得連接對象Properties properties = new Properties();properties.load(Class.class.getResourceAsStream("/database.properties"));Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", properties);} }

配置文件內容:

user=root password=123456

3.Statement發(fā)送sql語句對象

作用:

將SQL語句發(fā)送給數(shù)據(jù)庫執(zhí)行并獲取結果

創(chuàng)建方式:

通過連接對象的方法獲得( Statement createStatement() )

Statement對象常用方法說明
boolean execute(String sql)可以執(zhí)行任意SQL語句
一般用來執(zhí)行DDL語句:創(chuàng)庫或創(chuàng)表
int executeUpdate(String sql)用于執(zhí)行增刪改語句:返回影響的行數(shù)
只要不是查詢都稱為更新操作
ResultSet executeQuery(String sql)用于執(zhí)行查詢語句

4.Result結果集對象

作用:

封裝滿足查詢條件的記錄信息

獲得ResultSet對象:

通過Statement對象的方法獲取( ResultSet executeQuery(String sql) )

ResultSet對象常用方法說明
boolean next()將指針下移一行并判斷當前位置是否有記錄
有則返回true,否則返回false
Xxx getXxx(列號或列名)根據(jù)列號或列名獲得當前行指定列的數(shù)據(jù)

5.Statement的不足以及PreparedStatement

5.1 SQL注入分析

Statement的不足:

容易被sql注入,因為statement的執(zhí)行方式是先把sql語句寫好了之后再執(zhí)行

由于傳入的字符串有可能導致sql語句的內容發(fā)生變化,所以容易被sql注入

代碼樣例:

package JDBCConnection;import java.sql.*; import java.util.Scanner;public class login {public static void main(String[] args) throws Exception {//jdbc連接工具類直接獲得連接對象Connection connect = getConnect.getConnect();//創(chuàng)建statement對象Statement stmt = connect.createStatement();//創(chuàng)建scanner獲得數(shù)據(jù)Scanner sc = new Scanner(System.in);System.out.println("請輸入用戶名:");String username = sc.nextLine();System.out.println("請輸入密碼:");String password = sc.nextLine();//編寫sql語句String sql = "select * from personal where username='" + username + "' and password='" + password + "'";//執(zhí)行sql語句并獲得結果集ResultSet rs = stmt.executeQuery(sql);//判斷是否登錄成功if (rs.next()) {System.out.println("登錄成功");} else {System.out.println("登陸失敗");}}}

不足分析:

上面的代碼起來沒有什么問題,但是由于你不能控制用戶輸入的信息

那么他在登錄的時候就可能輸入這樣的信息a’ or ‘1’='1

這樣操作之后,sql語句就變成了下面這樣的:

select * from personal where username=‘xxx’ and password=‘a’ or ‘1’=‘1’;

這樣無論他輸入的是什么,存不存在,都會判定為登錄成功

優(yōu)化方案:

使用PreparedStatement來執(zhí)行sql語句;

5.2 PreparedStatement

概述:

PreparedStatemet預編譯處理,是Statement的子類,和Statement一樣,都是用來發(fā)送sql語句的

創(chuàng)建方式:

//在編寫格式上,預編譯對象不需要把參數(shù)寫入進去,而是使用通配符?來代替 PreparedStatement pstmt = conn.prepareStatement(sql); //下一步,就是調用預編譯對象的設置方法來把參數(shù)設置好,然后調用和父類一樣的執(zhí)行方法執(zhí)行即可 //由于不需要直接把參數(shù)寫進sql語句,而且預編譯預編譯,會在輸入sql獲得對象之后先對sql語句做預編譯 //然后再輸入?yún)?shù),所以可以避免sql注入 PreparedStatement接口常用方法說明
int executeUpdate();執(zhí)行DML語句
返回影響的行數(shù)
ResultSet executeQuery();執(zhí)行DQL語句
返回滿足查詢條件的結果集對象

6.PreparedStatement和Statement的對比

相同點:

都可以對數(shù)據(jù)庫執(zhí)行增刪改查操作

不同點:

1.PrepartedStatement有預編譯功能,Statement沒有預編譯功能

2.PrepartedStatement有緩存的功能,緩存的是sql語句編譯的結果,Statement沒有緩存功能

3.PrepartedStatement沒有sql注入,Statement有sql注入,前者更安全,后者不安全

7.JDBC事務的處理

事務實現(xiàn)
開啟事務連接對象.setAutoCommit(boolean b)
作用:設置是否自動提交事務
默認值是true即自動提交事務
需要開啟事物的話需要在獲得連接之后先關閉在發(fā)送sql
回滾連接對象.rollback();
作用:用來執(zhí)行sql語句中的回滾
提交事務連接對象.commit()
作用:提交事務

8.JDBC連接工具類

package JDBCConnection;import java.sql.*; import java.util.Properties;public class jdbcUtils {//靜態(tài)代碼塊,用來注冊驅動,因為驅動只需要注冊一次static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConnection() {try {//通過寫好的配置信息來連接數(shù)據(jù)庫return DriverManager.getConnection("jdbc:mysql://localhost:3306/personal","root", "123456");} catch (Exception e) {throw new RuntimeException(e);}}public static Connection getConnection(String path) {try {//讀取配置文件來連接數(shù)據(jù)庫Properties properties = new Properties();properties.load(Class.class.getResourceAsStream(path));return DriverManager.getConnection("jdbc:mysql://localhost:3306/personal",properties);} catch (Exception e) {throw new RuntimeException(e);}}//關閉所有數(shù)據(jù)庫相關的資源//因為prepartedstatement是statement的子類,所以也可以直接關閉public static void Close(Connection conn, Statement stmt, ResultSet rs) {//判斷傳入的組件是否為空,不為空則關閉if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}//調用上面的方法public static void Close(Connection conn, Statement stmt) {Close(conn, stmt, null);} }

三、連接池

概述:

連接池就是一個負責創(chuàng)建和管理連接對象的容器(集合)

使用連接池的原因:

和線程池的理由一樣,都是為了提高效率。因為頻繁的創(chuàng)建和銷毀連接是很消耗資源的。
使用連接池可以減少頻繁和銷毀連接帶來的系統(tǒng)資源損耗,從而提高訪問數(shù)據(jù)庫的效率

連接池的核心思想:

連接復用

連接池規(guī)范:

DataSource

常用連接池:

C3P0連接池
DRUID連接池

1.C3P0連接池

配置文件:

<!--這里要注意,這個文件會自動讀取,所以需要命名為c3p0-config.xml并且放到src目錄下--> <c3p0-config><!-- 使用默認的配置讀取連接池對象 --><default-config><!-- 連接參數(shù) --><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property><property name="user">root</property><property name="password">root</property><!-- 連接池參數(shù) --><property name="initialPoolSize">5</property><property name="maxPoolSize">10</property><property name="checkoutTimeout">2000</property><property name="maxIdleTime">1000</property></default-config><named-config name="pkxingc3p0"> <!-- 連接參數(shù) --><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property><property name="user">root</property><property name="password">root</property><!-- 連接池參數(shù) --><property name="initialPoolSize">5</property><property name="maxPoolSize">15</property><property name="checkoutTimeout">2000</property><property name="maxIdleTime">1000</property></named-config> </c3p0-config>

連接池常用方法:

ComboPooledDataSource構造方法說明
ComboPooledDataSource()使用默認的配置default-config創(chuàng)建數(shù)據(jù)源對象
ComboPooledDataSource(命名配置)使用命名的配置named-config創(chuàng)建數(shù)據(jù)源對象

配置信息詳解:

name說明
driverClass注冊jdbc的字符串
jdbcUrlmysql服務器地址
user用戶名
password密碼
initialPoolSize初始化連接數(shù)
maxPoolSize最大連接數(shù)
checkoutTimeout最大等待時間
maxIdTime最大空閑時間

代碼樣例:

public void C3P0() throws Exception {//使用默認配置方式DataSource ds = new ComboPooledDataSource();//選擇命名配置 // DataSource ds = new ComboPooledDataSource("ps");for (int i = 0; i < 15; i++) {//獲得連接,但不關閉//如果關閉之后,他不會銷毀而是會回到連接池中Connection connection = ds.getConnection();System.out.println("第" + (i + 1) + "次===>" + connection);}}

2.DRUID連接池

配置文件內容:

driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/day25 username=root password=root initialSize=5 maxActive=10 maxWait=3000 maxIdle=6 minIdle=3

參數(shù)內容說明:

參數(shù)說明
jdbcUrl連接數(shù)據(jù)庫的url:mysql : jdbc:mysql://localhost:3306/druid2
username數(shù)據(jù)庫的用戶名
password數(shù)據(jù)庫的密碼
driverClassName驅動類名。根據(jù)url自動識別,這一項可配可不配,如果不配置druid會根據(jù)url自動 識別dbType,然后選擇相應的driverClassName(建議配置下)
initialSize初始化時建立物理連接的個數(shù)。初始化發(fā)生在顯示調用init方法,或者第一次getConnection時
maxActive最大連接數(shù)量
maxIdle已經不再使用,配置了也沒效果
minIdle最小連接數(shù)量
maxWait獲取連接時最大等待時間,單位毫秒。

常用方法:

DruidDataSourceFactory類靜態(tài)方法說明
public static DataSource createDataSource(Properties properties)創(chuàng)建連接池對象

代碼樣例:

public void DRUID() throws Exception{//讀取配置文件Properties properties = new Properties();properties.load(Class.class.getResourceAsStream("/druid.properties"));//加載配置文件獲得連接池DataSource ds = DruidDataSourceFactory.createDataSource(properties);//從連接池獲得連接Connection connection = ds.getConnection();System.out.println(connection);}

3.連接池工具類

DRUID版:

package JDBCConnection;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;public class DataPoolUtils {//連接池對象private static DataSource ds = null;//靜態(tài)方法,加載連接池static {try {//讀取配置文件Properties properties = new Properties();properties.load(Class.class.getResourceAsStream("/druid.properties"));//獲得連接池ds = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() {try {//直接獲得連接return ds.getConnection();} catch (SQLException throwables) {throw new RuntimeException(throwables);}}public static DataSource getDataSource() {return ds;}public static void Close(Connection conn, Statement stmt, ResultSet rs) {if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}public static void Close(Connection conn, Statement stmt) {Close(conn, stmt, null);} }

C3P0版:

package JDBCConnection;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties;public class DataPoolUtils {private static DataSource ds = null;static {try {//其他和上面一樣//只不過創(chuàng)建連接池的時候,C3P0會自動讀取配置文件ds = new ComboPooledDataSource();} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() {try {return ds.getConnection();} catch (SQLException throwables) {throw new RuntimeException(throwables);}}public static DataSource getDataSource() {return ds;}public static void Close(Connection conn, Statement stmt, ResultSet rs) {if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}public static void Close(Connection conn, Statement stmt) {Close(conn, stmt, null);} }

總結

以上是生活随笔為你收集整理的Java学习笔记之JDBC和连接池的全部內容,希望文章能夠幫你解決所遇到的問題。

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