?
https://blog.csdn.net/jg15617651654/article/details/63262456/
?
JDBC連接數(shù)據(jù)庫教程,postgreSQL
流年你奈我何?2017-03-18 17:17:43??17389??收藏?4
分類專欄:?Postgres 修煉之道?文章標(biāo)簽:?postgresql?數(shù)據(jù)庫?事務(wù)?jdbc
版權(quán)
0、概述
本文借postgreSQL通過JDBC連接數(shù)據(jù)庫的示例,介紹了常見數(shù)據(jù)庫操作及JDBC的API、JDBC的一般工作流程及JDBC事務(wù)。
1、準(zhǔn)備工作
A、下載安裝好postgreSQL數(shù)據(jù)庫。
B、新建一個(gè)Java項(xiàng)目,并導(dǎo)入postgreSQL的JDBC驅(qū)動(dòng)程序jar包。
2、Java連接postgreSQL代碼示例。
[java]?view plain?copy??
package?vertxTest;????import?java.sql.Connection;??import?java.sql.DriverManager;??import?java.sql.Statement;????public?class?PostgreSQLJDBC?{??????public?static?void?main(String?args[])?{??????????Connection?c?=?null;??????????Statement?stmt?=?null;??????????try?{??????????????Class.forName("org.postgresql.Driver");??????????????c?=?DriverManager.getConnection("jdbc:postgresql://localhost:5432/pgsqltest",?"postgres",?"2016");??????????????c.setAutoCommit(false);?//?把自動(dòng)提交??????????????System.out.println("Opened?database?successfully");????????????????stmt?=?c.createStatement();???????????????String?sql?=?"CREATE?TABLE?STUDENTS?"?+????????????????????????????"(ID?TEXT?PRIMARY?KEY?????NOT?NULL?,"?+????????????????????????????"?NAME????????????TEXT????NOT?NULL,?"?+????????????????????????????"?SEX?????????????TEXT????NOT?NULL,?"?+????????????????????????????"?AGE?????????????TEXT????NOT?NULL)";???????????????stmt.executeUpdate(sql);???????????????System.out.println("Table?created?successfully");????????????????????????????stmt.close();??????????????c.commit();??????????????c.close();??????????}?catch?(Exception?e)?{??????????????System.err.println(e.getClass().getName()?+?":?"?+?e.getMessage());??????????????System.exit(0);??????????}??????}??}??
?
3、常見增刪改查操作。
A、定義記錄的類(可選)
[java]?view plain?copy??
package?vertxTest;????public?class?Student?{??????private?String?Id;??????private?String?Name;??????private?String?Sex;??????private?String?Age;????????Student(String?Id,String?Name,?String?Sex,?String?Age)?{??????????this.Id?=?Id;?//default??????????this.Name?=?Name;??????????this.Sex?=?Sex;??????????this.Age?=?Age;??????}????????public?String?getId()?{??????????return?Id;??????}????????public?void?setId(String?Id)?{??????????this.Id?=?Id;??????}????????public?String?getName()?{??????????return?Name;??????}????????public?void?setName(String?Name)?{??????????this.Name?=?Name;??????}????????public?String?getSex()?{??????????return?Sex;??????}????????public?void?setSex(String?Sex)?{??????????this.Sex?=?Sex;??????}????????public?String?getAge()?{??????????return?Age;??????}????????public?void?setage(String?Age)?{??????????this.Age?=?Age;??????}??}??
?
B、JDBC表數(shù)據(jù)操作方法
[java]?view plain?copy??
package?vertxTest;????import?java.sql.Connection;??import?java.sql.DriverManager;??import?java.sql.PreparedStatement;??import?java.sql.ResultSet;??import?java.sql.SQLException;????public?class?JDBCOperation?{????????????/**??????*?@method?getConn()?獲取數(shù)據(jù)庫的連接??????*?@return?Connection??????*/??????public?Connection?getConn()?{??????????String?driver?=?"org.postgresql.Driver";??????????String?url?=?"jdbc:postgresql://localhost:5432/pgsqltest";??????????String?username?=?"postgres";??????????String?password?=?"2016";??????????Connection?conn?=?null;??????????try?{??????????????Class.forName(driver);?//?classLoader,加載對(duì)應(yīng)驅(qū)動(dòng)??????????????conn?=?(Connection)?DriverManager.getConnection(url,?username,?password);??????????}?catch?(ClassNotFoundException?e)?{??????????????e.printStackTrace();??????????}?catch?(SQLException?e)?{??????????????e.printStackTrace();??????????}??????????return?conn;??????}????????????/**??????*?@method?insert(Student?student)?往表中插入數(shù)據(jù)??????*?@return?int?成功插入數(shù)據(jù)條數(shù)??????*/??????public?int?insert(Student?student)?{??????????Connection?conn?=?getConn();??????????int?i?=?0;??????????String?sql?=?"insert?into?students?(id,Name,Sex,Age)?values(?,?,?,?)";??????????PreparedStatement?pstmt;??????????try?{??????????????pstmt?=?(PreparedStatement)?conn.prepareStatement(sql);??????????????pstmt.setString(1,?student.getId());??????????????pstmt.setString(2,?student.getName());??????????????pstmt.setString(3,?student.getSex());??????????????pstmt.setString(4,?student.getAge());??????????????i?=?pstmt.executeUpdate();??????????????pstmt.close();??????????????conn.close();??????????}?catch?(SQLException?e)?{??????????????e.printStackTrace();??????????}??????????return?i;??????}????????????/**??????*?@method?delete(Student?student)?刪除表中數(shù)據(jù)??????*?@return?int?成功刪除表中數(shù)據(jù)條數(shù)??????*/??????public?int?delete(String?name)?{??????????Connection?conn?=?getConn();??????????int?i?=?0;??????????String?sql?=?"delete?from?students?where?Name='"?+?name?+?"'";??????????PreparedStatement?pstmt;??????????try?{??????????????pstmt?=?(PreparedStatement)?conn.prepareStatement(sql);??????????????i?=?pstmt.executeUpdate();??????????????System.out.println("resutl:?"?+?i);??????????????pstmt.close();??????????????conn.close();??????????}?catch?(SQLException?e)?{??????????????e.printStackTrace();??????????}??????????return?i;??????}????????????/**??????*?@method?update(Student?student)?更改表中數(shù)據(jù)??????*?@return?int?成功更改表中數(shù)據(jù)條數(shù)??????*/??????public?int?update(Student?student)?{??????????Connection?conn?=?getConn();??????????int?i?=?0;??????????String?sql?=?"update?students?set?Age='"?+?student.getAge()?+?"'?where?Name='"?+?student.getName()?+?"'";??????????PreparedStatement?pstmt;??????????try?{??????????????pstmt?=?(PreparedStatement)?conn.prepareStatement(sql);??????????????i?=?pstmt.executeUpdate();??????????????System.out.println("resutl:?"?+?i);??????????????pstmt.close();??????????????conn.close();??????????}?catch?(SQLException?e)?{??????????????e.printStackTrace();??????????}??????????return?i;??????}????????????/**??????*?@method?Integer?getAll()?查詢并打印表中數(shù)據(jù)??????*?@return?Integer?查詢并打印表中數(shù)據(jù)??????*/??????public?Integer?getAll()?{??????????Connection?conn?=?getConn();??????????String?sql?=?"select?*?from?students";??????????PreparedStatement?pstmt;??????????try?{??????????????pstmt?=?(PreparedStatement)conn.prepareStatement(sql);??????????????ResultSet?rs?=?pstmt.executeQuery();??????????????int?col?=?rs.getMetaData().getColumnCount();??????????????System.out.println("============================");??????????????while?(rs.next())?{??????????????????for?(int?i?=?1;?i?<=?col;?i++)?{??????????????????????System.out.print(rs.getString(i)?+?"\t");??????????????????????if?((i?==?2)?&&?(rs.getString(i).length()?<?8))?{??????????????????????????System.out.print("\t");??????????????????????}???????????????????}??????????????????System.out.println("");??????????????}??????????????????System.out.println("============================");??????????}?catch?(SQLException?e)?{??????????????e.printStackTrace();??????????}??????????return?null;??????}??}??
?
C、測(cè)試類
[java]?view plain?copy??
package?vertxTest;????public?class?JDBCTest?{??????public?static?void?main(String?args[])?{??????????JDBCOperation?op?=?new?JDBCOperation();??????????op.getAll();??????????op.insert(new?Student("001","Achilles",?"Male",?"14"));??????????op.insert(new?Student("002","Bean",?"Fmale",?"15"));??????????op.getAll();??????????op.update(new?Student("002","Bean",?"",?"7"));??????????op.delete("Achilles");??????????op.getAll();??????}??}??
?
C、輸出結(jié)果
| ============================ ============================ ============================ 001 Achilles?? Male?? 14? 002 Bean?????? Fmale? 15? ============================ resutl: 1 resutl: 1 ============================ 002 Bean?????? Fmale? 7?? ============================ |
?
4、代碼分析
在上述對(duì)數(shù)據(jù)庫進(jìn)行增刪改查的過程中,可以發(fā)現(xiàn)其共性部分,即通用的流程:
?
(1)創(chuàng)建Connection對(duì)象、SQL查詢命令字符串;
?
(2)對(duì)Connection對(duì)象傳入SQL查詢命令,獲得PreparedStatement對(duì)象;
?
(3)對(duì)PreparedStatement對(duì)象執(zhí)行executeUpdate()或executeQurey()獲得結(jié)果;
?
(4)先后關(guān)閉PreparedStatement對(duì)象和Connection對(duì)象。
?
可見,使用JDBC時(shí),最常打交道的是Connection、PreparedStatement這兩個(gè)類,以及select中的ResultSet類。
5、JDBC的API
| API | 說明 |
| java.sql.Connection? | 與特定數(shù)據(jù)庫的連接(會(huì)話)。能夠通過getMetaData方法獲得數(shù)據(jù)庫提供的信息、所支持的SQL語法、存儲(chǔ)過程和此連接的功能等信息。代表了數(shù)據(jù)庫。? |
| java.sql.Driver? | 每個(gè)驅(qū)動(dòng)程序類必需實(shí)現(xiàn)的接口,同時(shí),每個(gè)數(shù)據(jù)庫驅(qū)動(dòng)程序都應(yīng)該提供一個(gè)實(shí)現(xiàn)Driver接口的類。? |
| java.sql.DriverManager (Class) | 管理一組JDBC驅(qū)動(dòng)程序的基本服務(wù)。作為初始化的一部分,此接口會(huì)嘗試加載在”jdbc.drivers”系統(tǒng)屬性中引用的驅(qū)動(dòng)程序。只是一個(gè)輔助類,是工具。? |
| java.sql.Statement? | 用于執(zhí)行靜態(tài)SQL語句并返回其生成結(jié)果的對(duì)象。? |
| java.sql.PreparedStatement? | 繼承Statement接口,表示預(yù)編譯的SQL語句的對(duì)象,SQL語句被預(yù)編譯并且存儲(chǔ)在PreparedStatement對(duì)象中。然后可以使用此對(duì)象高效地多次執(zhí)行該語句。? |
| java.sql.CallableStatement? | 用來訪問數(shù)據(jù)庫中的存儲(chǔ)過程。它提供了一些方法來指定語句所使用的輸入/輸出參數(shù)。? |
| java.sql.PreparedStatement? | 繼承Statement接口,表示預(yù)編譯的SQL語句的對(duì)象,SQL語句被預(yù)編譯并且存儲(chǔ)在PreparedStatement對(duì)象中。然后可以使用此對(duì)象高效地多次執(zhí)行該語句。? |
| java.sql.CallableStatement? | 用來訪問數(shù)據(jù)庫中的存儲(chǔ)過程。它提供了一些方法來指定語句所使用的輸入/輸出參數(shù)。? |
?
6、JDBC的一般工作流程
(1)加載驅(qū)動(dòng)
???????? Class.forName(“org.postgresql.Driver”); JAVA規(guī)范中明確規(guī)定:所有的驅(qū)動(dòng)程序必須在靜態(tài)初始化代碼塊中將驅(qū)動(dòng)注冊(cè)到驅(qū)動(dòng)程序管理器中。
(2)建立連接
conn=DriverManager.getConnection("jdbc:postgresql://localhost:5432/pgsqltest","postgres", "2016");
Connection連接是通過DriverManager的靜態(tài)方法getConnection(.....)來得到的,這個(gè)方法的實(shí)質(zhì)是把參數(shù)傳到實(shí)際的Driver中的connect()方法中來獲得數(shù)據(jù)庫連接的。
postgreSQL URL的格式:
jdbc:postgresql:(協(xié)議)@XXX.XXX.X.XXX:XXXX(IP地址及端口號(hào)):XXXXXXX(所使用的庫名)
MySQL?URL的寫法 例:jdbc:mysql://192.168.8.21:3306/test
(3)獲得Statement對(duì)象
Statement stmt = conn.createStatement();
(4)執(zhí)行sql語句
stmt.executeQuery(String sql); //返回一個(gè)查詢結(jié)果集。
stmt.executeUpdate(String sql); //返回值為int型,表示影響記錄的條數(shù)。
將sql語句通過連接發(fā)送到數(shù)據(jù)庫中執(zhí)行,以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫的操作。
(5)處理結(jié)果集
使用Connection對(duì)象獲得一個(gè)Statement,Statement中的executeQuery(Stringsql) 方法可以使用select語句查詢,并且返回一個(gè)結(jié)果集。 ResultSet,通過遍歷這個(gè)結(jié)果集,可以獲得select語句的查尋結(jié)果,ResultSet的next()方法會(huì)操作一個(gè)游標(biāo)從第一條記錄的前面開始讀取,直到最后一條記錄。
executeUpdate(String sql) 方法用于執(zhí)行DDL和DML語句,比如可以u(píng)pdate,delete操作。
只有執(zhí)行select語句才有結(jié)果集返回。
Statement str=con.createStatement(); //創(chuàng)建Statement
String sql=”insert into test(id,name)values(1,”+”’”+”test”+”’”+”)”;
str. executeUpdate(sql);//執(zhí)行Sql語句
String sql=”select * from test”;
ResultSet rs=str. executeQuery(String sql);//執(zhí)行Sql語句,執(zhí)行select語句后有結(jié)果集
//遍歷處理結(jié)果集信息
while(rs.next()){
System.out.println(rs.getInt(“id”));
System.out.println(rs.getString(“name”))
}
(6)關(guān)閉數(shù)據(jù)庫連接
rs.close();
stmt.close();
con.close();
ResultSet Statement Connection是依次依賴的。
注意:要按先ResultSet結(jié)果集,后Statement,最后Connection的順序關(guān)閉資源,因?yàn)镾tatement和ResultSet是需要連接時(shí)才可以使用的,所以在使用結(jié)束之后有可能其它的Statement還需要連接,所以不能現(xiàn)關(guān)閉Connection。
7、JDBC事務(wù)
事務(wù)的4大特性
(1) 原子性
事務(wù)的原子性指的是,事務(wù)中包含的程序作為數(shù)據(jù)庫的邏輯工作單位,它所做的對(duì)數(shù)據(jù)修改操作要么全部執(zhí)行,要么完全不執(zhí)行。
原子操作,也就是不可分割的操作,必須一起成功一起失敗。
(2) 一致性
事務(wù)的一致性指的是在一個(gè)事務(wù)執(zhí)行之前和執(zhí)行之后數(shù)據(jù)庫都必須處于一致性狀態(tài)。這種特性稱為事務(wù)的一致性。假如數(shù)據(jù)庫的狀態(tài)滿足所有的完整性約束,就說該數(shù)據(jù)庫是一致的。
(3) 分離性
分離性指并發(fā)的事務(wù)是相互隔離的。即一個(gè)事務(wù)內(nèi)部的操作及正在操作的數(shù)據(jù)必須封鎖起來,不被其它企圖進(jìn)行修改的事務(wù)看到。
(4) 持久性
持久性意味著當(dāng)系統(tǒng)或介質(zhì)發(fā)生故障時(shí),確保已提交事務(wù)的更新不能丟失。即一旦一個(gè)事務(wù)提交,DBMS保證它對(duì)數(shù)據(jù)庫中數(shù)據(jù)的改變應(yīng)該是永久性的,耐得住任何系統(tǒng)故障。持久性通過數(shù)據(jù)庫備份和恢復(fù)來保證。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的JDBC连接数据库教程,postgreSQL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。