您好,登錄后才能下訂單哦!
小編給大家分享一下Java基礎(chǔ)之JDBC連接數(shù)據(jù)庫(kù)與基本操作的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
Java主要應(yīng)用于:1. web開(kāi)發(fā);2. Android開(kāi)發(fā);3. 客戶(hù)端開(kāi)發(fā);4. 網(wǎng)頁(yè)開(kāi)發(fā);5. 企業(yè)級(jí)應(yīng)用開(kāi)發(fā);6. Java大數(shù)據(jù)開(kāi)發(fā);7.游戲開(kāi)發(fā)等。
JDBC全稱(chēng)Java Database Connectivity,它是一個(gè)獨(dú)立于特定數(shù)據(jù)庫(kù)管理系統(tǒng)、通用的SQL數(shù)據(jù)庫(kù)存取和操作的公共接口,定義了用來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)Java類(lèi)庫(kù),使用這個(gè)類(lèi)庫(kù)可以以一種標(biāo)準(zhǔn)的方法、方便地訪問(wèn)數(shù)據(jù)庫(kù)資源
通俗的來(lái)說(shuō),JDBC就是讓我們通過(guò)Java來(lái)連接任何提供了JDBC驅(qū)動(dòng)程序的數(shù)據(jù)庫(kù)系統(tǒng),比如我有一個(gè)SQLServer數(shù)據(jù)和一個(gè)Mysql數(shù)據(jù)庫(kù),我可以通過(guò)Java的JDBC來(lái)完成前面學(xué)習(xí)SQL中的所有操作,而無(wú)需在命令行來(lái)分別連接它們兩個(gè),就像這樣
我來(lái)總結(jié)一下JDBC操作數(shù)據(jù)庫(kù)與表的步驟,然后詳細(xì)來(lái)介紹它們
1.注冊(cè)驅(qū)動(dòng) (只做一次)
2.建立連接(Connection)
3.創(chuàng)建執(zhí)行SQL的語(yǔ)句(Statement)
4.執(zhí)行語(yǔ)句
5.處理執(zhí)行結(jié)果(ResultSet)
6.釋放資源
看到這里是不是很熟悉,沒(méi)錯(cuò),就跟我們前面學(xué)習(xí)Mysql一樣,首先我來(lái)介紹一下JDBC的結(jié)構(gòu)與數(shù)據(jù)庫(kù)的連接
JDBC體系結(jié)構(gòu)由下面兩部分組成:
面向應(yīng)用的API:Java API,抽象接口,供應(yīng)用程序開(kāi)發(fā)人員使用(連接數(shù)據(jù)庫(kù),執(zhí)行SQL語(yǔ)句,獲得結(jié)果)。
面向數(shù)據(jù)庫(kù)的API:Java Driver API,供開(kāi)發(fā)商開(kāi)發(fā)數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序使用
JDBC API
JDBC API 是一系列的接口,它使得應(yīng)用程序能夠進(jìn)行數(shù)據(jù)庫(kù)聯(lián)接,執(zhí)行SQL語(yǔ)句,并且得到返回結(jié)果
Driver接口
java.sql.Driver 接口是所有 JDBC 驅(qū)動(dòng)程序需要實(shí)現(xiàn)的接口。這個(gè)接口是提供給數(shù)據(jù)庫(kù)廠商使用的,不同數(shù)據(jù)庫(kù)廠商提供不同的實(shí)現(xiàn)
在程序中不需要直接去訪問(wèn)實(shí)現(xiàn)了 Driver 接口的類(lèi),而是由驅(qū)動(dòng)程序管理器類(lèi)(java.sql.DriverManager)去調(diào)用這些Driver實(shí)現(xiàn)
Oracle的驅(qū)動(dòng):oracle.jdbc.driver.OracleDriver
mySql的驅(qū)動(dòng): com.mysql.jdbc.Driver
加載與注冊(cè)JDBC驅(qū)動(dòng)
前面我們說(shuō)了,JDBC就是通過(guò)一個(gè)接口和不同數(shù)據(jù)庫(kù)提供了JDBC的驅(qū)動(dòng)來(lái)完成數(shù)據(jù)的操作,因此,我們將驅(qū)動(dòng)加載到JDBC中,加載驅(qū)動(dòng)有兩種方式:
方式一:加載 JDBC 驅(qū)動(dòng)需調(diào)用 Class 類(lèi)的靜態(tài)方法 forName(),向其傳遞要加載的 JDBC 驅(qū)動(dòng)的類(lèi)名
Class.forName(“com.mysql.jdbc.Driver”);
方式二:DriverManager 類(lèi)是驅(qū)動(dòng)程序管理器類(lèi),負(fù)責(zé)管理驅(qū)動(dòng)程序
DriverManager.registerDriver(com.mysql.jdbc.Driver);
通常不用顯式調(diào)用 DriverManager 類(lèi)的 registerDriver() 方法來(lái)注冊(cè)驅(qū)動(dòng)程序類(lèi)的實(shí)例,因?yàn)?Driver 接口的驅(qū)動(dòng)程序類(lèi)都包含了靜態(tài)代碼塊,在這個(gè)靜態(tài)代碼塊中,會(huì)調(diào)用 DriverManager.registerDriver() 方法來(lái)注冊(cè)自身的一個(gè)實(shí)例
當(dāng)我們注冊(cè)并加載驅(qū)動(dòng)后,就可以連接數(shù)據(jù)庫(kù)了,方法和前面我們學(xué)習(xí)Mysql一樣,首先需要輸入賬號(hào),密碼等信息
在JDBC中,我們需要調(diào)用DriverManager 類(lèi)的 getConnection() 方法建立到數(shù)據(jù)庫(kù)的連接
user,password可以用“屬性名=屬性值”方式告訴數(shù)據(jù)庫(kù);
在JDBC中連接數(shù)據(jù)庫(kù)需要一個(gè)特殊的屬性,JDBC URL,它用于連接我們需要操作的數(shù)據(jù)庫(kù)
JDBC URL的標(biāo)準(zhǔn)由三部分組成,各部分間用冒號(hào)分隔。
jdbc:子協(xié)議:子名稱(chēng) 協(xié)議:JDBC URL中的協(xié)議總是jdbc 子協(xié)議:子協(xié)議用于標(biāo)識(shí)一個(gè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序 子名稱(chēng):一種標(biāo)識(shí)數(shù)據(jù)庫(kù)的方法。子名稱(chēng)可以依不同的子協(xié)議而變化,用子名稱(chēng)的目的是為了定位數(shù)據(jù)庫(kù)提供足夠的信息。包含主機(jī)名(對(duì)應(yīng)服務(wù)端的ip地址),端口號(hào),數(shù)據(jù)庫(kù)名
下面我來(lái)列舉幾個(gè)常見(jiàn)的JDBC URL,大家使用的時(shí)候直接復(fù)制就好
// 對(duì)于 Oracle 數(shù)據(jù)庫(kù)連接,采用如下形式: jdbc:oracle:thin:@localhost:1521:DatabaseName // 對(duì)于 SQLServer 數(shù)據(jù)庫(kù)連接,采用如下形式: jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid // 對(duì)于 MYSQL 數(shù)據(jù)庫(kù)連接,采用如下形式: jdbc:mysql://localhost:3306/DatabaseName // 插入中文的時(shí)候,這個(gè)url要寫(xiě)成這個(gè) jdbc:mysql://localhost:3306/數(shù)據(jù)庫(kù)名稱(chēng)?useUnicode=true&characterEncoding=UTF-8
小伙伴們注意一下,當(dāng)我們使用Java向數(shù)據(jù)庫(kù)中插入一個(gè)數(shù)據(jù)時(shí),如果是中文,首先數(shù)據(jù)庫(kù)和表的編碼是utf8,其次就是我們要在URL中聲明一下編碼是UTF-8,不然插入數(shù)據(jù)是?
,如果你們遇到這個(gè)問(wèn)題,那就忽略它
好了,下面是連接數(shù)據(jù)庫(kù)的示例代碼,這里我操作的是Mysql數(shù)據(jù)庫(kù)
package com.company; // 導(dǎo)入依賴(lài)包 import org.junit.Test; import java.io.FileInputStream; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public class Demo1 { /* *獲取connect的三種方式 * */ public static void main(String[] args) { System.out.println("JDBC Test..."); } // 使用Driver來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接 @Test public void test1() throws SQLException { // Driver driver=new com.mysql.jdbc.Driver(); Properties p1 = new Properties(); p1.setProperty("user", "root"); p1.setProperty("password", "mysql123"); Connection connect = driver.connect("jdbc:mysql://localhost:3306/myemployees", p1); System.out.println("connect = " + connect); } // 使用DriverManager來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接 @Test public void test2() throws SQLException { com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver(); Properties p1 = new Properties(); p1.setProperty("user", "root"); p1.setProperty("password", "mysql123"); DriverManager.registerDriver(driver); Connection connection = DriverManager.getConnection ("jdbc:mysql://localhost:3306/myemployees", p1); System.out.println("connection = " + connection); } // 將賬號(hào)密碼抽出到配置文件中,并使用IO流讀取配置文件的方式連接數(shù)據(jù)庫(kù) @Test public void test3() throws Exception { Properties p = new Properties(); FileInputStream fis = new FileInputStream("p.properties"); p.load(fis); fis.close(); Class.forName(p.getProperty("driverClass")); Connection connection = DriverManager.getConnection(p.getProperty("url"), p.getProperty("user"), p.getProperty("password")); System.out.println("connection = " + connection); } }
properties文件內(nèi)容
url=jdbc:mysql://localhost:3306/myemployees user=root password=mysql123 driverClass=com.mysql.jdbc.Driver
介紹完注冊(cè)驅(qū)動(dòng)與數(shù)據(jù)庫(kù)的連接,接下來(lái)就是操作SQL了,在JDBC中,操作SQL需要使用Connection 對(duì)象的 preparedStatement() 方法獲取 PreparedStatement 對(duì)象
PreparedStatement 接口是 Statement 的子接口,它表示一條預(yù)編譯過(guò)的 SQL 語(yǔ)句
PreparedStatement 對(duì)象所代表的 SQL 語(yǔ)句中的參數(shù)用問(wèn)號(hào)(?)來(lái)表示,調(diào)用 PreparedStatement 對(duì)象的 setXxx() 方法來(lái)設(shè)置這些參數(shù). setXxx() 方法有兩個(gè)參數(shù),第一個(gè)參數(shù)是要設(shè)置的 SQL 語(yǔ)句中的參數(shù)的索引(從 1 開(kāi)始),第二個(gè)是設(shè)置的 SQL 語(yǔ)句中的參數(shù)的值
在操作SQL前還要說(shuō)明一下數(shù)據(jù)類(lèi)型,我們知道SQL與Java的數(shù)據(jù)類(lèi)型命名是不一樣的,所以我們?cè)诰幋a時(shí)要注意
java類(lèi)型 | SQL類(lèi)型 |
boolean | BIT |
byte | TINYINT |
short | SMALLINT |
int | INTEGER |
long | BIGINT |
String | CHAR,VARCHAR,LONGVARCHAR |
byte array | BINARY , VAR BINARY |
java.sql.Date | DATE |
java.sql.Time | TIME |
java.sql.Timestamp | TIMESTAMP |
使用PreparedStatementSQL的操作步驟
1.調(diào)用連接對(duì)象的prepareStatement方法,創(chuàng)建PreparedStatement對(duì)象
2.完成預(yù)編譯的SQL語(yǔ)句
3.對(duì)SQL語(yǔ)句中的占位符進(jìn)行賦值
4.提交SQL語(yǔ)句
5.釋放資源
接下來(lái)就是操作SQL增刪改查的示例代碼(為了方便操作,我將數(shù)據(jù)庫(kù)連接抽出到了JDBCUtils類(lèi)中)
// 使用PreparedStatement來(lái)完成數(shù)據(jù)的增刪改查操作 package com.company.jdbc; import org.junit.Test; import java.io.FileInputStream; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Properties; /* 對(duì)數(shù)據(jù)庫(kù)進(jìn)行增,刪,改,查的操作 */ public class CRUDDemo { /* 添加一條數(shù)據(jù) CREATE TABLE student( sid INT, sname VARCHAR(20), sage INT ) */ @Test public void test() throws SQLException { //1.獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection connection = JDBCUtils.getConnection(); //2.預(yù)編譯 // ? : 占位符(只能是設(shè)置數(shù)據(jù)的地方可以寫(xiě)成占位符) String sql = "insert into student(sid,sname,sage) values(?,?,?)"; PreparedStatement ps = connection.prepareStatement(sql); //3.給占位符賦值 /* setInt(int parameterIndex, int x) parameterIndex : 參數(shù)索引(第幾個(gè)占位符) x : 數(shù)據(jù) */ ps.setInt(1,100); //數(shù)據(jù)設(shè)置成中文可不可以取決于表的編碼集 ps.setString(2,"longge"); ps.setInt(3,20); //4.執(zhí)行sql //返回值 : 有幾條數(shù)據(jù)受到影響 int result = ps.executeUpdate();//增,刪,改的語(yǔ)句使用該方法 System.out.println("有"+result+"條數(shù)據(jù)受到影響"); //5.關(guān)資源 JDBCUtils.close(ps,connection); } /* 改 */ @Test public void test2() throws SQLException { //1.獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection connection = JDBCUtils.getConnection(); //2.預(yù)編譯 String sql = "update student set sid=? where sid=?"; PreparedStatement ps = connection.prepareStatement(sql); //3.給占位符賦值 ps.setInt(1,10); ps.setInt(2,100); //4.執(zhí)行sql語(yǔ)句 int result = ps.executeUpdate(); System.out.println("有"+result+"條數(shù)據(jù)受到影響"); //5.關(guān)閉資源 JDBCUtils.close(ps,connection); } /* 刪除數(shù)據(jù) */ @Test public void test3() throws SQLException { //1.獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection connection = JDBCUtils.getConnection(); //2.預(yù)編譯 String sql = "delete from student where sid=?"; PreparedStatement ps = connection.prepareStatement(sql); //3.給占位符賦值 ps.setInt(1,10); //4.執(zhí)行sql語(yǔ)句 int i = ps.executeUpdate(); System.out.println("有"+i+"條數(shù)據(jù)受到影響"); //5.關(guān)閉資源 JDBCUtils.close(ps,connection); } /* 查詢(xún)數(shù)據(jù) */ @Test public void test4() throws Exception { List<Student> students = getStudent(); for (Student s : students) { System.out.println(s); } } public List<Student> getStudent() throws Exception { //1.獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection connection = JDBCUtils.getConnection(); //2.預(yù)編譯 PreparedStatement ps = connection.prepareStatement("select sid,sname,sage from student"); //3.執(zhí)行sql語(yǔ)句 ResultSet resultSet = ps.executeQuery();//查詢(xún)語(yǔ)必須執(zhí)行此方法 List<Student> list = new ArrayList<>(); //4.遍歷ResultSet while(resultSet.next()){//是否有數(shù)據(jù) /* getInt(String columnLabel) :根據(jù)字段名獲取對(duì)應(yīng)的數(shù)據(jù) getInt(int columnIndex) : 根據(jù)列的索引獲取對(duì)應(yīng)的數(shù)據(jù) */ int sid = resultSet.getInt("sid"); String sname = resultSet.getString("sname"); int sage = resultSet.getInt("sage"); //System.out.println(sid + " " + sname + " " + sage); list.add(new Student(sid,sname,sage)); } //5.關(guān)閉資源 JDBCUtils.close(ps,connection,resultSet); return list; } }
JDBCUtils連接數(shù)據(jù)庫(kù)的工具類(lèi)
//JDBCUtils類(lèi),專(zhuān)門(mén)實(shí)現(xiàn)數(shù)據(jù)庫(kù)的連接與資源釋放操作 package com.company.jdbc; import java.io.FileInputStream; import java.io.IOException; import java.sql.*; import java.util.Properties; public class JDBCUtils { private static String driverClass; private static String url; private static String username; private static String password; static{ FileInputStream fis = null; try { //1.獲取數(shù)據(jù)庫(kù)連接對(duì)象 //通過(guò)Properties讀取內(nèi)容 //1.創(chuàng)建Properties對(duì)象 Properties p = new Properties(); //2.加載流 fis = new FileInputStream("jdbc.properties"); p.load(fis); driverClass = p.getProperty("driverClass"); url = p.getProperty("url"); username = p.getProperty("username"); password = p.getProperty("password"); }catch (Exception e){ //終止程序的運(yùn)行 e.printStackTrace(); //將編譯時(shí)異常轉(zhuǎn)換成運(yùn)行時(shí)異常 throw new RuntimeException("xxxxxxxx"); }finally { if (fis != null){ //3.關(guān)資源 try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 獲取連接對(duì)象 */ public static Connection getConnection(){ try { Class.forName(driverClass); //獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection connection = DriverManager.getConnection(url, username, password); return connection; }catch (Exception e){ e.printStackTrace(); throw new RuntimeException("獲取連接失敗"); } } /* 關(guān)閉資源 */ public static void close(PreparedStatement ps, Connection connection) { if (ps != null){ try { ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } if (connection != null){ try { connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } public static void close(PreparedStatement ps, Connection connection, ResultSet resultSet) { close(ps,connection); if (resultSet != null){ try { resultSet.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } }
在前面對(duì)數(shù)據(jù)的增刪改查操作中,查詢(xún)操作比較復(fù)雜一些,因?yàn)槲覀円邮諗?shù)據(jù)庫(kù)返回的結(jié)果,因此我們要了解一下ResultSet 接口,它由數(shù)據(jù)庫(kù)廠商實(shí)現(xiàn)
查詢(xún)需要調(diào)用Prepared Statement 的 executeQuery() 方法,查詢(xún)結(jié)果是一個(gè) ResultSet 對(duì)象
ResultSet 對(duì)象維護(hù)了一個(gè)指向當(dāng)前數(shù)據(jù)行的游標(biāo),初始的時(shí)候,游標(biāo)在第一行之前,可以通過(guò) ResultSet 對(duì)象的 next() 方法移動(dòng)到下一行,具體方法可以自定百度
ResultSet:代表結(jié)果集,其封裝了使用 JDBC 進(jìn)行查詢(xún)的結(jié)果. 調(diào)用 PreparedStatement 對(duì)象的 executeQuery() 可以得到結(jié)果集.ResultSet 返回的實(shí)際上就是一張數(shù)據(jù)表. 有一個(gè)指針指向數(shù)據(jù)表的第一條記錄的前面
以上是“Java基礎(chǔ)之JDBC連接數(shù)據(jù)庫(kù)與基本操作的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。