最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中JDBC連接數(shù)據(jù)庫詳解

 更新時間:2017年03月16日 11:35:08   作者:Dmego  
本文主要介紹了JDBC連接數(shù)據(jù)庫的相關(guān)知識,具有很好的參考價值。下面跟著小編一起來看下吧

一、概念

  1. 為了能讓程序操作數(shù)據(jù)庫,對數(shù)據(jù)庫中的表進行操作,每一種數(shù)據(jù)庫都會提供一套連接和操作該數(shù)據(jù)庫的驅(qū)動,而且每種數(shù)據(jù)庫的驅(qū)動都各不相同,例如mysql數(shù)據(jù)庫使用mysql驅(qū)動,oracle數(shù)據(jù)庫使用oracle驅(qū)動,這樣假如我們編寫的程序哪一天想要換數(shù)據(jù)庫,那樣就會很不方便,因為所有連接數(shù)據(jù)庫的代碼都要從新編寫。SUN公司為了簡化。統(tǒng)一對數(shù)據(jù)庫的操作,定義了一套java操作數(shù)據(jù)庫的標準或者規(guī)范,這個規(guī)范就是JDBC。

  2.JDBC全稱為:Java Data Base Connectivity(java數(shù)據(jù)庫連接),它主要由接口組成。我們在開發(fā)過程中,只要實現(xiàn)它相應(yīng)的接口就可以非常進行連接?!   ?/p>

  3.我們在開發(fā)JDBC應(yīng)用時,還需要導入相應(yīng)的數(shù)據(jù)庫的驅(qū)動jar包,這些驅(qū)動jar包是由數(shù)據(jù)庫公司自己編寫的。

二、編寫JDBC應(yīng)用程序(需要連接數(shù)據(jù)庫的程序)的前提準備

1.首先要確定連接的是哪個數(shù)據(jù)庫實例,例如在mysql中,我們可以先創(chuàng)建一個庫,然后在庫中新建一張表,在表中插入一些數(shù)據(jù),我在這里提供一段在mysql數(shù)據(jù)庫中創(chuàng)建一個庫,以及表和數(shù)據(jù)的sql語句,這也是下面連接數(shù)據(jù)庫后操作的庫和表。

create database test ; /*創(chuàng)建一個名為Test的數(shù)據(jù)庫*/
use test;        /*使用該數(shù)據(jù)庫或者說切換到該數(shù)據(jù)庫*/
create table book (
  id int primary key auto_increment, /*列:id ,類型:int,從0開始,自動增加, 備注:主鍵*/
  name varchar(40) NOT NULL,    /*列:name ,類型:varchar, 備注:非空*/
  author varchar(40)NOT NULL, /*列:author ,類型:varchar, 備注:非空*/
  prices double NOT NULL  /*列:prices ,類型:double, 備注:非空*/
); /*新建一張名為book的表*/
/*插入四大名著的數(shù)據(jù)*/
insert into book(id,name,author,prices) values (null,'西游記','吳承恩',25.00);
insert into book(id,name,author,prices) values (null,'水滸傳','施耐庵',30.00);
insert into book(id,name,author,prices) values (null,'紅樓夢','曹雪芹',35.00);
insert into book(id,name,author,prices) values (null,'三國演義','羅貫中',40.00);

2.新建一個java項目,然后把mysql的驅(qū)動jar包導入進來,即添加到程序運行的庫中,具體的驅(qū)動jar包,我們可以在數(shù)據(jù)庫的安裝目錄下找到,或者都網(wǎng)上自己下載相對應(yīng)的數(shù)據(jù)庫驅(qū)動jar包

三、連接數(shù)據(jù)庫操作的步驟解析

(1)注冊數(shù)據(jù)庫驅(qū)動

雖然我們剛才在新建java項目的時候?qū)ysql數(shù)據(jù)庫的驅(qū)動jar包導入進來了,但是JBDC不知道這里有一個驅(qū)動包,此時我們就需要將這個驅(qū)動包交給JBDC去管理,我們可以使用java.sql包下的DriverManager 工具類 提供的registerDriver(Driver driver) 方法來在JDBC中注冊這個數(shù)據(jù)驅(qū)動,這個registerDriver(Driver driver)方法需要一個Driver對象,而這個Driver類本身是JDBC提供的一個接口,我們的驅(qū)動里面已經(jīng)實現(xiàn)了這個接口,所以我們只需要寫如下代碼就可以實現(xiàn)注冊數(shù)據(jù)庫驅(qū)動的功能

import java.sql.DriverManager; //需要導入的是接口類包
DriverManager.registerDriver(new Driver());

(2)獲取(創(chuàng)建)數(shù)據(jù)庫的連接

我們注冊好數(shù)據(jù)庫驅(qū)動后,并沒有連接上數(shù)據(jù)庫,以往,我們不管在CMD窗口下,通過可視化數(shù)據(jù)庫管理工具操作數(shù)據(jù)庫時,我們都需要先連接數(shù)據(jù)庫服務(wù)器,java程序連接數(shù)據(jù)庫也不例外,這里的java程序就相當于客戶端,只有先連接上數(shù)據(jù)庫服務(wù),才能對數(shù)據(jù)庫進行操作

客戶端與數(shù)據(jù)庫所有交互都是通過connection對象完成的,這個對象的常用方法:

createStatement():創(chuàng)建向數(shù)據(jù)庫發(fā)送sql的statement對象。

prepareStatement(sql) :創(chuàng)建向數(shù)據(jù)庫發(fā)送預編譯sql的

這里我們可以通過DriverManager 工具類里的getConnection(url,user,password)方法來創(chuàng)建數(shù)據(jù)庫連接對象,此方法需要傳入三個參數(shù):

User: 數(shù)據(jù)庫的用戶名

Password:用戶密碼

URL:數(shù)據(jù)庫服務(wù)器地址,不同的數(shù)據(jù)庫的URL寫法不同,我在這里提供三種主流數(shù)據(jù)庫的URL地址寫法:

Oracle寫法:jdbc:oracle:thin:@localhost:1521:sid

SqlServe寫法:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sid

MySql寫法:jdbc:mysql://localhost:3306/sid

Mysql的url地址的簡寫形式: jdbc:mysql:///sid

注:后面的sid就是數(shù)據(jù)庫的實例名稱(使用的數(shù)據(jù)庫名)

import java.sql.Connection; //導入的是接口類包
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root"); //這里使用的是一個名為test的mysql數(shù)據(jù)庫,用戶名和密碼都是root 

(3)創(chuàng)建傳輸器對象

上面我們已經(jīng)創(chuàng)建了數(shù)據(jù)庫的連接,已經(jīng)連上數(shù)據(jù)庫了,但是如果我們想要操作該數(shù)據(jù)庫,我們需要用到sql語句,而我們怎樣使用在java程序中使用sql語句來操作數(shù)據(jù)庫呢,這里我們就需要一個傳輸器對象來傳輸sql語句到數(shù)據(jù)庫中去執(zhí)行。上文提到在Connection 類中就有一個createStatement()的方法可以創(chuàng)建一個傳輸器對象

import java.sql.Statement; //導入的是接口類包
Statement stat = conn.createStatement();

(4)利用傳輸器對象傳輸sql語句到數(shù)據(jù)庫中執(zhí)行操作,將結(jié)果用結(jié)果集返回

java.sql.Statement身上有許多傳輸sql語句的方法:其中用的最多的是

executeQuery(String sql) :用于向數(shù)據(jù)發(fā)送查詢語句。

executeUpdate(String sql):用于向數(shù)據(jù)庫發(fā)送insert、update或delete語句

execute(String sql):用于向數(shù)據(jù)庫發(fā)送任意sql語句

import java.sql.ResultSet; //需要導入的接口類包
ResultSet rs = stat.executeQuery("select * from book"); //傳輸一條查詢語句,查詢book表中所有的元組數(shù)據(jù)

(5) 遍歷結(jié)果集,并獲取查詢對象

Jdbc程序中的ResultSet用于代表Sql語句的執(zhí)行結(jié)果。Resultset封裝執(zhí)行結(jié)果時,采用的類似于表格的方式。ResultSet 對象維護了一個指向表格數(shù)據(jù)行的游標,初始的時候,游標在第一行之前,調(diào)用ResultSet.next() 方法,可以使游標指向具體的數(shù)據(jù)行,進行調(diào)用方法獲取該行的數(shù)據(jù)。

ResultSet既然用于封裝執(zhí)行結(jié)果的,所以該對象提供的都是用于獲取數(shù)據(jù)的get方法:

獲取指定類型的數(shù)據(jù),例如:

getString(int index)

getString(String columnName)

ResultSet還提供了對結(jié)果集進行滾動的方法:

next():移動到下一行

Previous():移動到前一行

absolute(int row):移動到指定行

beforeFirst():移動resultSet的最前面。

afterLast() :移動到resultSet的最后面。

while(rs.next())
 {
 String name = rs.getString("name");
 System.out.println(name);
}

(6)關(guān)閉連接(先創(chuàng)建的后關(guān)閉)

Jdbc程序運行完后,切記要釋放程序在運行過程中,創(chuàng)建的那些與數(shù)據(jù)庫進行交互的對象,這些對象通常是ResultSet, Statement和Connection對象。

特別是Connection對象,它是非常稀有的資源,用完后必須馬上釋放,如果Connection不能及時、正確的關(guān)閉,極易導致系統(tǒng)宕機。Connection的使用原則是盡量晚創(chuàng)建,盡量早的釋放。

rs.close(); 
stat.close();
conn.close(); 

初期完整的源代碼

package jdbcDemo;
/****************************
 * 初版連接數(shù)據(jù)庫程序
 **************************/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//不能導入 java.sql 中的 Driver 接口,要導入驅(qū)動jar包中實現(xiàn)該接口的類,只有這要才能注冊相對應(yīng)的數(shù)據(jù)庫驅(qū)動
import com.mysql.jdbc.Driver; 
public class JDBCTest {
 public static void main(String[] args) throws SQLException {
 //1.注冊數(shù)據(jù)庫驅(qū)動
 DriverManager.registerDriver(new Driver());
 //2.獲取數(shù)據(jù)庫的連接 
 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root");
 //3.創(chuàng)建傳輸器對象
 Statement stat = conn.createStatement();
 //4.利用傳輸器對象傳輸sql語句到數(shù)據(jù)庫中執(zhí)行操作,將結(jié)果用結(jié)果集返回
  ResultSet rs = stat.executeQuery("select * from book");
 //5.遍歷結(jié)果集,并獲取查詢結(jié)果
 while(rs.next()) {
  String name = rs.getString("name");
  System.out.println(name);
 }
 //6.關(guān)閉連接(后開先關(guān))
 rs.close(); 
 stat.close();
 conn.close();
 } 
}

數(shù)據(jù)表視圖和運行結(jié)果:

四、初期連接數(shù)據(jù)庫程序中出現(xiàn)的問題

1--注冊數(shù)據(jù)庫驅(qū)動方法不當導致出現(xiàn)了兩次注冊,程序通用性低

我們在查看Driver類的源碼中可以看到如下代碼,從第7行代碼中我們可以看到,mysql在Driver類的實現(xiàn)中自己注冊了一次,而我們在程序中又注冊了一次,導致注冊兩次

我們在注冊驅(qū)動時,需要導入mysql驅(qū)動jar包中已經(jīng)實現(xiàn)的Driver類,這樣程序就和具體的數(shù)據(jù)庫綁定在一起了,程序的通用性就降低了,如果我們想要切換數(shù)據(jù)庫,還得改動源碼

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
 //
 // Register ourselves with the DriverManager
 //
 static {
 try {
  java.sql.DriverManager.registerDriver(new Driver());
 } catch (SQLException E) {
  throw new RuntimeException("Can't register driver!");
 }
 }

修復方法:

使用Class.forname() 方法將mysql中已經(jīng)實現(xiàn)的Driver類加載到程序中來,由于Driver類在實現(xiàn)接口時使用的是靜態(tài)代碼塊,而靜態(tài)代碼塊只會在類加載的時候執(zhí)行一次,即保證了數(shù)據(jù)庫驅(qū)動只會被注冊一次,同時不用導入mysql驅(qū)驅(qū)動里的類包,程序通用性提高

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

2--忽略了程序中可能會拋出的異常(最大的問題)

我們在執(zhí)行程序時,它的許多方法的調(diào)用都會拋出異常,如果它拋出異常后,沒有做相應(yīng)的處理(catch 這個異常)那么程序就會中斷執(zhí)行,Statement對象和Connection對象就沒有被關(guān)閉,而我們知道Connection對象,它是非常稀有的資源,用完后必須馬上釋放,如果Connection不能及時、正確的關(guān)閉,極易導致系統(tǒng)宕機,所以我們需要保證無論程序中哪一步出現(xiàn)了異常導致程序中斷,連接關(guān)閉的代碼都會被執(zhí)行,此時我們就會想到異常處理中的finally代碼塊,我們可以把異常向上拋出,而是先 try 住然后 catch 異常,最后執(zhí)行 finally 代碼塊

修改之后,我們發(fā)現(xiàn)每個close() 都提示有異常要處理,此時我們也直接 try/catch 每個異常

修改后的源代碼:

package jdbcDemo;
/****************************
 * 修改版連接數(shù)據(jù)庫程序
 **************************/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCTest {
 public static void main(String[] args) {
 Connection conn = null;
 Statement stat = null;
 ResultSet rs = null;
 try {
  //1.注冊數(shù)據(jù)庫驅(qū)動
  Class.forName("com.mysql.jdbc.Driver");
  //2.獲取數(shù)據(jù)庫的連接 
   conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root");
  //3.創(chuàng)建傳輸器對象
   stat = conn.createStatement();
  //4.利用傳輸器對象傳輸sql語句到數(shù)據(jù)庫中執(zhí)行操作,將結(jié)果用結(jié)果集返回
   rs = stat.executeQuery("select * from book");
  //5.遍歷結(jié)果集,并獲取查詢結(jié)果
  while(rs.next()) {
   String name = rs.getString("name");
   System.out.println(name);
  }
 }catch(Exception e) {
  e.printStackTrace();
 }finally {
  //6.關(guān)閉連接(后開先關(guān))
  try {
  rs.close();
  } catch (SQLException e) {
  e.printStackTrace();
  } 
  try {
  stat.close();
  } catch (SQLException e) {
  e.printStackTrace();
  }
  try {
  conn.close();
  } catch (SQLException e) {
  e.printStackTrace();
  }
 }
 } 
}

五、修改后程序中被忽略的異常

異常問題

1.由于我們在程序開頭先聲明了三個對象的引用,并且都賦值為null,假如程序在執(zhí)行到注冊數(shù)據(jù)庫這一步時就拋出了異常,此時catch 到這個異常 后執(zhí)行finally 代碼塊,結(jié)果發(fā)現(xiàn)ResultSet 對象的引用,Connection對象的引用以及Statement對象的引用都是空值,調(diào)用這個對象上的方法就會拋出空指針異常

2.close()這個方法身上也有異常,如果我們不做相應(yīng)的異常處理,那些對象還是不能被正常關(guān)閉

解決辦法

1---為了防止出現(xiàn)空指針異常,我們可以先判斷哪些對象的引用是否為null,如果不為null,則執(zhí)行異常處理代碼

2---在每個close()異常處理后在加上一個finally靜態(tài)代碼塊,將每個相應(yīng)對象的引用值置為null,原理是:如果程序執(zhí)行到close() 方法并拋出了異常,那么最后finally代碼塊執(zhí)行,給該對象的應(yīng)用值置為null,由于這個對象沒有任何引用指向它,它就成為了垃圾對象,JVM垃圾回收器就會回收這個對象資源,這個對象也就關(guān)閉了

異常處理完后最終的源代碼:

package jdbcDemo;
/****************************
 * 無異常版連接數(shù)據(jù)庫程序
 **************************/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCTest {
 public static void main(String[] args) {
 Connection conn = null;
 Statement stat = null;
 ResultSet rs = null;
 try {
  //1.注冊數(shù)據(jù)庫驅(qū)動
  Class.forName("com.mysql.jdbc.Driver");
  //2.獲取數(shù)據(jù)庫的連接 
   conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root");
  //3.創(chuàng)建傳輸器對象
   stat = conn.createStatement();
  //4.利用傳輸器對象傳輸sql語句到數(shù)據(jù)庫中執(zhí)行操作,將結(jié)果用結(jié)果集返回
   rs = stat.executeQuery("select * from book");
  //5.遍歷結(jié)果集,并獲取查詢結(jié)果
  while(rs.next()) {
   String name = rs.getString("name");
   System.out.println(name);
  }
 }catch(Exception e) {
  e.printStackTrace();
 }finally {
  //6.關(guān)閉連接(后開先關(guān))
  if(rs != null) {
   try {
   rs.close();
   } catch (SQLException e) {
   e.printStackTrace();
   } finally {
   rs = null;
   }
  }
  if(stat != null) {
   try {
   stat.close();
   } catch (SQLException e) {
   e.printStackTrace();
   }finally {
   stat = null;
   }
  }
  if(conn != null) {
   try {
   conn.close();
   } catch (SQLException e) {
   e.printStackTrace();
   }finally {
   conn = null;
   }
  } 
 } //--finally
 } //--main 
}//--class

總結(jié):

這里我只是把所有的異常處理完,但是程序的通用性還不是特別高,因為連接數(shù)據(jù)庫用到的Driver類名、URL、user以及password 都寫在程序中,我們其實可以寫在一個文本文件中,通過對文件的讀取來獲得每種數(shù)據(jù)庫特有的連接參數(shù)。

還有就是在實際開發(fā)過程中,連接數(shù)據(jù)庫的程序代碼一般會寫在一個工具類中,我們想要對數(shù)據(jù)庫中的數(shù)據(jù)進行操作時,只需要調(diào)用這個工具類就可以了,不用每次都寫那么多代碼

接下來我還會更新一篇如何將數(shù)據(jù)庫的連接信息保存在文本文件中,然后讀取這個文件來實現(xiàn)連接數(shù)據(jù)庫的操作,同時我也會將這個程序修改為連接數(shù)據(jù)庫的一個工具類

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關(guān)文章

  • Java反射機制用法總結(jié)

    Java反射機制用法總結(jié)

    反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。下面我們來一起學習一下吧
    2019-05-05
  • SkyWalking?自定義插件(Spring?RabbitMQ)具體分析過程

    SkyWalking?自定義插件(Spring?RabbitMQ)具體分析過程

    這篇文章主要介紹了SkyWalking?自定義插件(Spring?RabbitMQ)具體分析過程,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Mybatis常用注解中的SQL注入實例詳解

    Mybatis常用注解中的SQL注入實例詳解

    MyBatis是一款優(yōu)秀的持久層框架,它支持定制化 SQL(靈活)、存儲過程(PLSQL模塊化的組件,數(shù)據(jù)庫的一部分)以及高級映射(表映射為Bean也可以將Bean映射為表),下面這篇文章主要給大家介紹了關(guān)于Mybatis常用注解中的SQL注入的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • Springboot?JPA如何使用distinct返回對象

    Springboot?JPA如何使用distinct返回對象

    這篇文章主要介紹了Springboot?JPA如何使用distinct返回對象,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Spring如何集成ibatis項目并實現(xiàn)dao層基類封裝

    Spring如何集成ibatis項目并實現(xiàn)dao層基類封裝

    這篇文章主要介紹了Spring如何集成ibatis項目并實現(xiàn)dao層基類封裝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java實現(xiàn)將彩色PDF轉(zhuǎn)為灰度PDF的示例代碼

    Java實現(xiàn)將彩色PDF轉(zhuǎn)為灰度PDF的示例代碼

    本文以Java代碼為例介紹如何實現(xiàn)將彩色PDF文件轉(zhuǎn)為灰度(黑白)的PDF文件,文中的示例代碼講解詳細,感興趣的小伙伴快跟隨小編一起學習一下吧
    2022-03-03
  • IDEA反編譯jar,查看源碼方式

    IDEA反編譯jar,查看源碼方式

    該篇文章總結(jié)了查看Java本地jar包注釋的幾種方法,包括使用快捷鍵CTRL+q和在設(shè)置中設(shè)置自動浮現(xiàn)注釋
    2024-11-11
  • Java使用反射操作數(shù)組示例

    Java使用反射操作數(shù)組示例

    這篇文章主要介紹了Java使用反射操作數(shù)組,結(jié)合實例形式分析了基于java反射機制操作數(shù)組的創(chuàng)建、賦值、輸出等相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2019-07-07
  • Java線程同步實例分析

    Java線程同步實例分析

    這篇文章主要介紹了Java線程同步用法,實例分析了java中線程同步的相關(guān)實現(xiàn)技巧與注意事項,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Java使用Iterator迭代器遍歷集合數(shù)據(jù)的方法小結(jié)

    Java使用Iterator迭代器遍歷集合數(shù)據(jù)的方法小結(jié)

    這篇文章主要介紹了Java使用Iterator迭代器遍歷集合數(shù)據(jù)的方法,結(jié)合實例形式分析了java迭代器進行集合數(shù)據(jù)遍歷的常見操作技巧,需要的朋友可以參考下
    2019-11-11

最新評論

久治县| 通海县| 阜南县| 安阳县| 万州区| 庆安县| 弥渡县| 缙云县| 沙田区| 瑞金市| 乌什县| 扎赉特旗| 鹤岗市| 青州市| 普兰县| 左云县| 鄂州市| 漠河县| 商丘市| 晋州市| 丽水市| 社旗县| 黄梅县| 盐边县| 洛隆县| 武清区| 河曲县| 华安县| 扬中市| 温州市| 绥化市| 黑龙江省| 太湖县| 射洪县| 临潭县| 富阳市| 集贤县| 交口县| 阿坝| 中宁县| 广元市|