從JDBC基礎到C3P0的使用看這一篇就行了——基於MySQL8.0(完整版)

JDBC在mysql8.x上的使用

jdbc下載地址

  • mysql8.0和之前版本的區別,首先驅動換了,不是com.mysql.jdbc.Driver而是com.mysql.cj.jdbc.Driver

    5.5版本的註冊

    Class.forName(com.mysql.jdbc.Driver());
    

    8.x版本的註冊

    Calss.forName(com.mysql.cj.jdbc.Driver());
    
  • mysql8.x是不需要建立ssl連接的,需要顯示關閉。需要配置serverTimezone屬性設置時區

    Url="jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true";
    
    //連接地址+ssl連接關閉+時區+字符集爲utf-8+數據庫自動連接
    

    UTC代表的是全球標準時間 ,但是我們使用的時間是北京時區也就是東八區,領先UTC八個小時。時區使用中國標準時間,也是就serverTimezone=Asia/Shanghai。

用jdbc連接數據庫

package com.lxc.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.cj.jdbc.Driver;

public class JDBCDemo1 {
	
	public static void main(String[] args) {
		
		Connection conn=null;
		Statement stmt=null;
		ResultSet resultSet=null;
		try {
			
			//1、加載驅動
			//DriverManager.registerDriver(new Driver());//會進行兩次註冊驅動(加載Driver類一次,執行這條語句又一次)
			//加載Driver類,Driver類中的靜態代碼塊中含有DriverManager.registerDriver(new Driver());代碼,只要加載Driver類就會註冊驅動
			Class.forName("com.mysql.cj.jdbc.Driver");
			
			//2、獲得連接
			//三個參數1、localhost是主機名,3306是端口號,jdbctest是數據庫 2、用戶名 3、密碼
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest?useSSL=false&serverTimezone=Asia/Shanghai","root","123456");
			
			//3、創建執行SQL語句的對象,並執行SQL
			//3.1創建執行sql語句的對象
			stmt=conn.createStatement();             
			String sql="select * from user";
			//3.2、執行sql語句獲得結果集
			resultSet=stmt.executeQuery(sql);
		 	//3.3、讀取結果集中的數據
			while(resultSet.next()) {
				int id=resultSet.getInt("uid");
				String username=resultSet.getString("username");
				String password=resultSet.getString("password");
				String name=resultSet.getString("name");
				System.out.println(id+"  "+username+"  "+password+"  "+name);
			}
			 
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//4、釋放資源
			
			if(resultSet!=null) {
				try {
					resultSet.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				resultSet=null;
			}
			
			if(stmt!=null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				stmt=null;
			}
			
			if(conn!=null) {
				try {
					//這裏雖然關閉了資源,但不會馬上被垃圾回收機制回收
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				//手動置爲空,讓這個連接資源馬上被回收
				conn=null;
			}
		}
	}
}
  • 釋放資源必須放在finally中,因爲放在try塊中,如果在前面發生了異常,那麼這些資源將不會被正常回收。但是放在finally塊中,無論是否會有異常,都會執行這個塊中的代碼,進行資源的釋放。
  • 特別是Connection對象,它是非常稀有的資源(數據庫中規定了最大的連接數),用完後必須馬上釋放,如果Connection不能及時、正確的關閉,極易導致系統宕機。Connection的使用原則是儘量晚創建,儘量早的釋放。

DriverManager :驅動管理類

主要作用:

  • 註冊驅動

    • 實際開發中註冊驅動會使用如下的方式:
    Class.forName("com.mysql.cj.jdbc.Driver");
    
  • 獲得連接

    Connection conn=DriverManager.getConnection(String url,String username,String password)
    
    url寫法: jdbc:mysql://localhost:3306/jdbc?.....
    
    • jdbc :協議
    • mysql:子協議
    • localhost :主機名
    • 3306:端口號

Connection:獲得連接對象(Connection是接口)

主要作用:

  • 創建執行SQL語句的對象(調用下面的方法獲得不同的執行SQL語句的對象)
    • Statement createStatement():獲得執行SQL語句的對象,有SQL注入的漏洞存在。
    • PreparedStatement prepareStatement(String sql):這個接口繼承了Statement,預編譯SQL語句,解決SQL注入漏洞的問題。
    • CallableStatement prepareCall(String sql):執行SQL中的存儲過程。
  • 進行事務的管理
    • setAutoCommit(boolean autoCommit):設置事務是否自動提交,true爲自動,false爲禁止自動
    • commit():事務提交
    • rollback():事務回滾

Statement(接口):執行SQL語句

主要作用:

  • 執行SQL語句

    • boolean execute(String sql):執行SQL,執行select語句返回true,其它返回false。
    • ResultSet executeQuery(String sql):執行SQL中的select語句
    • int executeUpdate(String sql):執行SQL中的insert/update/delete語句,返回影響的行數
  • 執行批處理操作

    • addBatch(String sql):添加到批處理
    • executeBatch():執行批處理,返回一個數組,保存着每執行一次sql語句影響的行數
    • clearBatch():清空批處理

PreparedStatement的這些函數在傳參等方面略有不同

//用PreparedStatement的批處理執行多條delete操作
package com.lxc.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCDemo3 {
	public static void main(String[] args) {
		
		String driver="com.mysql.cj.jdbc.Driver";
		String url="jdbc:mysql://localhost:3306/jdbctest?useSSL=false&serverTimezone=Asia/Shanghai";
		String username="root";
		String password="123456";
		Connection conn=null;
		PreparedStatement pstmt=null;
		try {
			Class.forName(driver);
			conn=DriverManager.getConnection(url,username,password);
			String sql="delete from user where username=?";
			pstmt=conn.prepareStatement(sql);
			//設置爲不自動提交事務,自動提交不能實現真正的批處理
			conn.setAutoCommit(false);
			for(int i=1;i<10;i++) {
				pstmt.setString(1, "lewis"+String.valueOf(i));
				pstmt.addBatch();
			}
			int[] cnt=pstmt.executeBatch();//返回每次操作影響了幾行的數組
			conn.commit();//手動提交事務
			System.out.println("總共執行了"+cnt.length+"次刪除操作");
			for(int n:cnt) {
				System.out.println(n);
			}
			conn.setAutoCommit(true);//恢復自動提交事務
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(pstmt!=null) {
				try {
					pstmt.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				pstmt=null;
			}
			if(conn!=null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				conn=null;
			}
		}
	}
}

ResultSet:結果集

結果集:其實就是查詢語句(select)查詢結果的封裝。

主要作用:

  • 通過結果集獲取到查詢結果
  • next():針對不同類型的數據可以使用getXXX()獲取數據,通用的獲取方法:getObject()

提取工具類

properties文件:

properties文件的應用

  • 以鍵值對的形式保存信息,存儲格式鍵=值
  • 我這裏的文件是放在ClassPath根目錄下的
driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbctest?useSSL=false&serverTimezone=Asia/Shanghai
username=root
password=123

工具類:

  • 一些可能變化的信息從屬性文件中讀取,如果改變,只需改變屬性文件就行
package com.lxc.jdbc.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtils {

	private static String driverClass;
	private static String url;
	private static String username;
	private static String password;
	
    //靜態代碼塊,在類加載的時候執行
	static {
		//加載屬性文件並解析
		Properties properties=new Properties();
		//使用類加載器的方式獲取屬性文件的輸入流
		/*不能使用FileInputStream()的方式獲得文件的輸入流,這種方法只能用在java程序中,這種方式如果在web項目中程序會到tomcat/bin目錄下加載該屬性文件*/
		//jdbc.properties放在classpath根目錄下,下面是到classpath根目錄下讀取jdbc.properties文件
		//同樣也可以使用JDBCUtils.class.getResourceAsStream("/jdbc.properties")獲得該文件輸入流
        InputStream is=JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
		try {
            
            //解析.properties文件中的鍵值對,存進HashTable中,供後面的getProperty(Stirng key)使用
			properties.load(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//從屬性文件中獲取鍵值對中的值
        //本質是通過鍵獲取HashTable中的值
		driverClass=properties.getProperty("driverClass");
		url=properties.getProperty("url");
		username=properties.getProperty("username");
		password=properties.getProperty("password");
	}
	
	/**
	 * 註冊驅動的方法
	 */
	public static void loadDriver() throws ClassNotFoundException {
		Class.forName(driverClass);
	}
	
	/**
	 * 獲得連接的方法
	 * @throws ClassNotFoundException 
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws ClassNotFoundException, SQLException {
		JDBCUtils.loadDriver();
		return DriverManager.getConnection(url,username,password);
	}
	
	
	/**
	 * 釋放資源
	 */
	
	public static void release(Connection conn,PreparedStatement pstmt) {
		if(pstmt!=null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			pstmt=null;
		}
		if(conn!=null) {
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			conn=null;
		}
	}
	
	public static void release(Connection conn,PreparedStatement pstmt,ResultSet rs) {
		if(rs!=null) {
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			rs=null;
		}
		if(pstmt!=null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			pstmt=null;
		}
		if(conn!=null) {
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			conn=null;
		}
	}
}
  • 類名.class.getClassLoader.getResourceAsStream(path)中路徑問題
    • path不能以“/”開頭。
    • path是從ClassPath(項目中的src,在Eclipse項目文件中的bin目錄)根下獲取。

[關於Class.getResource和ClassLoader.getResource的路徑問題]

Class.getResource和ClassLoader.getResource的區別分析

使用工具類:

package com.lxc.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;

import com.lxc.jdbc.utils.JDBCUtils;

public class JDBCDemo3 {
	public static void main(String[] args) {
		
		Connection conn=null;
		PreparedStatement pstmt=null;
		try {
            //使用工具類中的方法獲得連接對象
			conn=JDBCUtils.getConnection();
			String sql="delete from user where username=?";
			pstmt=conn.prepareStatement(sql);
			conn.setAutoCommit(false);
			for(int i=1;i<10;i++) {
				pstmt.setString(1, "lewis"+String.valueOf(i));
				pstmt.addBatch();
			}
			int[] cnt=pstmt.executeBatch();
			conn.commit();
			System.out.println("總共執行了"+cnt.length+"次刪除操作");
			for(int n:cnt) {
				System.out.println(n);
			}
			conn.setAutoCommit(true);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
            //使用工具類中的方法釋放資源
			 JDBCUtils.release(conn,pstmt);
		}
	}
}

SQL注入漏洞的解決

產生的原因

public static boolean login(String username,String password){
		Connection conn = null;
		Statement stmt  = null;
		ResultSet rs = null;
		boolean flag = false;
		try{
			conn = JDBCUtils.getConnection();
			stmt = conn.createStatement();
			String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";
			rs = stmt.executeQuery(sql);
			if(rs.next()){
				flag = true;
			}else{
				flag = false;
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, stmt, conn);
		}
		return flag;
	}

上面是驗證登錄的代碼,如果我們在傳入參數的時候,在參數中包含一些SQL的關鍵字(and\or\註釋)。都會被拼接到SQL語句中,成爲SQL語句的一部分。比如login("aaa or '1==1'",password),無論密碼是什麼都會登錄成功,因爲傳入參數後SQL語句變成了select * from user where username='aaa' or '1==1' and password='asdfj';,只要用戶名對了就能登錄成功。

SQL注入漏洞的解決

  • PreparedStatement能很好的解決這個問題
  • PreparedStatementStatement的子接口
  • PreparedStatement相對於Statement而言
    • PreparedStatement可以避免SQL注入的問題,因爲在PreparedStatement中的SQL語句中會使用佔位符,傳入參數的時候,儘管傳入一些含有SQL關鍵字的字符串,但是SQL語句並不會識別這些關鍵字,而僅僅是當作普通的字符串來處理。(SQL語句的格式已固定)
    • Statement會使數據庫頻繁編譯SQL,可能會造成數據庫緩衝區的溢出。而PreparedStatement可對SQL語句進行預編譯(只要是同一種格式的SQL語句,只編譯一次,可使用多次),從而提高數據庫的執行效率。
    • 並且PreparedStatement對於sql中的參數,允許使用佔位符的形式進行替換,簡化SQL語句的編寫。
public static boolean login2(String username,String password){
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		boolean flag = false;
		try{
			conn = JDBCUtils.getConnection();
			String sql = "select * from user where username = ? and password = ?";
			pstmt = conn.prepareStatement(sql);
            //第一個參數代表第幾個佔位符,從1開始
			pstmt.setString(1, username);
			pstmt.setString(2, password);
			rs = pstmt.executeQuery();
			if(rs.next()){
				flag = true;
			}else{
				flag = false;
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
		return flag;
	}

JDBC連接池—C3P0

  • C3P0是開源的JDBC連接池

  • 連接池是創建和管理一個連接的緩衝池的技術,這些連接準備好被任何需要他們的線程使用。

  • 原來沒有連接池的缺點
    在這裏插入圖片描述
    沒有連接池的時候,這些連接都是需要的時候創建,用完後馬上銷燬,所以會導致數據庫一直在創建和銷燬連接。

  • 有連接池的優點
    在這裏插入圖片描述
    在數據庫連接池中存在着一定數量的連接,當需要使用的時候就取出來使用,等到用完後不會銷燬,而是歸還到連接池中,這樣就避免了大量的創建連接耗費資源等問題。

    [外鏈圖片轉存失敗(img-FGRZICiR-1565245636240)(assets/1565192749899.png)]

C3P0的使用

Jar包下載

  • 下載後需要把``c3p0-0.9.5.4.jar和依賴包mchange-commons-java-0.2.15.jar兩個包導入到工程的ClassPath`中

配置c3p0-config.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <named-config name="mysql">
        <!-- 配置數據庫用戶名 -->
        <property name="user">root</property>
        <!-- 配置數據庫密碼 -->
        <property name="password"></property>
        <!-- 配置數據庫鏈接地址 -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/cdcol?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai</property>
        <!-- 配置數據庫驅動 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <!-- 數據庫連接池一次性向數據庫要多少個連接對象 -->
        <property name="acquireIncrement">20</property>
        <!-- 初始化連接數 -->
        <property name="initialPoolSize">10</property>
        <!-- 最小連接數 -->
        <property name="minPoolSize">5</property>
        <!--連接池中保留的最大連接數。Default: 15 -->
        <property name="maxPoolSize">30</property>
        <!--JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但由於預緩存的statements 屬於單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。如果maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default:0 -->
        <property name="maxStatements">0</property>
        <!--maxStatementsPerConnection定義了連接池內單個連接所擁有的最大緩存statements數。Default: 0 -->
        <property name="maxStatementsPerConnection">0</property>
        <!--c3p0是異步操作的,緩慢的JDBC操作通過幫助進程完成。擴展這些操作可以有效的提升性能 通過多線程實現多個操作同時被執行。Default:3 -->
        <property name="numHelperThreads">3</property>
        <!--用戶修改系統配置參數執行前最多等待300秒。Default: 300 -->
        <property name="propertyCycle">3</property>
        <!-- 獲取連接超時設置 默認是一直等待單位毫秒 -->
        <property name="checkoutTimeout">1000</property>
        <!--每多少秒檢查所有連接池中的空閒連接。Default: 0 -->
        <property name="idleConnectionTestPeriod">3</property>
        <!--最大空閒時間,多少秒內未使用則連接被丟棄。若爲0則永不丟棄。Default: 0 -->
        <property name="maxIdleTime">10</property>
        <!--配置連接的生存時間,超過這個時間的連接將由連接池自動斷開丟棄掉。當然正在使用的連接不會馬上斷開,而是等待它close再斷開。配置爲0的時候則不會對連接的生存時間進行限制。 -->
        <property name="maxIdleTimeExcessConnections">5</property>
        <!--兩次連接中間隔時間,單位毫秒。Default: 1000 -->
        <property name="acquireRetryDelay">1000</property>
        <!--c3p0將建一張名爲Test的空表,並使用其自帶的查詢語句進行測試。如果定義了這個參數那麼屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操作,它將只供c3p0測試使用。Default: null -->
        <property name="automaticTestTable">Test</property>
        <!-- 獲取connnection時測試是否有效 -->
        <property name="testConnectionOnCheckin">true</property>
    </named-config>
</c3p0-config>
  • 在xml文件中可以配置多個數據庫源連接信息,比如可以是mysql、oracle

    可以使用c3p0-config.xml文件配置連接信息,使用xml作爲配置信息的話,comboPoolDataSource還可以接受一個String參數,這個參數的名稱是在c3p0-config.xml文件中配置的,也可以使用無參的默認配置。這樣就能連接不同的數據庫、連接不同廠商的數據庫

    public ComboPooledDataSource()
    //無參構造使用默認配置(使用xml中default‐config標籤中對應的參數)
    
    public ComboPooledDataSource(String configName)
    //有參構造使用命名配置(configName:xml中配置的名稱,使用xml中named‐config標籤中對應的參數)
    //例如在xml中:<named-config name="oracle">各種配置信息</named-config>
    

    我的c3p0-config.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
    
      <!--默認配置,無參時使用這個-->
      <default-config>
      	<!--連接參數 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <!--使用&amp;對&進行轉義-->
    	<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest?useSSL=false&amp;serverTimezone=Asia/Shanghai</property>
    	<property name="user">root</property>
    	<property name="password">123456</property>
    	<!-- 連接池參數 -->
    	<property name="initialPoolSize">5</property>
    	<property name="maxPoolSize">20</property>
      </default-config>
      
      <!--命名配置,配置mysql數據庫,傳入"mysql"參數使用這個  -->
      <named-config name="mysql">
            <!-- 配置數據庫用戶名 -->
            <property name="user">root</property>
            <!-- 配置數據庫密碼 -->
            <property name="password">123456</property>
            <!-- 配置數據庫鏈接地址 -->
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai</property>
            <!-- 配置數據庫驅動 -->
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <!-- 數據庫連接池一次性向數據庫要多少個連接對象 -->
            <property name="acquireIncrement">20</property>
            <!-- 初始化連接數 -->
            <property name="initialPoolSize">10</property>
            <!-- 最小連接數 -->
            <property name="minPoolSize">5</property>
            <!--連接池中保留的最大連接數。Default: 15 -->
            <property name="maxPoolSize">30</property>
       </named-config>
       
       <!-- 配置ORACLE數據庫   -->
       <named-config name="oracle">各種配置信息</named-config>
    </c3p0-config>
    
  • 配置文件的連接方式

    • C3P0默認會在classpath(src)根目錄讀取配置文件c3p0-config.xml,不需要任何的設置。所以我們最好把配置文件放在classpath根目錄下,而且文件名爲c3p0-config.xml(不要更改)。

    • 也可以把c3p0-config.xml放到自己想放的位置,但必須在加載程序的時候進行設置

      System.setProperties(“ com.mchange.v2.c3p0.cfg.xml”,”config/c3p0-config.xml”); 
      

工具類:

package com.lxc.jdbc.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
	private static ComboPooledDataSource dataSource;
	
	static {
		dataSource=new ComboPooledDataSource();
        //也可以使用命名配置的數據庫
        //dataSource=new ComboPooledDataSource("mysql");
	}
	
	/**
	 * 獲得連接
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException {
		return dataSource.getConnection();
	}
	
	/**
	 * 釋放ResultSet和PreparedStatement資源,並把Connection歸還到連接池中
	 * @param stmt
	 * @param conn
	 */
	public static void release(Statement stmt,Connection conn){
		if(stmt != null){
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			stmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
	
	public static void release(ResultSet rs,Statement stmt,Connection conn){
		if(rs!= null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if(stmt != null){
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			stmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
}

操作

package com.lxc.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.lxc.jdbc.utils.C3P0Utils;


public class C3P0Test {
	public static void main(String[] args) {
		
		Connection conn=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		try {
			//利用工具類獲得連接
			conn=C3P0Utils.getConnection();
			String sql="select * from user";
			pstmt=conn.prepareStatement(sql);
			rs=pstmt.executeQuery();
			while(rs.next()) {
				System.out.println(rs.getInt("uid")+"  "+rs.getString("username")+"  "+rs.getString("password")+"  "+rs.getString("name"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			//以前調用conn.close()是釋放資源,但是C3P0中對方法進行了升級,把銷燬連接改成了把連接歸還到連接池中
			C3P0Utils.release(rs, pstmt,conn);
		}	
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章