<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="https://tcwsunny.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://tcwsunny.github.io/" rel="alternate" type="text/html" /><updated>2024-05-08T16:41:29+00:00</updated><id>https://tcwsunny.github.io/feed.xml</id><title type="html">Sunny的轉職筆記</title><subtitle>從寫C++跨來寫Java的(微)轉職新手
</subtitle><entry><title type="html">《JDBC專題》4. 資料處理與簡易Jsoup爬蟲</title><link href="https://tcwsunny.github.io/2024/05/08/jsoup-data" rel="alternate" type="text/html" title="《JDBC專題》4. 資料處理與簡易Jsoup爬蟲" /><published>2024-05-08T19:06:00+00:00</published><updated>2024-05-08T19:06:00+00:00</updated><id>https://tcwsunny.github.io/2024/05/08/jsoup-data</id><content type="html" xml:base="https://tcwsunny.github.io/2024/05/08/jsoup-data"><![CDATA[<blockquote>
  <p>本文會介紹此專題讀取資料的方法，以及如何運用簡易爬蟲抓取匯率資料</p>
</blockquote>

<p>以下圖片是這個專題的架構，在前面的文章中，我們已經完成了model、util及DAO的建置，接著會介紹我如何取得資料。</p>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-08-jsoup-data-res\image.png?raw=true" alt="架構" />
<img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-08-jsoup-data-res\flowChart.png?raw=true" alt="流程圖" /></p>

<h2 id="getdata">getData</h2>

<p>這個class的主要目的在於取得資料中的文字，並且以字串形式回傳，這個專題的輸入資料支援當日匯率csv、自行輸出的json、爬蟲取得的單日資料及單一匯率資料。</p>

<h3 id="csv">CSV</h3>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre><span class="kd">public</span> <span class="kd">static</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="nf">getCsvData</span><span class="o">(</span><span class="nc">String</span> <span class="n">dataPath</span><span class="o">)</span> <span class="o">{</span>

    <span class="c1">//建立inputStream，並以bufferReader加快讀取速度</span>
    <span class="nc">FileInputStream</span> <span class="n">fileInputStream</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="nc">InputStreamReader</span> <span class="n">inputStreamReader</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="nc">BufferedReader</span> <span class="n">bufferedReader</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;();</span>
    <span class="k">try</span> <span class="o">{</span>
        <span class="n">fileInputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileInputStream</span><span class="o">(</span><span class="k">new</span> <span class="nc">File</span><span class="o">(</span><span class="n">dataPath</span><span class="o">));</span>
        <span class="n">inputStreamReader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">fileInputStream</span><span class="o">);</span>
        <span class="n">bufferedReader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="n">inputStreamReader</span><span class="o">);</span>

        <span class="c1">//當bufferReader準備好後，就可以將內容放進list中</span>
        <span class="k">while</span><span class="o">(</span><span class="n">bufferedReader</span><span class="o">.</span><span class="na">ready</span><span class="o">())</span> <span class="o">{</span>
            <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">bufferedReader</span><span class="o">.</span><span class="na">readLine</span><span class="o">());</span>
        <span class="o">}</span>

        <span class="c1">//因為第一行會讀到標題，所以將首行移除</span>
        <span class="n">list</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">FileNotFoundException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span><span class="k">finally</span> <span class="o">{</span>
        <span class="k">try</span> <span class="o">{</span>
            <span class="n">fileInputStream</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
            <span class="n">inputStreamReader</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
            <span class="n">bufferedReader</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
        <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
            <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
        <span class="o">}</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">list</span><span class="o">;</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>這樣就會回傳一個字串list，其中一個string代表一筆資料，不同欄位之間使用逗號隔開，就可以傳入service進行處理。</p>

<h3 id="json">JSON</h3>

<p>這邊IO的方法會和上面不太一樣，是我刻意練習不同方式實作，其實兩種是可以互通的。</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span> <span class="nf">getJsonData</span><span class="o">(</span><span class="nc">String</span> <span class="n">dataPath</span><span class="o">)</span> <span class="o">{</span>

    <span class="c1">//建立一個stringBuilder</span>
    <span class="nc">StringBuilder</span> <span class="n">jsonBuilder</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuilder</span><span class="o">();</span>

    <span class="c1">//這邊把IO放進括號，try結束時會auto close，不需要另外關閉</span>
    <span class="k">try</span> <span class="o">(</span><span class="nc">FileInputStream</span> <span class="n">fileInputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileInputStream</span><span class="o">(</span><span class="k">new</span> <span class="nc">File</span><span class="o">(</span><span class="n">dataPath</span><span class="o">));</span>
        <span class="nc">InputStreamReader</span> <span class="n">inputStreamReader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">fileInputStream</span><span class="o">);</span>
        <span class="nc">BufferedReader</span> <span class="n">bufferedReader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="n">inputStreamReader</span><span class="o">)){</span>

        <span class="c1">//把json檔全部放進一個字串中</span>
        <span class="nc">String</span> <span class="n">line</span><span class="o">;</span>
        <span class="k">while</span> <span class="o">((</span><span class="n">line</span> <span class="o">=</span> <span class="n">bufferedReader</span><span class="o">.</span><span class="na">readLine</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
            <span class="n">jsonBuilder</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">line</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">jsonBuilder</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>這樣就可以產生一整個Json字串，之後再將字串使用GSON解析即可（這部分會在service介紹）。</p>

<h3 id="jsoup爬蟲">Jsoup爬蟲</h3>

<p>這邊會分為兩個含式，getNowData是爬取當日資料，而getPastData則是爬單一幣別整個月的資料（datTime為月份、name不為空）或是過去的單日資料（datTime為日期、name為空字串）。</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre><span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span><span class="o">[]</span> <span class="nf">getNowData</span><span class="o">()</span> <span class="o">{</span>
    <span class="nc">String</span><span class="o">[]</span> <span class="n">dataList</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="k">try</span> <span class="o">{</span>

        <span class="c1">//使用Jsoup抓取網路資料</span>
        <span class="nc">Document</span> <span class="n">document</span> <span class="o">=</span> <span class="nc">Jsoup</span><span class="o">.</span><span class="na">connect</span><span class="o">(</span><span class="s">"https://rate.bot.com.tw/xrt/flcsv/0/day"</span><span class="o">).</span><span class="na">get</span><span class="o">();</span>

        <span class="c1">//print出來後可以發現資料都包在body中，所以使用body().text()取出內部文字</span>
        <span class="c1">//&lt;html&gt;</span>
        <span class="c1">//    &lt;head&gt;&lt;/head&gt;</span>
        <span class="c1">//    &lt;body&gt;</span>
        <span class="c1">//        幣別,匯率,現金,即期,遠期10天...</span>
        <span class="c1">//    &lt;/body&gt;</span>
        <span class="c1">//&lt;/html&gt;</span>
        <span class="nc">String</span> <span class="n">body</span> <span class="o">=</span> <span class="n">document</span><span class="o">.</span><span class="na">body</span><span class="o">().</span><span class="na">text</span><span class="o">();</span>

        <span class="c1">//因為在不同筆中間是用空格隔開，因此使用split就可以將字串轉換為String的陣列</span>
        <span class="n">dataList</span> <span class="o">=</span> <span class="n">body</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">" "</span><span class="o">);</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">dataList</span><span class="o">;</span>
<span class="o">}</span>

<span class="c1">//getPastData也是使用一樣的方法，只是爬取網址不同</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">String</span><span class="o">[]</span> <span class="nf">getPastData</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="nc">String</span> <span class="n">dayTime</span><span class="o">)</span> <span class="o">{</span>
    <span class="nc">String</span><span class="o">[]</span> <span class="n">dataList</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="k">try</span> <span class="o">{</span>
        <span class="nc">Document</span> <span class="n">document</span> <span class="o">=</span> <span class="nc">Jsoup</span><span class="o">.</span><span class="na">connect</span><span class="o">(</span><span class="s">"https://rate.bot.com.tw/xrt/flcsv/0/"</span><span class="o">+</span><span class="n">dayTime</span><span class="o">+</span><span class="s">"/"</span><span class="o">+</span><span class="n">name</span><span class="o">).</span><span class="na">get</span><span class="o">();</span>
        <span class="nc">String</span> <span class="n">body</span> <span class="o">=</span> <span class="n">document</span><span class="o">.</span><span class="na">body</span><span class="o">().</span><span class="na">text</span><span class="o">();</span>
        <span class="n">dataList</span> <span class="o">=</span> <span class="n">body</span><span class="o">.</span><span class="na">split</span><span class="o">(</span><span class="s">" "</span><span class="o">);</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
    <span class="k">return</span> <span class="n">dataList</span><span class="o">;</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>這樣就可以回傳String陣列，再使用service處理相應的格式變成物件即可。</p>

<p>取得資料後，下一篇會分享我如何將回傳的資料轉換為物件。</p>]]></content><author><name></name></author><category term="coding" /><category term="JDBC" /><summary type="html"><![CDATA[本文會介紹此專題讀取資料的方法，以及如何運用簡易爬蟲抓取匯率資料]]></summary></entry><entry><title type="html">《JDBC專題》3. 製作CRUD功能</title><link href="https://tcwsunny.github.io/2024/05/06/using-CRUD" rel="alternate" type="text/html" title="《JDBC專題》3. 製作CRUD功能" /><published>2024-05-06T23:33:00+00:00</published><updated>2024-05-06T23:33:00+00:00</updated><id>https://tcwsunny.github.io/2024/05/06/using-CRUD</id><content type="html" xml:base="https://tcwsunny.github.io/2024/05/06/using-CRUD"><![CDATA[<blockquote>
  <p>CRUD是網頁執行最基礎的四個操作，本文會教大家如何應用JDBC執行CRUD操作</p>
</blockquote>

<h2 id="資料庫介紹">資料庫介紹</h2>

<p>我自己的專題使用的是<a href="https://rate.bot.com.tw/xrt?Lang=zh-TW">台灣銀行匯率資料庫</a>，下載csv後可以發現官方檔案的欄位有很多，這個專題只會使用即期匯率跟現金匯率。</p>

<p>首先先在 SQL server 加入 exchangeRate 資料庫，這邊我將幣別與日期設為共同主鍵，確保資料不會重複。</p>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="p">[</span><span class="n">exchangeRate</span><span class="p">](</span>
    <span class="n">name</span> <span class="n">NVARCHAR</span><span class="p">(</span><span class="mi">50</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span> <span class="c1">--幣別</span>
    <span class="nb">date</span> <span class="nb">DATE</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span> <span class="c1">--日期</span>
    <span class="n">buy_cash</span> <span class="nb">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="c1">--現金買入</span>
    <span class="n">buy_spot</span> <span class="nb">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="c1">--現金賣出</span>
    <span class="n">sell_cash</span> <span class="nb">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="c1">--即期買入</span>
    <span class="n">sell_spot</span> <span class="nb">decimal</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span> <span class="c1">--即期賣出</span>
    <span class="k">CONSTRAINT</span> <span class="n">name_date_PK</span> <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="nb">date</span><span class="p">)</span>
<span class="p">)</span>
</pre></td></tr></tbody></table></code></pre></figure>

<h2 id="建立匯率物件">建立匯率物件</h2>

<p>為了方便操作資料，我會先建立一個匯率的 model ，內容如下：</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ExchangeRate</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Date</span> <span class="n">date</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Float</span> <span class="n">buyCash</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Float</span> <span class="n">buySpot</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Float</span> <span class="n">sellCash</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Float</span> <span class="n">sellSpot</span><span class="o">;</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>後面再加上每個屬性的 getter &amp; setter</p>

<h2 id="操作crud">操作CRUD</h2>

<p>這邊使用 DAO(Data Access Objects) 模式，將資料庫相關操作封裝起來，先測試是否能成功操作基本CRUD後再進行下一步設計</p>

<h3 id="基本步驟">基本步驟</h3>

<ol>
  <li>建立SQL語句</li>
  <li>建立connection</li>
  <li>建立statement（statement/prepareStatement)，因為prepareStatement基本上可以覆蓋statement的使用範圍，本次專題只會使用prepareStatement</li>
  <li>將sql語句放入statement中</li>
  <li>如果是prepareStatement，把變數放進sql語句中</li>
  <li>視需求將prepareStatement加入batch</li>
  <li>執行</li>
  <li>如果是查詢需要取得回傳的resultSet</li>
  <li>關閉資源</li>
</ol>

<h3 id="新增修改刪除">新增、修改、刪除</h3>

<p>以上三個功能其實基本概念都一樣，這邊使用新增來當作範例，因為這裡輸入是直接用ExchangeRate的List，代表一次會執行多筆插入，所以也會示範使用Batch的方式以節省時間。</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre><span class="kd">public</span> <span class="kt">void</span> <span class="nf">InsertExchangeRate</span><span class="o">(</span><span class="nc">List</span><span class="o">&lt;</span><span class="nc">ExchangeRate</span><span class="o">&gt;</span> <span class="n">erList</span><span class="o">)</span> <span class="o">{</span>

    <span class="c1">//建立SQL語句，這邊先判斷插入的資料是否重複，若沒有重複則insert</span>
    <span class="c1">//問號的地方是prepareStatement需要加入變數的位置</span>
    <span class="nc">String</span> <span class="n">sql</span> <span class="o">=</span> <span class="s">"IF NOT EXISTS (SELECT * FROM exchangeRate WHERE (name = ? AND date = ?)) BEGIN INSERT INTO exchangeRate VALUES (?,?,?,?,?,?)END"</span><span class="o">;</span>

    <span class="c1">//因為connection和prepareStatement會需要包在try裡面並且在finally的地方關閉，故需要在外面先宣告</span>
    <span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="nc">PreparedStatement</span> <span class="n">preparedStatement</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>

    <span class="k">try</span> <span class="o">{</span>

        <span class="c1">//建立connection及prepareStatement</span>
        <span class="n">connection</span> <span class="o">=</span> <span class="nc">C3p0Util</span><span class="o">.</span><span class="na">getConnection</span><span class="o">();</span>
        <span class="n">preparedStatement</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="na">prepareStatement</span><span class="o">(</span><span class="n">sql</span><span class="o">);</span>

        <span class="c1">//將list的物件取出，加入prepareStatement</span>
        <span class="k">for</span><span class="o">(</span><span class="nc">ExchangeRate</span> <span class="n">er</span> <span class="o">:</span> <span class="n">erList</span><span class="o">)</span> <span class="o">{</span>

            <span class="c1">//代表第一個問號加入er的name(對應資料庫第一欄)</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setString</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>

            <span class="c1">//因為當日資料不會在csv中寫日期，也就是說建立物件時可能不會有日期，所以多新增一個判斷式將今天的日期手動加入</span>
            <span class="k">if</span><span class="o">(</span><span class="n">er</span><span class="o">.</span><span class="na">getDate</span><span class="o">()!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
                <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getDate</span><span class="o">());</span>
            <span class="o">}</span><span class="k">else</span> <span class="o">{</span>
                <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">sql</span><span class="o">.</span><span class="na">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="nc">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">()));</span>
            <span class="o">}</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setString</span><span class="o">(</span><span class="mi">3</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>
            <span class="k">if</span><span class="o">(</span><span class="n">er</span><span class="o">.</span><span class="na">getDate</span><span class="o">()!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
                <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="mi">4</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getDate</span><span class="o">());</span>
            <span class="o">}</span><span class="k">else</span> <span class="o">{</span>
                <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="mi">4</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">sql</span><span class="o">.</span><span class="na">Date</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="nc">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">()));</span>
            <span class="o">}</span>

            <span class="c1">//繼續加變數</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setFloat</span><span class="o">(</span><span class="mi">5</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getBuyCash</span><span class="o">());</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setFloat</span><span class="o">(</span><span class="mi">6</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getBuySpot</span><span class="o">());</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setFloat</span><span class="o">(</span><span class="mi">7</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getSellCash</span><span class="o">());</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">setFloat</span><span class="o">(</span><span class="mi">8</span><span class="o">,</span> <span class="n">er</span><span class="o">.</span><span class="na">getSellSpot</span><span class="o">());</span>

            <span class="c1">//將prepareStatement加入batch中</span>
            <span class="n">preparedStatement</span><span class="o">.</span><span class="na">addBatch</span><span class="o">();</span>
        <span class="o">}</span>

        <span class="c1">//執行batch，因為大部分情況資料庫匯入只有幾十到幾百筆，故只執行一次，若筆數過多也可以使用判斷式設定每多少筆執行一次</span>
        <span class="c1">//若不使用batch則需使用execute指令，一次執行一筆新增</span>
        <span class="n">preparedStatement</span><span class="o">.</span><span class="na">executeBatch</span><span class="o">();</span>

        <span class="c1">//執行完後清空batch</span>
        <span class="n">preparedStatement</span><span class="o">.</span><span class="na">clearBatch</span><span class="o">();</span>

        <span class="c1">//顯示執行成功</span>
        <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"新增成功"</span><span class="o">);</span>

    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span><span class="k">finally</span> <span class="o">{</span>

        <span class="c1">//最後將connection和prepareStatement關閉</span>
        <span class="nc">C3p0Util</span><span class="o">.</span><span class="na">release</span><span class="o">(</span><span class="n">connection</span><span class="o">,</span> <span class="n">preparedStatement</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>而修改刪除邏輯相似，基本上只要依需求修改SQL指令及batch的部分即可。</p>

<h3 id="查詢">查詢</h3>

<p>查詢語句較不一樣的地方是執行時需要使用executeQuery，且會回傳resultSet，需要將resultSet中的資料進行整理。</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre><span class="kd">public</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">ExchangeRate</span><span class="o">&gt;</span> <span class="nf">selectAll</span><span class="o">()</span> <span class="o">{</span>

    <span class="c1">//以下步驟同增刪改，但需要多一個resultSet去接住回傳的資料</span>
    <span class="nc">String</span> <span class="n">sql</span> <span class="o">=</span> <span class="s">"SELECT * FROM exchangeRate ORDER BY name,date"</span><span class="o">;</span>
    <span class="nc">ResultSet</span> <span class="n">resultSet</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="nc">PreparedStatement</span> <span class="n">preparedStatement</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
    <span class="k">try</span> <span class="o">{</span>
        <span class="n">connection</span> <span class="o">=</span> <span class="nc">C3p0Util</span><span class="o">.</span><span class="na">getConnection</span><span class="o">();</span>
        <span class="n">preparedStatement</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="na">prepareStatement</span><span class="o">(</span><span class="n">sql</span><span class="o">);</span>

        <span class="c1">//執行時需使用executeQuery</span>
        <span class="n">resultSet</span> <span class="o">=</span> <span class="n">preparedStatement</span><span class="o">.</span><span class="na">executeQuery</span><span class="o">();</span>

        <span class="c1">//建立準備回傳的list</span>
        <span class="nc">List</span><span class="o">&lt;</span><span class="nc">ExchangeRate</span><span class="o">&gt;</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;</span><span class="nc">ExchangeRate</span><span class="o">&gt;();</span>

        <span class="c1">//當有下一筆resultSet時讀取下一筆</span>
        <span class="k">while</span> <span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">next</span><span class="o">())</span> <span class="o">{</span>

            <span class="c1">//建立匯率物件</span>
            <span class="nc">ExchangeRate</span> <span class="n">exchangeRate</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ExchangeRate</span><span class="o">();</span>

            <span class="c1">//設定屬性值，依據不同型別使用getXXX，括號內可以放第幾欄或欄位名稱（此處使用第幾欄做示範）</span>
            <span class="n">exchangeRate</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="mi">1</span><span class="o">));</span>
            <span class="n">exchangeRate</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">getDate</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span>
            <span class="n">exchangeRate</span><span class="o">.</span><span class="na">setBuyCash</span><span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">getFloat</span><span class="o">(</span><span class="mi">3</span><span class="o">));</span>
            <span class="n">exchangeRate</span><span class="o">.</span><span class="na">setBuySpot</span><span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">getFloat</span><span class="o">(</span><span class="mi">4</span><span class="o">));</span>
            <span class="n">exchangeRate</span><span class="o">.</span><span class="na">setSellCash</span><span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">getFloat</span><span class="o">(</span><span class="mi">5</span><span class="o">));</span>
            <span class="n">exchangeRate</span><span class="o">.</span><span class="na">setSellSpot</span><span class="o">(</span><span class="n">resultSet</span><span class="o">.</span><span class="na">getFloat</span><span class="o">(</span><span class="mi">6</span><span class="o">));</span>

            <span class="c1">//將匯率加入list中</span>
            <span class="n">list</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">exchangeRate</span><span class="o">);</span>
        <span class="o">}</span>

        <span class="c1">//回傳list</span>
        <span class="k">return</span> <span class="n">list</span><span class="o">;</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span><span class="k">finally</span> <span class="o">{</span>

        <span class="c1">//關閉資源</span>
        <span class="nc">C3p0Util</span><span class="o">.</span><span class="na">release</span><span class="o">(</span><span class="n">connection</span><span class="o">,</span> <span class="n">preparedStatement</span><span class="o">,</span> <span class="n">resultSet</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="c1">//若失敗則回傳null</span>
    <span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>有了基本的CRUD後，接下來就是依需求自行增加更多的DAO操作，下一篇會介紹整個專題的資料流程及爬蟲相關內容。</p>]]></content><author><name></name></author><category term="coding" /><category term="JDBC" /><summary type="html"><![CDATA[CRUD是網頁執行最基礎的四個操作，本文會教大家如何應用JDBC執行CRUD操作]]></summary></entry><entry><title type="html">《JDBC專題》2. 使用java與SQL server建立連結</title><link href="https://tcwsunny.github.io/2024/05/03/get-connection" rel="alternate" type="text/html" title="《JDBC專題》2. 使用java與SQL server建立連結" /><published>2024-05-03T00:24:00+00:00</published><updated>2024-05-03T00:24:00+00:00</updated><id>https://tcwsunny.github.io/2024/05/03/get-connection</id><content type="html" xml:base="https://tcwsunny.github.io/2024/05/03/get-connection"><![CDATA[<blockquote>
  <p>在執行SQL語句前需要建立Connection和Statement，這篇會介紹建立connection的2種方法：直接建立connection及connection pool</p>
</blockquote>

<p>實作這一篇之前請先確認系統設定都正確，還沒設定的請看<a href="https://tcwsunny.github.io/2024/05/01/jdbc-setting">上一篇</a></p>

<h2 id="建立connection直接連線">建立connection：直接連線</h2>

<p>在建立connection時需要前一篇設定的帳號密碼進行登入，因為這個功能之後會很常用到，所以建議直接建一個工具class，在裡面新增static函式</p>

<h3 id="首先需要建立一個preperties檔">首先需要建立一個preperties檔</h3>

<p>檔名叫XXXX.properties(範例叫jdbc.properties)，裡面放url、user和password三個參數</p>

<figure class="highlight"><pre><code class="language-properties" data-lang="properties"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="code"><pre>  <span class="py">url</span><span class="p">=</span><span class="s">jdbc:sqlserver://localhost:1433;DatabaseName=你的資料庫名稱;encrypt = false</span>
  <span class="py">user</span><span class="p">=</span><span class="s">帳號名稱</span>
  <span class="py">password</span><span class="p">=</span><span class="s">你的密碼</span>
  
</pre></td></tr></tbody></table></code></pre></figure>

<p>建在properties是為了讓其他使用者更方便修改，不然讓別人動code是一件有點危險的事，如果沒有這個需求也可以直接寫在code裡面</p>

<h3 id="開始建立connection程式如下">開始建立connection，程式如下</h3>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre>  <span class="kd">public</span> <span class="kd">class</span> <span class="nc">JDBCutil</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Connection</span> <span class="nf">getConnection</span><span class="o">()</span> <span class="o">{</span>
      <span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
      <span class="nc">FileInputStream</span> <span class="n">fileInputStream</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
      <span class="k">try</span> <span class="o">{</span>
        <span class="c1">//註冊JDBC驅動程式</span>
        <span class="nc">Class</span><span class="o">.</span><span class="na">forName</span><span class="o">(</span><span class="s">"com.microsoft.sqlserver.jdbc.SQLServerDriver"</span><span class="o">);</span>

        <span class="c1">//讀properties檔案，取出帳號密碼</span>
        <span class="nc">Properties</span> <span class="n">properties</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Properties</span><span class="o">();</span>
        <span class="n">fileInputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FileInputStream</span><span class="o">(</span><span class="k">new</span> <span class="nc">File</span><span class="o">(</span><span class="s">"你的properties位置"</span><span class="o">));</span>
        <span class="n">properties</span><span class="o">.</span><span class="na">load</span><span class="o">(</span><span class="n">fileInputStream</span><span class="o">);</span>
        <span class="nc">String</span> <span class="n">url</span> <span class="o">=</span> <span class="n">properties</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"url"</span><span class="o">);</span>
        <span class="nc">String</span> <span class="n">user</span> <span class="o">=</span> <span class="n">properties</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"user"</span><span class="o">);</span>
        <span class="nc">String</span> <span class="n">password</span> <span class="o">=</span> <span class="n">properties</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"password"</span><span class="o">);</span>

        <span class="c1">//建立connection</span>
        <span class="n">connection</span> <span class="o">=</span> <span class="nc">DriverManager</span><span class="o">.</span><span class="na">getConnection</span><span class="o">(</span><span class="n">url</span><span class="o">,</span><span class="n">user</span><span class="o">,</span><span class="n">password</span><span class="o">);</span>

        <span class="c1">//確認connection是否連線</span>
        <span class="kt">boolean</span> <span class="n">status</span> <span class="o">=</span> <span class="o">!</span><span class="n">connection</span><span class="o">.</span><span class="na">isClosed</span><span class="o">();</span>
        <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"連線狀態"</span><span class="o">+</span><span class="n">status</span><span class="o">);</span>
      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">ClassNotFoundException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">FileNotFoundException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
      <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
      <span class="o">}</span><span class="k">finally</span> <span class="o">{</span>
        <span class="c1">//關閉fileInputString</span>
        <span class="k">try</span> <span class="o">{</span>
          <span class="n">fileInputStream</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
        <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
          <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
        <span class="o">}</span>
      <span class="o">}</span>
      <span class="k">return</span> <span class="n">connection</span><span class="o">;</span>
    <span class="o">}</span>
  <span class="o">}</span>
  
</pre></td></tr></tbody></table></code></pre></figure>

<h3 id="在使用完connection後需要關閉連線">在使用完connection後需要關閉連線</h3>

<p>可以在工具class底下新增closeResource()，這邊我會使用overload的方式把statement和resultset(請見下篇)的關閉函式一起寫好</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre>  <span class="nc">Statement</span> <span class="n">statement</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
  <span class="nc">ResultSet</span> <span class="n">resultSet</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> 
  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">closeResource</span><span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">if</span><span class="o">(</span><span class="n">connection</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">connection</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
  <span class="o">}</span>
  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">closeResource</span><span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span><span class="o">,</span><span class="nc">Statement</span> <span class="n">statement</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">if</span><span class="o">(</span><span class="n">connection</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">connection</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
      <span class="k">if</span><span class="o">(</span><span class="n">statement</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">statement</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
  <span class="o">}</span>
  
  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">closeResource</span><span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span><span class="o">,</span><span class="nc">Statement</span> <span class="n">statement</span><span class="o">,</span><span class="nc">ResultSet</span> <span class="n">resultSet</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">if</span><span class="o">(</span><span class="n">connection</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">connection</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
      <span class="k">if</span><span class="o">(</span><span class="n">statement</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">statement</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
      <span class="k">if</span><span class="o">(</span><span class="n">resultSet</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">resultSet</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
  <span class="o">}</span>
  
</pre></td></tr></tbody></table></code></pre></figure>

<h3 id="在main裡面呼叫函式jdbcutilgetconnection">在main裡面呼叫函式JDBCutil.getConnection()</h3>

<p>執行後如果看到”連線狀態true”表示連線成功</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="code"><pre>  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
    <span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="nc">JDBCUtil</span><span class="o">.</span><span class="na">getConnection</span><span class="o">();</span>
    <span class="nc">JDBCUtil</span><span class="o">.</span><span class="na">closeResource</span><span class="o">(</span><span class="n">connection</span><span class="o">);</span>
  <span class="o">}</span>
  
</pre></td></tr></tbody></table></code></pre></figure>

<h2 id="建立connection連接池connection-pool">建立Connection：連接池(Connection pool)</h2>

<p>連接池是在系統執行時建立多個連結，需要用時把連結拿來使用，用完後再放回池子中，而連接池也是我在這次專題中主要使用的方法，以下code是示範連接池工具中如何getConnection，使用的是c3p0套件</p>

<blockquote>
  <p><a href="https://www.mchange.com/projects/c3p0/">下載連結</a>：滑到下面installation下載c3p0–0.10.0.jar 和mchange-commons-java-0.3.0.jar(有最新版就下載最新版)，然後加到build path中</p>
</blockquote>

<h3 id="以下是getconnection的實作方式">以下是getConnection的實作方式</h3>

<p>可以看到我在openDataSource中開了一個連接池，並將帳號密碼設定好，接著用一個變數代表連接池(dataSource)，然後在getConnection的地方把connection取出並回傳，這裡我直接把exception丟出，如果要在函式中直接try catch也是可以。</p>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre>  <span class="kd">public</span> <span class="kd">static</span> <span class="nc">ComboPooledDataSource</span> <span class="nf">openDataSource</span><span class="o">()</span> <span class="o">{</span>
    <span class="c1">//連接池設定</span>
    <span class="nc">ComboPooledDataSource</span> <span class="n">cpds</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ComboPooledDataSource</span><span class="o">();</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="n">cpds</span><span class="o">.</span><span class="na">setDriverClass</span><span class="o">(</span> <span class="s">"com.microsoft.sqlserver.jdbc.SQLServerDriver"</span> <span class="o">);</span>
      <span class="n">cpds</span><span class="o">.</span><span class="na">setJdbcUrl</span><span class="o">(</span> <span class="s">"jdbc:sqlserver://localhost:1433;DatabaseName=資料庫名稱;encrypt=false"</span> <span class="o">);</span>
      <span class="n">cpds</span><span class="o">.</span><span class="na">setUser</span><span class="o">(</span><span class="s">"帳號"</span><span class="o">);</span>
      <span class="n">cpds</span><span class="o">.</span><span class="na">setPassword</span><span class="o">(</span><span class="s">"密碼"</span><span class="o">);</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">PropertyVetoException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
      <span class="k">return</span> <span class="n">cpds</span><span class="o">;</span>
    <span class="o">}</span>
  
    <span class="kd">private</span> <span class="kd">static</span> <span class="nc">ComboPooledDataSource</span> <span class="n">dataSource</span> <span class="o">=</span> <span class="nc">C3p0Util</span><span class="o">.</span><span class="na">openDataSource</span><span class="o">();</span>
  
    <span class="kd">public</span> <span class="kd">static</span> <span class="nc">Connection</span> <span class="nf">getConnection</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">SQLException</span> <span class="o">{</span>
      <span class="k">return</span> <span class="n">dataSource</span><span class="o">.</span><span class="na">getConnection</span><span class="o">();</span>
    <span class="o">}</span>
  
</pre></td></tr></tbody></table></code></pre></figure>

<h3 id="然後就是關連結的函式一樣使用overload">然後就是關連結的函式，一樣使用overload</h3>

<figure class="highlight"><pre><code class="language-java" data-lang="java"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">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
</pre></td><td class="code"><pre>  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">release</span><span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">if</span><span class="o">(</span><span class="n">connection</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">connection</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
    <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
  <span class="o">}</span>
  
  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">release</span><span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span><span class="o">,</span><span class="nc">Statement</span> <span class="n">statement</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">if</span><span class="o">(</span><span class="n">connection</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">connection</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
      <span class="k">if</span><span class="o">(</span><span class="n">statement</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">statement</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
  <span class="o">}</span>
  
  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">release</span><span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span><span class="o">,</span><span class="nc">Statement</span> <span class="n">statement</span><span class="o">,</span><span class="nc">ResultSet</span> <span class="n">resultSet</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">try</span> <span class="o">{</span>
      <span class="k">if</span><span class="o">(</span><span class="n">connection</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">connection</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
      <span class="k">if</span><span class="o">(</span><span class="n">statement</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">statement</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
      <span class="k">if</span><span class="o">(</span><span class="n">resultSet</span><span class="o">!=</span><span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">resultSet</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
      <span class="o">}</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">SQLException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
    <span class="o">}</span>
  <span class="o">}</span>
  
</pre></td></tr></tbody></table></code></pre></figure>

<p>測試連線成功後就可以開始建statement和跑SQL程式了!!!(下篇待續)</p>]]></content><author><name></name></author><category term="coding" /><category term="JDBC" /><summary type="html"><![CDATA[在執行SQL語句前需要建立Connection和Statement，這篇會介紹建立connection的2種方法：直接建立connection及connection pool]]></summary></entry><entry><title type="html">《JDBC專題》1. 系統設定：使用JDBC的前置作業</title><link href="https://tcwsunny.github.io/2024/05/01/jdbc-setting" rel="alternate" type="text/html" title="《JDBC專題》1. 系統設定：使用JDBC的前置作業" /><published>2024-05-01T22:35:00+00:00</published><updated>2024-05-01T22:35:00+00:00</updated><id>https://tcwsunny.github.io/2024/05/01/jdbc-setting</id><content type="html" xml:base="https://tcwsunny.github.io/2024/05/01/jdbc-setting"><![CDATA[<blockquote>
  <p>JDBC提供API讓JAVA使用者能夠透過程式訪問資料庫，這篇文章是在說明撰寫JDBC前的系統設定，step by step 教你如何設定資料庫與防火牆</p>
</blockquote>

<h2 id="事前準備">事前準備</h2>

<ul>
  <li>下載eclipse和SSMS和SQL server</li>
  <li>確保以上都可以正常運作</li>
</ul>

<h2 id="開始設定">開始設定</h2>

<h3 id="打開ssms">打開SSMS</h3>

<ul>
  <li>打開SSMS，在資料庫的地方右鍵新增資料庫</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res//2024-05-01-jdbc-setting-res/image.png?raw=true" alt="打開SSMS，在資料庫的地方右鍵新增資料庫" /></p>

<ul>
  <li>打上資料庫名稱後按確定</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res//2024-05-01-jdbc-setting-res/image-1.png?raw=true" alt="打上資料庫名稱後按確定" /></p>

<ul>
  <li>在”安全性” “登入”中新增一筆登入</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res//2024-05-01-jdbc-setting-res/image-2.png?raw=true" alt="在”安全性” “登入”中新增一筆登入" /></p>

<ul>
  <li>輸入登入名稱-&gt;勾選SQL server驗證後輸入密碼</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res//2024-05-01-jdbc-setting-res/image-3.png?raw=true" alt="輸入登入名稱-&gt;勾選SQL server驗證後輸入密碼" /></p>

<ul>
  <li>使用者對應中選擇剛剛建立的資料庫-&gt;下面勾選db_owner-&gt;按確定</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-4.png?raw=true" alt="使用者對應中選擇剛剛建立的資料庫" /></p>

<h3 id="sql-server設定管理員">SQL server設定管理員</h3>

<ul>
  <li>打開SQL server設定管理員</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-5.png?raw=true" alt="打開SQL server設定管理員" /></p>

<ul>
  <li>到SQLEXPRESS的通訊協定-&gt;TCP/IP按右鍵啟用</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-6.png?raw=true" alt="到SQLEXPRESS的通訊協定" /></p>

<ul>
  <li>在TCP/IP再按一次右鍵-&gt;內容-&gt;選擇IP位址-&gt;滑到最底下TCP通訊埠-&gt;改成1433</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-7.png?raw=true" alt="在TCP/IP再按一次右鍵" /></p>

<h3 id="windows防火牆">Windows防火牆</h3>

<ul>
  <li>打開windows defender防火牆(不要開錯!!!)-&gt;進階設定</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-8.png?raw=true" alt="打開windows defender防火牆" /></p>

<ul>
  <li>輸入規則-&gt;新增規則</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-9.png?raw=true" alt="輸入規則-&gt;新增規則" /></p>

<ul>
  <li>選擇連接埠-&gt;下一步</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-10.png?raw=true" alt="選擇連接埠-&gt;下一步" /></p>

<ul>
  <li>選擇TCP-&gt;輸入1433-&gt;下一步</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-11.png?raw=true" alt="選擇TCP-&gt;輸入1433-&gt;下一步" /></p>

<ul>
  <li>下一步-&gt;全部打勾</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-12.png?raw=true" alt="下一步-&gt;全部打勾" /></p>

<ul>
  <li>輸入名稱SQL Server-&gt;完成</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-13.png?raw=true" alt="輸入名稱SQL Server-&gt;完成" /></p>

<h3 id="再次打開ssms">再次打開SSMS</h3>

<ul>
  <li>最上層右鍵屬性</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-14.png?raw=true" alt="最上層右鍵屬性" /></p>

<ul>
  <li>安全性-&gt;勾選SQL Server及Windows驗證模式-&gt;確定</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-15.png?raw=true" alt="安全性" /></p>

<h3 id="回到sql-server設定管理員">回到SQL Server設定管理員</h3>

<ul>
  <li>右鍵將資料庫重新啟動</li>
</ul>

<p><img src="https://github.com/TcwSunny/TcwSunny.github.io/blob/main/assets/res/\2024-05-01-jdbc-setting-res\image-16.png?raw=true" alt="右鍵將資料庫重新啟動" /></p>

<p>以上做完系統設定就大功告成啦，下一篇會介紹如何透過java程式連結資料庫。</p>]]></content><author><name></name></author><category term="coding" /><category term="JDBC" /><summary type="html"><![CDATA[JDBC提供API讓JAVA使用者能夠透過程式訪問資料庫，這篇文章是在說明撰寫JDBC前的系統設定，step by step 教你如何設定資料庫與防火牆]]></summary></entry><entry><title type="html">《JDBC專題》0. 系列文簡介</title><link href="https://tcwsunny.github.io/2024/04/30/first-post" rel="alternate" type="text/html" title="《JDBC專題》0. 系列文簡介" /><published>2024-04-30T20:17:00+00:00</published><updated>2024-04-30T20:17:00+00:00</updated><id>https://tcwsunny.github.io/2024/04/30/first-post</id><content type="html" xml:base="https://tcwsunny.github.io/2024/04/30/first-post"><![CDATA[<p>最近深陷畢業即失業的困擾之中，從大學時期就因為對程式開發有興趣所以雙主修了資管系，沒想到打開104才發現怎麼需要會的東西學校都沒有教，所以毅然決然報名了資展的就業培訓班，從主力寫C++微跨領域到JAVA後端並開始重新學習，目前一個多月做了JDBC的小型專題，結果報告只有5分鐘根本不能講太詳細（體諒老師要聽38個學生，辛苦了），想說詳細紀錄一下自己的專題內容於是誕生了這篇系列文。</p>

<p>本來是要寫在Medium的文，結果medium的SEO政策讓我的文根本不能被搜尋，於是決定建一個github網站來放我的文章，目前使用的是<a href="https://github.com/ShawnTeoh/matjek">Matjek</a>大做的漂亮模板，之後有餘裕會再自己研究怎麼刻。</p>

<p>這個系列主要以介紹我做的專題內容為主，使用的工具是eclipse和SQL server，會分享從如何架環境到做出圖形化介面的心路歷程跟一些小細節，希望可以幫助到跟我一樣的程式新手！</p>]]></content><author><name></name></author><category term="coding" /><category term="introduction" /><category term="JDBC" /><summary type="html"><![CDATA[最近深陷畢業即失業的困擾之中，從大學時期就因為對程式開發有興趣所以雙主修了資管系，沒想到打開104才發現怎麼需要會的東西學校都沒有教，所以毅然決然報名了資展的就業培訓班，從主力寫C++微跨領域到JAVA後端並開始重新學習，目前一個多月做了JDBC的小型專題，結果報告只有5分鐘根本不能講太詳細（體諒老師要聽38個學生，辛苦了），想說詳細紀錄一下自己的專題內容於是誕生了這篇系列文。]]></summary></entry></feed>