一顆簡單的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操作過程。 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 }
程序運行結果如下:
java.sql.Connection:
與資料庫的連接,注意導包不要導錯,因為導入MySQL驅動後,在com.mysql.jdbc下也有個Connection,如果導成這個會出錯;
連接由JDBC管理層的DriverManager類調用getConnection方法獲得,方法中後兩個參數比較簡單,一個用戶名一個密碼,第一個參數url格式則與各資料庫有關
MySQL:jdbc:mysql://
ORACLE:jdbc:oracle:thin:@
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; 小結 JDBC操作資料庫步驟概述如下: 1.註冊載入驅動類
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
138 Connection conn = JdbcUtil.getConnection;
139 PreparedStatement ps = null;
140 ResultSet rs = null;
141 List
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 }
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美國製造夢