當前位置:
首頁 > 知識 > 一顆簡單的JDBC栗子

一顆簡單的JDBC栗子

前言:安裝好資料庫之後,我們編寫的java程序是不能直接使用資料庫的,而JDBC(Java Database Connectivity,即java資料庫連接)是java語言里用來規範客戶端程序訪問資料庫的API,有了它,我們就可以向各種關係型資料庫發送SQL語句,從而實現對資料庫的增刪改查等操作。

準備工作:

1.資料庫:這裡以MySQL為例,創建一個Person表,四個欄位分別為:自增主鍵id、姓名name、性別gender、年齡age

1 DROP TABLE IF EXISTS `person`;
2 CREATE TABLE `person` (
3 `id` int(11) NOT NULL AUTO_INCREMENT,
4 `name` varchar(11) DEFAULT NULL,
5 `gender` varchar(11) DEFAULT NULL,
6 `age` int(11) DEFAULT NULL,
7 PRIMARY KEY (`id`)
8 ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
9
10 INSERT INTO `person` VALUES ("1", "小明", "男", "18");
11 INSERT INTO `person` VALUES ("2", "小芳", "女", "19");
12 INSERT INTO `person` VALUES ("3", "小剛", "男", "20");
13 INSERT INTO `person` VALUES ("4", "小麗", "女", "21");

2.資料庫驅動程序jar包:這裡使用的是mysql-connector-java-5.1.42-bin.jar

3.在eclipse中導入驅動包:右鍵項目點擊Builder Path----Configure Builder Path----Add External JARs----找到jar包位置選擇打開----Ok,可以開始搞事情了!

圖示如下:

一顆簡單的JDBC栗子

先完整演示一段簡單的JDBC操作過程。

1 package com.jdbc.demo;
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.sql.Statement;
8
9 //一段完整的jdbc操作過程,後面會詳細介紹,為了代碼視圖簡潔,異常均拋出。
10 public class Demo {
11
12 public static void main(String[] args) throws ClassNotFoundException, SQLException {
13 //第1步,註冊載入驅動類
14 Class.forName("com.mysql.jdbc.Driver");
15 //第2步,獲取資料庫連接,方法中3個參數依次為:
16 //url:就是你要連接的資料庫的地址,不同的資料庫格式會有差異
17 //user:就是資料庫的用戶名,例如MySQL的root
18 //password:資料庫連接密碼
19 String url = "jdbc:mysql://127.0.0.1/hb?characterEncoding=utf-8";
20 String user = "root";
21 String password = "123123";
22 Connection conn = DriverManager.getConnection(url, user, password);
23 //第3步,構造語句集對象,為了簡要直觀,這裡使用Statement,不過實際開發建議用PreparedStatement
24 String sql = "select * from person";
25 Statement stmt = conn.createStatement;
26 //第4步,提交SQL語句,這是是查詢,所以調用executeQuery方法,會返回一個集合,我們可以遍歷輸出其中信息;
27 //如果是增刪改,不同於資料庫中的3種SQL語句,這裡都是調用executeUpdate方法,返回的是int值
28 ResultSet rs = stmt.executeQuery(sql);
29 //第5步(可選),處理結果,在這裡我們輸出Person表中所有人名
30 while(rs.next) {
31 String name = rs.getString("name");
32 System.out.println(name);
33 }
34 //第6步,關閉相關對象,這裡為ResultSet,Statement,Connection
35 //注意!關閉順序和聲明順序相反!依次如下
36 rs.close;
37 stmt.close;
38 conn.close;
39
40 }
41
42 }

程序運行結果如下:

一顆簡單的JDBC栗子

相關API介紹

java.sql.Connection:

與資料庫的連接,注意導包不要導錯,因為導入MySQL驅動後,在com.mysql.jdbc下也有個Connection,如果導成這個會出錯;

連接由JDBC管理層的DriverManager類調用getConnection方法獲得,方法中後兩個參數比較簡單,一個用戶名一個密碼,第一個參數url格式則與各資料庫有關

MySQL:jdbc:mysql://<:port>/,默認埠3306,如果伺服器使用默認埠則port可以省略,可以在URL中添加額外的連接屬性jdbc:mysql://:/?property1=value1&property2=value2;

ORACLE:jdbc:oracle:thin:@<:port>:

java,sql.Statement 和java.sql.PreparedStatement

語句對象,用於提交SQL語句;

Statement通常用於執行靜態SQL語句,statement.excute(sql)即可提交;

PreparedStatement可以執行動態SQL語句,允許參數化查詢,而且性能更好,還可以有效避免SQL注入式攻擊,後面示例都使用PreparedStatement

java.sql.ResultSet:

指定SQL語句(通常為查詢)執行返回的原始結果集,在實際開發我們通常對結果進行再封裝,以方便調用

實體類Person

1 package com.jdbc.entity;
2 //實體類Person,屬性與資料庫中欄位對應
3 public class Person {
4 private Integer id;
5 private String name;
6 private String gender;
7 private Integer age;
8 public Integer getId {
9 return id;
10 }
11 public void setId(Integer id) {
12 this.id = id;
13 }
14 public String getName {
15 return name;
16 }
17 public void setName(String name) {
18 this.name = name;
19 }
20 public String getGender {
21 return gender;
22 }
23 public void setGender(String gender) {
24 this.gender = gender;
25 }
26 public Integer getAge {
27 return age;
28 }
29 public void setAge(Integer age) {
30 this.age = age;
31 }
32 @Override
33 public String toString {
34 return "Person [id=" + id + ", name=" + name + ", gender=" + gender
35 + ", age=" + age + "]";
36 }
37
38 }

簡易封裝一個DAO類實現對Person表的增刪改查

1 package com.jdbc.demo;
2
3 import java.sql.Connection;
4 import java.sql.PreparedStatement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import com.jdbc.entity.Person;
11
12
13 //封裝Person表的增刪改查方法
14 public class PersonDaoImpl {
15 //這裡的問號?是佔位符,用於給將要傳遞的參數佔位置,實現了動態SQL語句的執行
16 //添加一條記錄的SQL語句,第一個參數由於數據表中是主鍵自增,這裡可以用null
17 private static final String SQL_ADD = "insert into person values(null,?,?,?)";
18 //刪除,指定id的記錄
19 private static final String SQL_DEL = "delete from person where id = ?";
20 //修改,指定id的記錄
21 private static final String SQL_UPD = "update person set name = ?,gender = ?,age = ? where id = ?";
22 //查詢,指定id記錄
23 private static final String SQL_ID = "select * from person where id = ?";
24 //查詢,所有記錄
25 private static final String SQL_ALL = "select * from person";
26
27 //添加一條記錄
28 public boolean add(Person p) {
29 Connection conn = JdbcUtil.getConnection;
30 PreparedStatement ps = null;
31 try {
32 ps = conn.prepareStatement(SQL_ADD);
33 //把我們傳入的person對象的屬性值分作為佔位符的值傳入,數組各值順序對應佔位符欄位順序
34 Object params = {p.getName,p.getGender,p.getAge};
35 int len = params.length;
36 for(int i = 0;i < len;i++) { 37 //!!!這裡比較特殊,很多下標都是從0開始,例如數組, 38 //!!!但是這個setObject方法第一個索引參數是從1開始 39 ps.setObject(i+1, params[i]); 40 } 41 //這裡的整型返回值line意指更新的記錄數,或者說是資料庫中受影響的記錄行數 42 //之前的Statement.excute方法要傳入SQL語句字元串參數, 43 //但是用了PreparedStatement就不用傳參數了,因為在前面我們已經預定義處理了 44 int line = ps.executeUpdate; 45 if (line > 0) {
46 System.out.println("添加成功,受影響記錄數為"+line);
47 return true;//結束,但是後面finally區代碼會執行
48 }
49 } catch (SQLException e) {
50 e.printStackTrace;
51 } finally {
52 //關閉相關對象
53 JdbcUtil.close(null, ps, conn);
54 }
55 System.out.println("添加失敗");
56 return false;
57 }
58 //刪除一條記錄
59 public boolean delete(int id) {
60 Connection conn = JdbcUtil.getConnection;
61 PreparedStatement ps = null;
62 try {
63 ps = conn.prepareStatement(SQL_DEL);
64 ps.setInt(1, id);
65 //這裡的整型返回值line意指更新的記錄數,或者說是資料庫中受影響的記錄行數
66 int line = ps.executeUpdate;
67 if (line > 0) {
68 System.out.println("刪除成功,受影響記錄數為"+line);
69 return true;//結束,但是後面finally區代碼會執行
70 }
71 } catch (SQLException e) {
72 e.printStackTrace;
73 } finally {
74 //關閉相關對象
75 JdbcUtil.close(null, ps, conn);
76 }
77 System.out.println("刪除失敗");
78 return false;
79 }
80 //修改一條記錄
81 public boolean update(Person p) {
82 Connection conn = JdbcUtil.getConnection;
83 PreparedStatement ps = null;
84 try {
85 ps = conn.prepareStatement(SQL_UPD);
86 //把我們傳入的person對象的屬性值分作為佔位符的值傳入
87 Object params = {p.getName,p.getGender,p.getAge,p.getId};
88 int len = params.length;
89 for(int i = 0;i < len;i++) { 90 //!!!這裡比較特殊,很多下標都是從0開始,例如數組, 91 //!!!但是這個setObject方法第一個索引參數是從1開始 92 ps.setObject(i+1, params[i]); 93 } 94 //這裡的整型返回值line意指更新的記錄數,或者說是資料庫中受影響的記錄行數 95 int line = ps.executeUpdate; 96 if (line > 0) {
97 System.out.println("修改成功,受影響記錄數為"+line);
98 return true;//結束,但是後面finally區代碼會執行
99 }
100 } catch (SQLException e) {
101 e.printStackTrace;
102 } finally {
103 //關閉相關對象
104 JdbcUtil.close(null, ps, conn);
105 }
106 System.out.println("修改失敗");
107 return false;
108 }
109 //獲取一條記錄,這裡返回的不再是布爾值,而是一個對應數據表中一條記錄的Person對象
110 public Person findById(int id) {
111 Connection conn = JdbcUtil.getConnection;
112 PreparedStatement ps = null;
113 ResultSet rs = null;
114 try {
115 ps = conn.prepareStatement(SQL_ID);
116 ps.setInt(1, id);
117 //返回結果集,這裡是查詢指定id,所以結果集中應該最多只有一條記錄
118 rs = ps.executeQuery;
119 if(rs.next) {
120 Person p = new Person;
121 p.setId(id);
122 //這裡的Result的getObject方法,參數為數據表中欄位名,可以獲取對應欄位值
123 p.setName(rs.getString("name"));
124 p.setGender(rs.getString("gender"));
125 p.setAge(rs.getInt("age"));
126 return p;//返回p對象,結束
127 }
128 } catch (SQLException e) {
129 e.printStackTrace;
130 } finally {
131 //關閉相關對象
132 JdbcUtil.close(rs, ps, conn);
133 }
134 return null;
135 }
136 //獲取所有記錄,返回結果集不便操作,故封裝到一個List中作為方法返回值
137 public List findAll {
138 Connection conn = JdbcUtil.getConnection;
139 PreparedStatement ps = null;
140 ResultSet rs = null;
141 List list = new ArrayList<>;
142 try {
143 ps = conn.prepareStatement(SQL_ALL);
144 //返回結果集
145 rs = ps.executeQuery;
146 while(rs.next) {
147 //創建一個Person對象
148 Person p = new Person;
149 //這裡的Result的getObject方法,參數為數據表中欄位名,可以獲取對應欄位值
150 p.setId(rs.getInt("id"));
151 p.setName(rs.getString("name"));
152 p.setGender(rs.getString("gender"));
153 p.setAge(rs.getInt("age"));
154 list.add(p);//添加至集合
155 }
156 return list;
157 } catch (SQLException e) {
158 e.printStackTrace;
159 } finally {
160 //關閉相關對象
161 JdbcUtil.close(rs, ps, conn);
162 }
163 return null;
164 }
165 }

小結

JDBC操作資料庫步驟概述如下:

1.註冊載入驅動類

2.獲取連接

3.創建語句對象

4.執行SQL語句(excute)

5(可選).處理結果

6.關閉相關對象(注意順序:依次為ResultSet、Statement/PreparedStatement、Connction)

擴展

上述過程能基本完整實現對一個數據表的操作,但是只能針對固定的單個數據表,利用泛型、反射等技術,可對dao層代碼進行抽取和封裝,添加SQL語句實現聯表查詢,使得程序更具有通用性和靈活性,對任意的數據表都適用。在實際開發過程中,有框架已經封裝了JDBC,如hibernate和mybatis,可以通過底層的JDBC操作進一步學習。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

MySql單表最大8000W+ 之資料庫遇瓶頸記
nodejs伺服器部署教程二
使用JS開發桌面端應用程序NW.js-3-開發問題小記
raft如何實現Linearizable Read
OpenStack(企業私有雲)萬里長征第五步——虛擬機Migrate&Resize

TAG:達人科技 |

您可能感興趣

暖心的AMD:借你一顆CPU來刷BIOS
老主板無法刷BIOS上三代銳龍?AMD借你一顆CPU
老主板無法刷BIOS上三代銳龍?AMD借你一顆U
蘋果iPhone XR特別版開箱:心口一顆硃砂痣
MINI BOOK10月下| 李子璇:「我是一顆會魔法的小豆子」!
蘋果:用 HomePod 聽歌,比一顆 LED 燈泡還省電
官方向你丟來一顆超燃的BML-SP×AWM現場repo
SUPER ME | 每天只種一顆草
MIT AI 實驗室研究如何打擊假新聞;特斯拉下一代 Roadster 諜照曝光;一顆小行星與地球擦肩而過
戴森 Cyclone V10 評測:一顆射向老用戶的子彈
TOP:一顆扣子的重要性!
一顆潛力無限的賽道種子 本田BRIO
4K市場一顆炸彈:日系標杆JVC為何這麼干
黑石奈央子——一顆把復古風演繹的超有味道的BlackStone 春天與復古來一場完美邂逅!(一)
土豪試驗:一顆手槍子彈能射穿幾台iPhone X
日本的一顆「小球」是如何卡住了我們LCD屏的脖子
RMJ如何成為刀具行業的一顆新星?RMJ的成長之路簡述
野獸派 x BVLGARI:聞到看到摸到,一顆柔軟的粉紅心
這條被子,一顆賽艇!艾錫 APEX C棉多用被子/毯子使用心得
一顆小螺絲釘摧毀iPhone美國製造夢