CRUD是網頁執行最基礎的四個操作,本文會教大家如何應用JDBC執行CRUD操作
資料庫介紹
我自己的專題使用的是台灣銀行匯率資料庫,下載csv後可以發現官方檔案的欄位有很多,這個專題只會使用即期匯率跟現金匯率。
首先先在 SQL server 加入 exchangeRate 資料庫,這邊我將幣別與日期設為共同主鍵,確保資料不會重複。
1
2
3
4
5
6
7
8
9
CREATE TABLE [exchangeRate](
name NVARCHAR(50) NOT NULL, --幣別
date DATE NOT NULL, --日期
buy_cash decimal(10,5), --現金買入
buy_spot decimal(10,5), --現金賣出
sell_cash decimal(10,5), --即期買入
sell_spot decimal(10,5) --即期賣出
CONSTRAINT name_date_PK PRIMARY KEY (name,date)
)
建立匯率物件
為了方便操作資料,我會先建立一個匯率的 model ,內容如下:
1
2
3
4
5
6
7
8
public class ExchangeRate {
private String name;
private Date date = null;
private Float buyCash;
private Float buySpot;
private Float sellCash;
private Float sellSpot;
}
後面再加上每個屬性的 getter & setter
操作CRUD
這邊使用 DAO(Data Access Objects) 模式,將資料庫相關操作封裝起來,先測試是否能成功操作基本CRUD後再進行下一步設計
基本步驟
- 建立SQL語句
- 建立connection
- 建立statement(statement/prepareStatement),因為prepareStatement基本上可以覆蓋statement的使用範圍,本次專題只會使用prepareStatement
- 將sql語句放入statement中
- 如果是prepareStatement,把變數放進sql語句中
- 視需求將prepareStatement加入batch
- 執行
- 如果是查詢需要取得回傳的resultSet
- 關閉資源
新增、修改、刪除
以上三個功能其實基本概念都一樣,這邊使用新增來當作範例,因為這裡輸入是直接用ExchangeRate的List,代表一次會執行多筆插入,所以也會示範使用Batch的方式以節省時間。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public void InsertExchangeRate(List<ExchangeRate> erList) {
//建立SQL語句,這邊先判斷插入的資料是否重複,若沒有重複則insert
//問號的地方是prepareStatement需要加入變數的位置
String sql = "IF NOT EXISTS (SELECT * FROM exchangeRate WHERE (name = ? AND date = ?)) BEGIN INSERT INTO exchangeRate VALUES (?,?,?,?,?,?)END";
//因為connection和prepareStatement會需要包在try裡面並且在finally的地方關閉,故需要在外面先宣告
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
//建立connection及prepareStatement
connection = C3p0Util.getConnection();
preparedStatement = connection.prepareStatement(sql);
//將list的物件取出,加入prepareStatement
for(ExchangeRate er : erList) {
//代表第一個問號加入er的name(對應資料庫第一欄)
preparedStatement.setString(1, er.getName());
//因為當日資料不會在csv中寫日期,也就是說建立物件時可能不會有日期,所以多新增一個判斷式將今天的日期手動加入
if(er.getDate()!=null) {
preparedStatement.setDate(2, er.getDate());
}else {
preparedStatement.setDate(2, java.sql.Date.valueOf(LocalDate.now()));
}
preparedStatement.setString(3, er.getName());
if(er.getDate()!=null) {
preparedStatement.setDate(4, er.getDate());
}else {
preparedStatement.setDate(4, java.sql.Date.valueOf(LocalDate.now()));
}
//繼續加變數
preparedStatement.setFloat(5, er.getBuyCash());
preparedStatement.setFloat(6, er.getBuySpot());
preparedStatement.setFloat(7, er.getSellCash());
preparedStatement.setFloat(8, er.getSellSpot());
//將prepareStatement加入batch中
preparedStatement.addBatch();
}
//執行batch,因為大部分情況資料庫匯入只有幾十到幾百筆,故只執行一次,若筆數過多也可以使用判斷式設定每多少筆執行一次
//若不使用batch則需使用execute指令,一次執行一筆新增
preparedStatement.executeBatch();
//執行完後清空batch
preparedStatement.clearBatch();
//顯示執行成功
System.out.println("新增成功");
} catch (SQLException e) {
e.printStackTrace();
}finally {
//最後將connection和prepareStatement關閉
C3p0Util.release(connection, preparedStatement);
}
}
而修改刪除邏輯相似,基本上只要依需求修改SQL指令及batch的部分即可。
查詢
查詢語句較不一樣的地方是執行時需要使用executeQuery,且會回傳resultSet,需要將resultSet中的資料進行整理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public List<ExchangeRate> selectAll() {
//以下步驟同增刪改,但需要多一個resultSet去接住回傳的資料
String sql = "SELECT * FROM exchangeRate ORDER BY name,date";
ResultSet resultSet = null;
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = C3p0Util.getConnection();
preparedStatement = connection.prepareStatement(sql);
//執行時需使用executeQuery
resultSet = preparedStatement.executeQuery();
//建立準備回傳的list
List<ExchangeRate> list = new ArrayList<ExchangeRate>();
//當有下一筆resultSet時讀取下一筆
while (resultSet.next()) {
//建立匯率物件
ExchangeRate exchangeRate = new ExchangeRate();
//設定屬性值,依據不同型別使用getXXX,括號內可以放第幾欄或欄位名稱(此處使用第幾欄做示範)
exchangeRate.setName(resultSet.getString(1));
exchangeRate.setDate(resultSet.getDate(2));
exchangeRate.setBuyCash(resultSet.getFloat(3));
exchangeRate.setBuySpot(resultSet.getFloat(4));
exchangeRate.setSellCash(resultSet.getFloat(5));
exchangeRate.setSellSpot(resultSet.getFloat(6));
//將匯率加入list中
list.add(exchangeRate);
}
//回傳list
return list;
} catch (SQLException e) {
e.printStackTrace();
}finally {
//關閉資源
C3p0Util.release(connection, preparedStatement, resultSet);
}
//若失敗則回傳null
return null;
}
有了基本的CRUD後,接下來就是依需求自行增加更多的DAO操作,下一篇會介紹整個專題的資料流程及爬蟲相關內容。
