顯示具有 技術札記 標籤的文章。 顯示所有文章
顯示具有 技術札記 標籤的文章。 顯示所有文章

[Xcode]產生iOS可用的jansson函式庫

序言

jansson函式庫是一個使用C語言開發的JSON編解譯的工具,

理論上應該是可以在不同環境下編譯後就能產生對應的函式庫檔來使用。

不過似乎從別人的發問與官方的回應下並沒有針對iOS給出一個確切的答案回答能不能使用。

經過嘗試之後,發現有另一個函式庫:libpomelo裡面有使用到這個函式庫,而這個函式庫目前也支援Andorid與iOS。

並且在我編譯過libpomelo就會產生jansson的函式庫,所以以下的步驟就是編譯過程與從中取得jansson函式庫檔。

環境

  • mac mini+New iPad with iOS 6.1

  • Xcode 4.6
  • libpomelo 0.3

命令

開啟Terminal,依序輸入以下命令

svn checkout https://github.com/NetEase/libpomelo.git/trunk libpomelo

cd libpomelo

svn checkout http://gyp.googlecode.com/svn/trunk/ gyp-read-only

cd gyp-read-only

./setup.py build

cd ..

sudo ./gyp-read-only/gyp --depth=. pomelo.gyp -Dlibrary=static_library -DTO=ios

./build_ios

./build_iossim


命令解釋

  1. 下載目前最新版的libpomelo
  2. 進入下載後的目錄
  3. 因為libpomelo的編譯是透過gyp這個工具,所以下載這個工具
  4. 進入gyp目錄
  5. 編譯gyp
  6. 離開gyp目錄
  7. 連結libpomelo
  8. 編譯ios版函式庫
  9. 編譯ios模擬器版函式庫

設定函式庫

以下要做的動作不是必要的。
我這邊依據我所需要的狀況,將函式庫複製到我的Xcode專案目錄並且命名為習慣的檔名。


  1. 從libpomelo的子目錄[deps/jansson/build/Default-iphoneos]與[deps/jansson/build/Default-iphonesimulator]會找到兩個同名的[libjansson.a]
  2. 將這兩個檔案複製到自己專案的根目錄,分別命名為[libjansson-device.a]與[libjansson-simulator.a]
  3. 設定的方式為點選專案的[TARGETS→Build Phases→Link Binary With Libraries],點選下面的[+]

    加入剛才複製過來的兩個.a檔[libjansson-device.a]與[libjansson-simulator.a]
  4. 從libpomelo的子目錄[deps/jansson]複製[src]目錄到自己專案的根目錄命名為[jansson]
  5. 專案的[TARGETS→Build Settings→Search Paths],設定[Header Search Paths],加入"$(SRCROOT)/jansson"

使用範例

這邊只寫個小程式測試編譯後可以執行,詳細CURL用法請參考相關文章


#include <jansson.h>
void myLib_test2(){
json_t *jdata;
char cmd_ark_id[] = "id";
char ark_id[] = "value";
jdata = json_pack("{s:s}",
cmd_ark_id,ark_id);
char *j_object;//json
j_object = json_dumps( jdata, 0 );
json_decref( jdata );
printf("%s",j_object);
}

參考文章

[Xcode]簡易加入libcurl到Xproject

序言

Curl函式庫常使用在進行Http的操作,這篇文章將使用已編譯完成的libcurl(來源為Nick's software)加入一個Xcode的Project所需的設定。

環境

設定函式庫

  1. 下載ioscurl-7.32.0.tar.gz,解壓縮後可以得到[ioscurl-7.32.0]目錄
  2. 進入[ioscurl-7.32.0/iOScURL]目錄會找到[libcurl-device.a]與[libcurl-simulator.a]兩個檔案與一個[curl]目錄,將這三個東西複製到自己專案的根目錄。

    (同層目錄下也有一個xCode的Project可以做為設定的參考)

    壓縮檔內的檔案


  3. 在專案中加入所需要的函式庫。

    設定的方式為點選專案的[TARGETS→Build Phases→Link Binary With Libraries],點選下面的[+]

    加入iOS原有的[Security.framework]、[libz.dylib]與剛才複製過來的兩個.a檔[libcurl-device.a][libcurl-simulator.a]
    設定後的函式庫
  4. 專案的[TARGETS→Build Settings→Search Paths],設定[Header Search Paths],加入"$(SRCROOT)/curl"

使用範例

這邊只寫個小程式測試編譯後可以執行,詳細CURL用法請參考相關文章

#ifndef xcurl_myLib_h
#define xcurl_myLib_h

#include <curl.h>
int myLib_test1(){
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl;
CURLcode res;
curl=curl_easy_init();
{
curl_easy_setopt(curl, CURLOPT_URL,"http://www.google.com.tw");
res=curl_easy_perform(curl);
curl_easy_cleanup(curl);
}

return (int)res;
}

#endif

相關文章

[MS-SQL]不具自動容錯移轉的鏡像設定

以下的資料庫鏡像架構大致上就是

應用程式==data==>主體伺服器==data==>鏡像伺服器

環境

兩台一樣環境的伺服器

  • Windows Server 2003 R2
  • Microsoft SQL Server 2008 R2
  • Microsoft SQL Server Management Studio 10.0.1600.22

SQL Server服務啟動帳號設定

  1. 在windows服務(services.msc) 列表中,找到SQL Server,右鍵選內容或雙擊
  2. 後選擇登入頁,在此帳戶中這裡配置登錄用戶和密碼,這個地方建議兩台伺服器都配置一組一樣的帳號,並將此帳戶加到SQL Server的管理帳戶,後續的鏡像會用這組帳號繼續設定
  3. SQL Server Agent 啟動帳號也一樣設置

主體伺服器備份

  1. 在主體伺服器用windows帳戶登入Management Studio工具,這個動作是為了後續使用語法產生SQL檔時才不會有權限錯誤
  2. 產生資料庫建立語法
    以物件總管詳細資料選取需要鏡像的資料庫,並產生Create語法(選檔案即可產生.sql檔)
  3. 匯出每個資料庫的備份檔
    backup database [DataBaseName1] to disk='D:\dbbackup\[DataBaseName1].bak'  with init
    GO
    backup database [DataBaseName2] to disk='D:\dbbackup\[DataBaseName2].bak' with init
    GO
  4. 匯出每個資料庫的記錄檔
    BACKUP LOG [DataBaseName1] TO DISK = 'D:\dbbackup\[DataBaseName1].log'
    GO
    BACKUP LOG [DataBaseName2] TO DISK = 'D:\dbbackup\[DataBaseName2].log'
    GO

還原資料到鏡像伺服器

  1. 將上一步驟產生的檔案(含*.sql、*.bak、*.log)所在dbbackup資料夾複製到鏡像資料庫
  2. 在鏡像伺服器用windows帳戶登入Management Studio工具
  3. 建立資料庫:以Management Studio開啟建立資料庫用的sql檔並執行,即可產生與主體伺服器相同名稱的資料庫
  4. 還原資料
    restore database [DataBaseName1] from disk='D:\backupz\[DataBaseName1].bak' with replace,norecovery
    GO
    restore database [DataBaseName2] from disk='D:\backupz\[DataBaseName2].bak' with replace,norecovery
    GO
  5. 還原記錄檔
    RESTORE LOG [DataBaseName1] FROM DISK = 'D:\backupz\[DataBaseName1].log'  WITH FILE=1, NORECOVERY
    GO
    RESTORE LOG [DataBaseName2] FROM DISK = 'D:\backupz\[DataBaseName2].log' WITH FILE=1, NORECOVERY
    GO
  6. 成功後會看到建立起來的資料庫名稱後面會出現(正在還原...)的狀態

於主體伺服器啟動鏡像服務

  1. 在主體伺服器的資料庫上點右鍵,選屬性,並選擇[鏡像]頁籤。接著點選[設定安全性]鈕就會開啟[設定資料庫鏡像安全性精靈]

  2. 於見證伺服器選擇頁選擇否,不使用見證伺服器

  3. 第一次使用鏡像設定會選擇本機的鏡像服務Port與鏡像端點名稱,此處採用預設值即可

  4. 設定鏡像伺服器的連線資訊

  5. 服務帳戶不用設定

  6. 完成後就會進行設定,第一次設定時會自動產生服務端點,這時就會啟動服務的Port

  7. 完成後會詢問是否要啟動鏡像,選擇不要啟動鏡像。這時如果直接啟動如果連線網域名稱錯誤就會失敗(而且還不給設定…)

  8. 接著就可以在伺服器網路位址確認鏡像伺服器的連線資訊

    需注意的是他有個奇怪的驗證,就是預設他會把鏡像伺服器的電腦名稱帶到鏡像的位址,但他的預設格式是[電腦名稱.網域名稱],沒有網域名稱時就必須在電腦名稱後面加一個句點.,否則你就會看到下面的錯誤

  9. 啟動成功後如下圖

  10. 重覆此上述動作把所有資料庫的鏡像都啟動

[C#]MS-SQL資料庫存取函式

序言

我將C#存取MS-SQL的程式包了一層方便使用。

環境

  • VS2008
  • MS-SQL 2008

存取函式類別

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text;
using System.Data;

namespace MyCommon.DAO
{

    /// 
    /// MS-SQL連線物件
    /// 
    public class MSSQLBaseIO
    {
        SqlConnection sqlConn = null;
        /// 
        /// 建立連線物件
        /// 
        /// 連線字串,如Data Source=localhost;Initial Catalog=dbName;User id=Account;Password=Password;
        public MSSQLBaseIO(string connectionString)
        {
            sqlConn = new SqlConnection(connectionString);
        }
        /// 
        /// 建立連線物件
        /// 
        /// 可為localhost / domainname  / 或 IP
        /// 若Host為IP,則需為true
        /// 不設定則填0,則會用MSSQL預設port
        /// 不設定則填null,express版預設為SQLEXPRESS,正式版預設為MSSQLSERVER,從服務組態可以看到
        /// 資料庫名稱
        /// 是否使用 Windows 整合驗証方式連線,false則必需填帳號密碼
        /// 登入帳號
        /// 登入密碼
        /// 連線逾期,不設定則填0
        public MSSQLBaseIO(string host,bool isHostIP,int port,
            string instanceName, string dbName,
            bool isIntegratedSecurity,
            string id, string password,
            int timeout)
        {
            StringBuilder connectionString = new StringBuilder();
            if (isHostIP) connectionString.Append("Data Source=tcp:" + host);
            else connectionString.Append("Data Source=" + host);
            if (instanceName != null) connectionString.Append("\\" + instanceName);
            if (port != 0) connectionString.Append("," + port);
            connectionString.Append(";");
            connectionString.Append("Initial Catalog=" + dbName + ";");
            if (isIntegratedSecurity) connectionString.Append("integrated security=true;");
            if (id!=null) connectionString.Append("User id=" + id + ";");
            if (password!=null) connectionString.Append("Password=" + password + ";");
            if (timeout>0) connectionString.Append("Connect Timeout=" + timeout + ";");
            sqlConn = new SqlConnection(connectionString.ToString());
        }
        /// 
        /// 取得目前連線物件
        /// 
        /// 
        public SqlConnection getConnection()
        {
            return sqlConn;
        }

        Exception _exception = null;
        /// 
        /// 取得上次執行後的錯誤
        /// 
        /// 
        public Exception getException(){
            return _exception;
        }
        /// 
        /// 關閉連線
        /// 
        public void closeConn()
        {
            closeConn(true);
        }
        /// 
        /// 關閉連線
        /// 
        /// 是否關閉連線
        public void closeConn(bool isCloseConn){
            if (sqlConn != null && isCloseConn && sqlConn.State!=System.Data.ConnectionState.Closed)
            {
                sqlConn.Close();
            }
        }
        /// 
        /// 取得新的Transaction物件
        /// 
        /// Transaction物件
        public SqlTransaction getNewTransaction()
        {
            if (sqlConn.State != System.Data.ConnectionState.Open)
                sqlConn.Open();
            return sqlConn.BeginTransaction();
        }

        /// 
        /// 執行SQL命令,執行後會關閉SQL連線
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 變動筆數
        public int ExecuteNonQuery(string sqlcmd, bool isStoredProcedure)
        {
            return ExecuteNonQuery(sqlcmd,isStoredProcedure, true);
        }
        /// 
        /// 執行SQL命令
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 是否關閉連線
        /// 變動筆數
        public int ExecuteNonQuery(string sqlcmd, bool isStoredProcedure, bool isCloseConn)
        {
            SqlParameter[] sqlparams = null;
            return ExecuteNonQuery(sqlcmd, ref sqlparams, isStoredProcedure, isCloseConn);
        }
        /// 
        /// 執行SQL命令
        /// 
        /// SQL命令
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// 是否關閉連線
        /// 變動筆數
        public int ExecuteNonQuery(string sqlcmd, ref SqlParameter[] sqlparams, bool isStoredProcedure, bool isCloseConn)
        {
            return ExecuteNonQuery(sqlcmd, ref sqlparams, isStoredProcedure, null, isCloseConn);
        }
        /// 
        /// 執行SQL命令
        /// 
        /// SQL命令
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// SqlTransaction,可為null
        /// 是否關閉連線
        /// 變動筆數
        public int ExecuteNonQuery(string sqlcmd, ref SqlParameter[] sqlparams,bool isStoredProcedure, SqlTransaction trans, bool isCloseConn)
        {
            int result = -1;
            _exception = null;
            try
            {
                if (sqlConn.State != System.Data.ConnectionState.Open)
                    sqlConn.Open();
                SqlCommand cmd;
                if (trans==null)
                    cmd = new SqlCommand(sqlcmd, sqlConn);
                else
                    cmd = new SqlCommand(sqlcmd, sqlConn, trans);
                if(isStoredProcedure)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (sqlparams!=null)
                    cmd.Parameters.AddRange(sqlparams);
                result = cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                _exception = ex;
            }
            finally
            {
                closeConn(isCloseConn);
            }
            return result;
        }
        /// 
        /// 取得多列資料,執行後會關閉SQL連線
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 是否關閉連線
        /// 多列資料
        public List ExecuteReader(string sqlcmd, bool isStoredProcedure)
        {
            return ExecuteReader(sqlcmd, isStoredProcedure, true);
        }
        /// 
        /// 取得多列資料
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 是否關閉連線
        /// 多列資料
        public List ExecuteReader(string sqlcmd, bool isStoredProcedure, bool isCloseConn)
        {
            SqlParameter[] sqlparams = null;
            return ExecuteReader(sqlcmd, ref sqlparams, isStoredProcedure, isCloseConn);
        }
        /// 
        /// 取得多列資料
        /// 
        /// SQL命令
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// 是否關閉連線
        /// 多列資料
        public List ExecuteReader(string sqlcmd, ref SqlParameter[] sqlparams, bool isStoredProcedure, bool isCloseConn)
        {
            return ExecuteReader(sqlcmd, ref sqlparams, isStoredProcedure, null, isCloseConn);
        }
        /// 
        /// 取得多列資料
        /// 
        /// SQL命令
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// SqlTransaction,可為null
        /// 是否關閉連線
        /// 多列資料
        public List ExecuteReader(string sqlcmd, ref SqlParameter[] sqlparams, bool isStoredProcedure, SqlTransaction trans, bool isCloseConn)
        {
            List result = null;
            _exception = null;
            SqlDataReader reader = null;
            try
            {
                if (sqlConn.State != System.Data.ConnectionState.Open)
                    sqlConn.Open();
                SqlCommand cmd;
                if (trans == null)
                    cmd = new SqlCommand(sqlcmd, sqlConn);
                else
                    cmd = new SqlCommand(sqlcmd, sqlConn, trans);
                if (isStoredProcedure)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (sqlparams != null)
                    cmd.Parameters.AddRange(sqlparams);
                reader = cmd.ExecuteReader();
                object[] item;
                if (reader.HasRows)
                {
                    result = new List();
                    while (reader.Read())
                    {
                        item = new object[reader.FieldCount];
                        for (int j = 0; j < reader.FieldCount; j++)
                        {
                            item[j] = reader[j];
                        }
                        result.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                _exception = ex;
            }
            finally
            {
                if (reader!=null) reader.Close();
                closeConn(isCloseConn);
            }
            return result;
        }

        /// 
        /// 取得單一值,執行後會關閉SQL連線
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 單一值
        public object ExecuteScalar(string sqlcmd, bool isStoredProcedure)
        {
            return ExecuteScalar(sqlcmd, isStoredProcedure, true);
        }
        /// 
        /// 取得單一值
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 是否關閉連線
        /// 單一值
        public object ExecuteScalar(string sqlcmd, bool isStoredProcedure, bool isCloseConn)
        {
            SqlParameter[] sqlparams = null;
            return ExecuteScalar(sqlcmd, ref sqlparams, isStoredProcedure, isCloseConn);
        }
        /// 
        /// 取得單一值
        /// 
        /// SQL命令
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// 是否關閉連線
        /// 單一值
        public object ExecuteScalar(string sqlcmd,ref SqlParameter[] sqlparams, bool isStoredProcedure, bool isCloseConn)
        {
            return ExecuteScalar(sqlcmd,ref sqlparams, isStoredProcedure, null, isCloseConn);
        }
        /// 
        /// 取得單一值
        /// 
        /// SQL命令
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// SqlTransaction,可為null
        /// 是否關閉連線
        /// 單一值
        public object ExecuteScalar(string sqlcmd,ref SqlParameter[] sqlparams, bool isStoredProcedure, SqlTransaction trans, bool isCloseConn)
        {
            object result = null;
            _exception = null;
            try
            {
                if (sqlConn.State != System.Data.ConnectionState.Open)
                    sqlConn.Open();
                SqlCommand cmd;
                if (trans == null)
                    cmd = new SqlCommand(sqlcmd, sqlConn);
                else
                    cmd = new SqlCommand(sqlcmd, sqlConn, trans);
                if (isStoredProcedure)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (sqlparams != null)
                    cmd.Parameters.AddRange(sqlparams);
                result = cmd.ExecuteScalar();
              
            }
            catch (Exception ex)
            {
                _exception = ex;
            }
            finally
            {
                closeConn(isCloseConn);
            }
            return result;
        }

        /// 
        /// 取得單一列資料,執行後會關閉SQL連線
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 單一列資料
        public object[] ExecuteReaderSingleRow(string sqlcmd, bool isStoredProcedure)
        {
            return ExecuteReaderSingleRow(sqlcmd, isStoredProcedure, true);
        }
        /// 
        /// 取得單一列資料
        /// 
        /// SQL命令
        /// 是否為預存程序
        /// 是否關閉連線
        /// 單一列資料
        public object[] ExecuteReaderSingleRow(string sqlcmd, bool isStoredProcedure, bool isCloseConn)
        {
            SqlParameter[] sqlparams = null;
            return ExecuteReaderSingleRow(sqlcmd, ref sqlparams, isStoredProcedure, isCloseConn);
        }
        /// 
        /// 取得單一列資料
        /// 
        /// SQL命令,參數部份以 @參數名稱 標示
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// 是否關閉連線
        /// 單一列資料
        public object[] ExecuteReaderSingleRow(string sqlcmd,ref SqlParameter[] sqlparams, bool isStoredProcedure, bool isCloseConn)
        {
            return ExecuteReaderSingleRow(sqlcmd,ref sqlparams, isStoredProcedure, null, isCloseConn);
        }
        /// 
        /// 取得單一列資料
        /// 
        /// SQL命令,參數部份以 @參數名稱 標示
        /// 命令參數,可為null,參數名稱為 @參數名稱
        /// 是否為預存程序
        /// SqlTransaction,可為null
        /// 是否關閉連線
        /// 單一列資料
        public object[] ExecuteReaderSingleRow(string sqlcmd, ref SqlParameter[] sqlparams, bool isStoredProcedure, SqlTransaction trans, bool isCloseConn)
        {
            object[] result = null;
            _exception = null;
            SqlDataReader reader = null;
            try
            {
                if (sqlConn.State != System.Data.ConnectionState.Open)
                    sqlConn.Open();
                SqlCommand cmd;
                if (trans == null)
                    cmd = new SqlCommand(sqlcmd, sqlConn);
                else
                    cmd = new SqlCommand(sqlcmd, sqlConn, trans);
                if (isStoredProcedure)
                    cmd.CommandType = CommandType.StoredProcedure;
                if (sqlparams != null)
                    cmd.Parameters.AddRange(sqlparams);
                reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
                object[] item;
                if (reader.HasRows)
                {
                    reader.Read();
                    item = new object[reader.FieldCount];
                    for (int j = 0; j < reader.FieldCount; j++)
                    {
                        item[j] = reader[j];
                    }
                    result = item;
                }
            }
            catch (Exception ex)
            {
                _exception = ex;
            }
            finally
            {
                if (reader != null) reader.Close();
                closeConn(isCloseConn);
            }
            return result;
        }
    }
}
 

[C++]Oracle資料庫存取函式(OCCI)


開發環境

  • VS2008
  • Oracle 10g Express Edition

下載OCCI函式庫

  1. 下載occivc9win32-111060-132181.zip,解壓縮到自行建立的lib目錄後可以得到目錄
  2. 下載instantclient-sdk-win32-11.2.0.1.0.zip,解壓縮後可在[instantclient_11_2\sdk\]目錄找到[include]
  3. 將上述兩個目錄複製到某個目錄下,如[D:\Project\CPPProject\occivc9win32-111060-132181]

設定開發專案

  1. 將[lib]目錄中的oraocci11.dll與oraocci11d.dll都複製到[C:\WINDOWS\system32]
  2. 於開發用的C++專案設定屬性:展開[組態屬性→C/C++→一般],修改[其他Include目錄],指到[include]目錄
  3. 展開[組態屬性→連結器→一般],修改[其他程式庫目錄],指到lib目錄
  4. 展開[組態屬性→連結器→輸入],修改[其他相依性],,增加[oraocci11d.lib]

資料庫連線函式庫

  1. OracleIO.h
    #pragma once
    #include
    namespace commonio {
     class OracleIO
     {
      private:
       oracle::occi::Environment *env;
       oracle::occi::Connection *conn;
       oracle::occi::Statement *stmt;
       oracle::occi::ResultSet *rs;
       const char* _ip;
       unsigned int _port;
       const char* _account;
       const char* _pswd;
       const char* _defaultDB;
      public:
       OracleIO(const char* ip,unsigned int port,const char* account,const char* pswd,const char* defaultDB);
       ~OracleIO(void);
    
       
       /**
       **取得連線
       **/
       oracle::occi::Connection *getConn();
       void closeConn();
       void closeStatement();
       /**
       **執行查詢
       **/
       oracle::occi::ResultSet *executeQuery(const char* sqlStr);
       /**
       **執行新增、更新、刪除
       **/
       unsigned int executeUpdate(const char* sqlStr);
     };
    };
  2. OracleIO.cpp
    #include "StdAfx.h"
    #include "OracleIO.h"
    #include "CommonFunc.h"
    #include 
    using namespace std;
    using namespace commonio;
    using namespace oracle::occi;
    OracleIO::OracleIO(const char* ip,unsigned int port,const char* account,const char* pswd,const char* defaultDB)
    {
     _ip=ip;
     _port=port;
     _account=account;
     _pswd=pswd;
     _defaultDB=defaultDB;
     env = oracle::occi::Environment::createEnvironment("UTF8","UTF8",Environment::THREADED_MUTEXED);
     conn=NULL;
     stmt=NULL;
     rs=NULL;
    }
    
    
    
    OracleIO::~OracleIO(void)
    {
     closeConn();
     oracle::occi::Environment::terminateEnvironment(env);
    }
    
    Connection* OracleIO::getConn(){
     if(conn==NULL){
      string port;
      commonio::CommonFunc::itostr(_port,port,10);
      string connectString="//";
      connectString=connectString + _ip+ ":" + port + "/" + _defaultDB;
      conn = env->createConnection(_account, _pswd, connectString);
     }
     return conn;
    }
    void OracleIO::closeConn(){
     if(conn!=NULL){
      closeStatement();
      env->terminateConnection(conn);
      conn=NULL;
     }
    }
    void OracleIO::closeStatement(){
     if(stmt!=NULL){
      if(rs!=NULL){
       stmt->closeResultSet(rs);
       rs=NULL;
      }
      conn->terminateStatement(stmt);
      stmt=NULL;
     }
    }
    
    ResultSet *OracleIO::executeQuery(const char* sqlStr){
     try{
      getConn();
      string sql=string(sqlStr);
      stmt = conn->createStatement(sql);
      rs = stmt->executeQuery();  
     }catch (SQLException &sqlExcp){
      cerr <createStatement(sql);
      result=stmt->executeUpdate();
      closeStatement();
     }catch (SQLException &sqlExcp){
      cerr <
  3. 額外函式
    • CommonFunc.h
      #pragma once
      using namespace std;
      namespace commonio {
       class CommonFunc
       {
       public:
        static void itostr(int value, std::string& buf, int base);
       };
      };
    • CommonFunc.cpp
      #include "stdafx.h"
      #include 
      #include "CommonFunc.h"
      using namespace std;
      using namespace commonio;
      
      void CommonFunc::itostr(int value, std::string& buf, int base){
       
       int i = 30;
       
       buf = "";
       
       for(; value && i ; --i, value /= base) buf = "0123456789abcdef"[value % base] + buf;
       
      }

使用範例

#include "stdafx.h"
#include 
#include 
#include "OracleIO.h"
using namespace std;
using namespace commonio;

int main(int argc, _TCHAR* argv[])
{

 OracleIO oracleio=OracleIO("localhost",1521,"oracle","oracle","XE");
 /**
 **更新測試Start
 **/ 
 unsigned int changeNum= oracleio.executeUpdate("update test1 set testname='test123' where testsn=1");
 cout<<"changeNum:"< listOfColumns =rs->getColumnListMetaData();
 for(int i=0;inext())
 {
  for(int i=0;igetString(i+1)<<"\t";
  }
  cout <

[C++]MySQL資料庫存取函式(MySQL++)

序言

此篇為研究C++存取MySQL所寫的函式。

環境

編譯MySQL++函式庫

  1. 下載mysql++-3.1.0.tar.gz,解壓縮後可以得到[mysql++-3.1.0]目錄
  2. 進入[mysql++-3.1.0\vc2008\]目錄會找到[mysql++_mysqlpp.vcproj]專案,以Visual Studio 2008開啟
  3. 編譯時MySQL++會需要MySQL的版本定義標頭檔,函式庫預設MySQL安裝於[C:\Program Files\MySQL\MySQL Server 5.1],所以需先確認是否有[C:\Program Files\MySQL\MySQL Server 5.1\include]與[C:\Program Files\MySQL\MySQL Server 5.1\lib\opt]是否存在,如果MySQL放在其他目錄,可透過專案屬性修改
    • 開啟專案屬性
    • 展開[組態屬性→C/C++→一般],修改[其他Include目錄],指到MySQL的安裝目錄中的include資料夾
    • 展開[組態屬性→連結器→一般],修改[其他程式庫目錄],指到MySQL的安裝目錄中的lib\opt資料夾
  4. 建置專案
  5. 建置成功後會在[mysql++-3.1.0\vc2008\Debug]目錄下看到編譯完成的mysqlpp_d.dll、mysqlpp_d.lib

設定開發專案

  1. 將上一步產生的[mysqlpp_d.dll]複製到[C:\WINDOWS\system32]
  2. 於開發用的C++專案設定屬性:展開[組態屬性→C/C++→一般],修改[其他Include目錄],指到MySQL的安裝目錄中的include資料夾與mysql++函式庫的lib目錄
  3. 展開[組態屬性→連結器→一般],修改[其他程式庫目錄],指到MySQL的安裝目錄中的lib\opt資料夾與mysql++編譯後的Debug目錄
  4. 展開[組態屬性→連結器→輸入],修改[其他相依性],,增加[mysqlpp_d.lib]與 [libmysql.lib]

資料庫連線函式庫

  1. MySQLIO.h
    #pragma once
    
    #include 
    
    namespace commonio {
    
         class MySQLIO
    
         {
    
         private:
    
               mysqlpp::Connection _conn;
    
               const char* _ip;
    
               unsigned int _port;
    
               const char* _account;
    
               const char* _pswd;
    
               const char* _defaultDB;
    
               const char* _error;
    
               int _errnum;
    
         public:
    
               /**
    
               **MySQL資料庫連線物件
    
               **/
    
               MySQLIO(const char* ip,unsigned int port,const char* account,const char* pswd,const char* defaultDB);
    
               ~MySQLIO(void);
    
               /**
    
               **錯誤訊息
    
               **/
    
               const char* error();
    
               int errnum();
    
               /**
    
               **取得連線
    
               **/
    
               mysqlpp::Connection getConn(){return _conn;}
    
               /**
    
               **執行查詢
    
               **/
    
               mysqlpp::StoreQueryResult executeQuery(const char* sqlStr);
    
               /**
    
               **執行查詢
    
               **/
    
               mysqlpp::StoreQueryResult executeQuery(const char* sqlStr,mysqlpp::SQLQueryParms & param);
    
               /**
    
               **執行新增、更新、刪除
    
               **/
    
               mysqlpp::SimpleResult executeUpdate(const char* sqlStr);
    
               /**
    
               **執行新增、更新、刪除
    
               **/
    
               mysqlpp::SimpleResult executeUpdate(const char* sqlStr,mysqlpp::SQLQueryParms & param);
    
         };
    
    };
  2. MySQLIO.cpp
    #include "stdafx.h"
    
    #include "MySQLIO.h"
    
     
    
    using namespace std;
    
    using namespace commonio;
    
    MySQLIO::MySQLIO(const char* ip,unsigned int port,const char* account,const char* pswd,const char* defaultDB):_conn(false)
    
    {
    
         _ip=ip;
    
         _port=port;
    
         _account=account;
    
         _pswd=pswd;
    
         _defaultDB=defaultDB;
    
         _conn.set_option(new mysqlpp::SetCharsetNameOption("utf8") );
    
    }
    
    const char* MySQLIO::error(){return _error;}
    
    int MySQLIO::errnum(){return _errnum;}
    
    mysqlpp::StoreQueryResult MySQLIO::executeQuery(const char* sqlStr){
    
         _error=NULL;
    
         _errnum=0;
    
         
    
         try{
    
               if(!_conn.connected()) {
    
                    if(!_conn.connect(_defaultDB, _ip,
    
                         _account, _pswd,_port)){
    
                               _error=_conn.error();
    
                               _errnum=_conn.errnum();
    
                               
    
                    }
    
               }
    
               if(_conn.connected()) {
    
                    mysqlpp::Query query = _conn.query(sqlStr);
    
                    if (mysqlpp::StoreQueryResult res = query.store()) {
    
                         query.reset();
    
                         return res;
    
                    }else{
    
                         _error=query.error();
    
                         _errnum=query.errnum();
    
                         
    
                    }
    
               }
    
         }catch(const mysqlpp::ConnectionFailed &e){
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch(const mysqlpp::BadQuery &e){        
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch (const mysqlpp::BadConversion & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadFieldName & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadIndex & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadInsertPolicy & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadOption & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadParamCount & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::Exception& e) {
    
               _error=e.what();
    
         }
    
         return mysqlpp::StoreQueryResult();
    
     
    
    }
    
    mysqlpp::StoreQueryResult MySQLIO::executeQuery(const char* sqlStr,mysqlpp::SQLQueryParms & param){
    
         _error=NULL;
    
         _errnum=0;
    
         
    
         try{
    
               if(!_conn.connected()) {
    
                    if(!_conn.connect(_defaultDB, _ip,
    
                         _account, _pswd,_port)){
    
                               _error=_conn.error();
    
                               _errnum=_conn.errnum();
    
                               
    
                    }
    
               }
    
               if(_conn.connected()) {
    
                    mysqlpp::Query query = _conn.query(sqlStr);
    
                    query.parse();
    
                    if (mysqlpp::StoreQueryResult res = query.store(param)) {
    
                         query.reset();
    
                         return res;
    
                    }else{
    
                         _error=query.error();
    
                         _errnum=query.errnum();
    
                         
    
                    }
    
               }
    
         }catch(const mysqlpp::ConnectionFailed &e){
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch(const mysqlpp::BadQuery &e){        
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch (const mysqlpp::BadConversion & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadFieldName & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadIndex & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadInsertPolicy & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadOption & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadParamCount & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::Exception& e) {
    
               _error=e.what();
    
         }
    
         return mysqlpp::StoreQueryResult();
    
    }
    
     
    
     
    
    mysqlpp::SimpleResult MySQLIO::executeUpdate(const char* sqlStr){
    
         _error=NULL;
    
         _errnum=0;
    
         
    
         try{
    
               if(!_conn.connected()) {
    
                    if(!_conn.connect(_defaultDB, _ip,
    
                         _account, _pswd,_port)){
    
                               _error=_conn.error();
    
                               _errnum=_conn.errnum();
    
                    }
    
               }
    
               if(_conn.connected()) {
    
                    mysqlpp::Query query = _conn.query(sqlStr);
    
                    query.parse();
    
                    if (mysqlpp::SimpleResult res = query.execute()) {
    
                         query.reset();
    
                         return res;
    
                    }else{
    
                         _error=query.error();
    
                         _errnum=query.errnum();
    
                         
    
                    }
    
               }
    
         }catch(const mysqlpp::ConnectionFailed &e){
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch(const mysqlpp::BadQuery &e){        
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch (const mysqlpp::BadConversion & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadFieldName & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadIndex & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadInsertPolicy & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadOption & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadParamCount & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::Exception& e) {
    
               _error=e.what();
    
         }
    
         return mysqlpp::SimpleResult();
    
    }
    
     
    
    mysqlpp::SimpleResult MySQLIO::executeUpdate(const char* sqlStr,mysqlpp::SQLQueryParms & param){
    
         _error=NULL;
    
         _errnum=0;
    
         
    
         try{
    
               if(!_conn.connected()) {
    
                    if(!_conn.connect(_defaultDB, _ip,
    
                         _account, _pswd,_port)){
    
                               _error=_conn.error();
    
                               _errnum=_conn.errnum();
    
                    }
    
               }
    
               if(_conn.connected()) {
    
                    mysqlpp::Query query = _conn.query(sqlStr);
    
                    query.parse();
    
                    if (mysqlpp::SimpleResult res = query.execute(param)) {
    
                         query.reset();
    
                         return res;
    
                    }else{
    
                         _error=query.error();
    
                         _errnum=query.errnum();
    
                         
    
                    }
    
               }
    
         }catch(const mysqlpp::ConnectionFailed &e){
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch(const mysqlpp::BadQuery &e){        
    
               _error=e.what();
    
               _errnum=e.errnum();
    
         }catch (const mysqlpp::BadConversion & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadFieldName & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadIndex & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadInsertPolicy & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadOption & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::BadParamCount & e) {
    
               _error=e.what();
    
         }catch (const mysqlpp::Exception& e) {
    
               _error=e.what();
    
         }
    
         return mysqlpp::SimpleResult();
    
    }
    
     
    
    MySQLIO::~MySQLIO(void)
    
    {    
    
    }

使用範例

#include "stdafx.h"

#include 

#include "MySQLIO.h"

using namespace std;

using namespace commonio;

 

int main(int argc, _TCHAR* argv[])

{

     string data;

 

     MySQLIO mysqlio("localhost",3306,"root",NULL,"pklogdb");

     mysqlpp::SQLQueryParms params;

           params << 2;

     if (mysqlpp::StoreQueryResult res = mysqlio.executeQuery("select * from gametypetab where gameType=%0q",params)) {

           mysqlpp::StoreQueryResult::const_iterator it;

           mysqlpp::Row::const_iterator colit;

           for (it = res.begin(); it != res.end(); ++it) {

                mysqlpp::Row row = *it;

                cout << '\t';

                for (colit = row.begin(); colit != row.end(); ++colit) {

                     if(colit->is_null()){

                           cout << "\t (NULL)"<< endl;

                     }else{

                           string col(*colit);

                           cout << '\t' << col << endl;                         

                     }

                }

                cout << endl;

           }

           params.clear();

           string value("TEST");

           params<0){

                cerr << "success update"<< endl;

           }

     }else{

           cerr << "Failed to get item list: "<< endl;

           return 1;

     }

 

    return 0;

}

[C++]Http Get與Post函式(Curl)

序言

此篇記錄我使用Curl函式庫來達成Http的Get與Post方法。

開發環境

編譯Curl函式庫

  1. 下載curl-7.21.4.zip,解壓縮後可以得到[curl-7.21.4]目錄
  2. 進入[curl-7.21.4]目錄會找到[vc6curl.dsw]專案,以Visual Studio 2008開啟
  3. 建置專案
  4. 建置成功後會在[curl-7.21.4\lib\DLL-Debug]目錄下看到編譯完成的libcurld.dll、libcurld_imp.lib

設定開發專案

  1. 將上一步產生的[libcurld.dll]複製到[C:\WINDOWS\system32]
  2. 於開發用的C++專案設定屬性:展開[組態屬性→C/C++→一般],修改[其他Include目錄],指到[curl-7.21.4]目錄中的include資料夾
  3. 展開[組態屬性→連結器→一般],修改[其他程式庫目錄],指到[curl-7.21.4\lib\DLL-Debug]目錄
  4. 展開[組態屬性→連結器→輸入],修改[其他相依性],,增加[libcurld_imp.lib]


Http連線函式庫

  1. HttpIO.h
    #pragma once
    #include 
    using namespace std;
    namespace commonio {
     class HttpIO
     {
     public:
      /**
      **post方法
      **isRedirect:是否依head redirect
      **param:傳參數,如val1=123&val2=abc
      **timeout:等待回應逾期時間(秒),為不限制
      **/
      static string doPost(string URL,bool isRedirect,string param="",long timeout=0);
      /**
      **get方法
      **isRedirect:是否依head redirect
      **timeout:等待回應逾期時間(秒),為不限制
      **/
      static string doGet(string URL,bool isRedirect,long timeout=0);
     };
    };
  2. HttpIO.cpp
    #include "StdAfx.h"
    #include 
    //#include 
    #include 
    #include "HttpIO.h"
    
    using namespace std;
    using namespace commonio;
    
    
    // This is the writer call back function used by curl
    size_t writer (char *data, size_t size, size_t nmemb, std::string *buffer)
    {
        size_t result = 0;
        if (buffer != NULL)
        {
            buffer->append (data, size * nmemb);
            result = size * nmemb;
        }
        return result;
    }    
    
    
    
    string HttpIO::doPost(string URL,bool isRedirect,string param,long timeout)
    {
        CURL *curl;
        CURLcode cc;
        string bufferdata;
     string error;
     //string user_agent("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
     if ((curl = curl_easy_init()) == NULL)
            exit(1);
     curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
        curl_easy_setopt(curl, CURLOPT_URL, URL.c_str()); // URL used for posting
     //curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
     
    
     if(isRedirect) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //Redirect
     if(timeout>0) curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); //times out after second
        curl_easy_setopt(curl, CURLOPT_POST, 1);//Tell libcurl to use POST
     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, param.c_str());
        curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION,   writer);
        curl_easy_setopt (curl, CURLOPT_WRITEDATA,&bufferdata);
        //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  //Debug
        //cc=curl_easy_setopt(curl, CURLOPT_HEADER, 1);    //Debug
     cc = curl_easy_perform(curl);
     
        curl_easy_cleanup(curl);
        if(cc == CURLE_OK)
            {
                string data;
                data=bufferdata;
                bufferdata="";
       return data;
            }      
            else
            {
                //cout << "Error: [" << cc << "] - "<< error;
       string data("");
       return data;
            }
    }
    
    string HttpIO::doGet(string URL,bool isRedirect,long timeout)
    {
        CURL *curl;
        CURLcode cc;
    
        string bufferdata;
     string error;
        if ((curl = curl_easy_init()) == NULL)
            exit(1);
     curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
        curl_easy_setopt(curl, CURLOPT_URL, URL.c_str()); // URL used for posting
     if(isRedirect) curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //Redirect
     if(timeout>0) curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); //times out after second
        curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION,   writer);
        curl_easy_setopt (curl, CURLOPT_WRITEDATA,&bufferdata);
     //cc=curl_easy_setopt(curl, CURLOPT_HEADER, 1);    //Debug
        cc = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        if(cc == CURLE_OK)
            {
                string data;
                data=bufferdata;
                bufferdata="";
       return data;
            }      
            else
            {
                //cout << "Error: [" << cc << "] - "<< error;
       string data("");
       return data;
            }
    }
  3. 額外函式
    • CommonFunc.h
      #pragma once
      using namespace std;
      namespace commonio {
       class CommonFunc
       {
       public:
        static void str_split(const string& str,
              vector& tokens,
              const string& delimiters = " ");
        static vector> paramToArray(string param);
       };
      };
    • CommonFunc.cpp
      #include "stdafx.h"
      
      #include 
      #include 
      #include "CommonFunc.h"
      using namespace std;
      using namespace commonio;
      void CommonFunc::str_split(const string& str,
                            vector& tokens,
                            const string& delimiters){
          // Skip delimiters at beginning.
          string::size_type lastPos = str.find_first_not_of(delimiters, 0);
          // Find first "non-delimiter".
          string::size_type pos     = str.find_first_of(delimiters, lastPos);
      
          while (string::npos != pos || string::npos != lastPos)
          {
              // Found a token, add it to the vector.
              tokens.push_back(str.substr(lastPos, pos - lastPos));
              // Skip delimiters.  Note the "not_of"
              lastPos = str.find_first_not_of(delimiters, pos);
              // Find next "non-delimiter"
              pos = str.find_first_of(delimiters, lastPos);
          }
      }
      
      
      vector> CommonFunc::paramToArray(string param){
         vector>  arr;
         vector p;
         CommonFunc::str_split(param,p,"&");
         if (param.find("&")>-1) {
          vector p2;
          int j = 0;
          for (unsigned int i = 0; i < p.size(); i++) {
           if (p[i].find_first_of("amp;")==0) {
            p2[j - 1]=p2[j - 1] + "&" + p[i].substr(4);
            j--;
           }
           p2.push_back(p[i]);
           j++;
          }
          p=p2;
         }
      
         for (unsigned int i = 0; i < p.size(); i++) {
          vector item;
          CommonFunc::str_split(p[i],item,"=");
          if (item.size() == 2) {
           arr.push_back(item);
          }
         }
         return arr;
        }

使用範例程式

#include "stdafx.h"
#include 
#include 
#include "HttpIO.h"
using namespace std;
using namespace commonio;

int main(int argc, _TCHAR* argv[])
{
 string data=HttpIO::doGet("http://www.google.com",false);
 cout << '\t' << data << endl;
    return 0;
}

[Java]Http Get與Post函式2(HttpURLConnection)

序言

之前我發的一篇[Http Get與Post函式]中已經實現了可維持Session狀態的HTTP連線函式,但我發現了Apache提供的這個Client在Windows下會有連線數上限的問題(聽說好像調整XP連線數可以解決)。
另外,有的時候使用HTTP連線也不一定需要維持Session狀態,這時候其實就不需要另外加入Apache的http client的JAR。
因此我還是整理一下如果一個不維持Session狀態的HTTP Client連線怎麼達成。

函式原始碼

參數轉換函式
package common.control;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;

public class HTTPParseFunc {

/**
* hashMapToString
*
* @param map
* @param charset編碼
* ,如HTTP.UTF_8
* @return
* @throws UnsupportedEncodingException
*/
@SuppressWarnings("unchecked")
public static String hashMapToString(HashMap<String, String> map,
String charset) throws UnsupportedEncodingException {
StringBuffer result = new StringBuffer();
java.util.Iterator it = map.entrySet().iterator();
boolean isfirst = true;
while (it.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
if (isfirst) {
isfirst = false;
} else {
result.append("&");
}
result
.append(URLEncoder.encode(entry.getKey().toString(),
charset));
result.append("=");
result.append(URLEncoder.encode(entry.getValue().toString(),
charset));
}
return result.toString();
}
/**
* 將inputStream轉為String
*
* @param is
* inputStream
* @param charset
* 編碼,如HTTP.UTF_8
* @return inputStream的內容
* @throws UnsupportedEncodingException
*/
public static String inputStream2String(InputStream is, String charset)
throws UnsupportedEncodingException {
BufferedReader in = new BufferedReader(new InputStreamReader(is,
charset));
StringBuffer buffer = new StringBuffer();
String line = "";
try {
boolean isfirst = true;
while ((line = in.readLine()) != null) {
if (!isfirst) {
buffer.append("\n");
} else {
isfirst = false;
}
buffer.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}

return buffer.toString();
}

/**
* HTTP 傳輸參數分割
* @param param 如name1=value1&name2=value2
* @return
* @throws UnsupportedEncodingException
*/
public static ArrayList<String[]> paramToArray(String param)
throws UnsupportedEncodingException {
ArrayList<String[]> arr = null;
String[] p = param.split("&");
if (param.toLowerCase().contains("&amp;")) {
ArrayList<String> p2 = new ArrayList<String>();
int j = 0;
for (int i = 0; i < p.length; i++) {
if (p[i].toLowerCase().startsWith("amp;")) {
p2.set(j - 1, p2.get(j - 1) + "&amp;" + p[i].substring(4));
j--;
}
p2.add(p[i]);
j++;
}
p2.toArray(p);
}

for (int i = 0; i < p.length; i++) {
String[] item = p[i].split("=");
if (item.length == 2) {
if (arr == null)
arr = new ArrayList<String[]>();
// item[0]=URLDecoder.decode(item[0],charset);
// item[1]=URLDecoder.decode(item[1],charset);
arr.add(item);
}
}
return arr;
}
}

連線參數模型
package common.model;

public class HTTPResponse {
String html=null;
Integer statusCode=null;
public String getHtml() {
return html;
}
public void setHtml(String html) {
this.html = html;
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
}


HTTP連線函式
package common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.util.HashMap;

import common.control.HTTPParseFunc;
import common.model.HTTPResponse;



public class HTTPBaseIO2 {
public enum Method {
get, post
}
/**
* 送出Request
* @param urlpath URL
* @param method HTTPBaseIO2.Method.get/post
* @param params HashMap<Name, Value>
* @param charset UTF-8
* @param timeout 連線逾時null:不設限/millisecond
* @return 回傳的html
* @throws UnsupportedEncodingException
*/
public static HTTPResponse doSend(String urlpath, Method method,
HashMap<String, String> params, String charset,boolean isAutoRedirect, Integer timeout,Proxy proxy) throws UnsupportedEncodingException {
HTTPResponse result=new HTTPResponse();
String param=null;
if(params!=null){
param=HTTPParseFunc.hashMapToString(params, charset);
}
if(method==Method.post){
result=sendPost(urlpath,param,charset,isAutoRedirect,timeout,proxy);
}else{
result=sendGet(urlpath,param,charset,isAutoRedirect,timeout,proxy);
}
return result;
}
/**
* 向指定URL發送GET方法的請求
*
* @param url
* 發送請求的URL
* @param param
* 請求參數,請求參數應該是name1=value1&name2=value2的形式。
* @return URL所代表遠程資源的響應
*/
public static HTTPResponse sendGet(String url, String params, String charset,boolean isAutoRedirect, Integer timeout,Proxy proxy) {
HTTPResponse result=new HTTPResponse();
HttpURLConnection conn=null;
BufferedReader in = null;
try {
String urlName = url;
if(params!=null) urlName+= "?" + params;
URL realUrl = new URL(urlName);

HttpURLConnection.setFollowRedirects(isAutoRedirect);
// 打開和URL之間的連接
if(proxy!=null)
conn = (HttpURLConnection)realUrl.openConnection(proxy);
else
conn = (HttpURLConnection)realUrl.openConnection();
if(timeout!=null) conn.setConnectTimeout(timeout);
// 設置通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 建立實際的連接
conn.connect();
result.setHtml(HTTPParseFunc.inputStream2String(conn.getInputStream(), charset));
} catch (Exception e) {
e.printStackTrace();
result=null;
}
// 使用finally塊來關閉輸入流
finally {
try {
if (conn != null){
if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK)
result=null;
result.setStatusCode(conn.getResponseCode());
}
} catch (Exception e) {
}
try {
if (in != null) {
in.close();
}
if (conn != null){
conn.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}

/**
* 向指定URL發送POST方法的請求
*
* @param url
* 發送請求的URL
* @param param
* 請求參數,請求參數應該是name1=value1&name2=value2的形式。
* @return URL所代表遠程資源的響應
*/
public static HTTPResponse sendPost(String url, String params, String charset,boolean isAutoRedirect, Integer timeout,Proxy proxy) {
HTTPResponse result=new HTTPResponse();
PrintWriter out = null;
BufferedReader in = null;
HttpURLConnection conn=null;
try {
URL realUrl = new URL(url);
// 打開和URL之間的連接

HttpURLConnection.setFollowRedirects(isAutoRedirect);
if(proxy!=null)
conn = (HttpURLConnection)realUrl.openConnection(proxy);
else
conn = (HttpURLConnection)realUrl.openConnection();
if(timeout!=null) conn.setConnectTimeout(timeout);
// 設置通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 發送POST請求必須設置如下兩行
conn.setDoOutput(true);
conn.setDoInput(true);
// 獲取URLConnection對象對應的輸出流
out = new PrintWriter(conn.getOutputStream());
// 發送請求參數
if(params!=null) out.print(params);
// flush輸出流的緩衝
out.flush();
result.setHtml(HTTPParseFunc.inputStream2String(conn.getInputStream(), charset));

} catch (Exception e) {
e.printStackTrace();
result=null;
}
// 使用finally塊來關閉輸出流、輸入流
finally {
try {
if (conn != null){
if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK)
result=null;
result.setStatusCode(conn.getResponseCode());
}
} catch (Exception e) {
}
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
if (conn != null){
conn.disconnect();
}
}
return result;
}


}

使用範例程式

package common.test;

import java.util.HashMap;


import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import common.HTTPBaseIO2;
import common.model.HTTPResponse;

public class HTTPBaseIO2Test {

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void testDoGet() {
String urltest = "http://localhost:8080/Test/Test1" ;
String charset="UTF-8";
HashMap<String, String> params=new HashMap<String, String>();
try {
params.put("val", "測試&測試");
HTTPResponse html=HTTPBaseIO2.doSend(urltest, HTTPBaseIO2.Method.get, params, charset,true,null,null);
System.out.println("testDoGet:"+html.getHtml());
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void testDoPost() {
String urltest = "http://localhost:8080/Test/Test1" ;
String charset="UTF-8";
HashMap<String, String> params=new HashMap<String, String>();
try {
params.put("val", "測試1&測試1");
HTTPResponse html=HTTPBaseIO2.doSend(urltest, HTTPBaseIO2.Method.post, params, charset,true,null,null);
System.out.println("testDoPost:"+html.getHtml());
params.clear();
params.put("val", "測試2&測試2");
html=HTTPBaseIO2.doSend(urltest, HTTPBaseIO2.Method.post, params, charset,true,null,null);
System.out.println("testDoPost:"+html.getHtml());
} catch (Exception e) {
e.printStackTrace();
}
}

}

[CentOS]JBoss5.1安裝

序言

此篇簡單的記錄JBoss在CentOS的安裝步驟。

環境

安裝步驟

  1. 官方網站下載JBoss的5.1.0版的zip檔如[jboss-5.1.0.GA.zip]
  2. 到[/usr/local/]目錄下解壓縮這個zip檔
    #cd /usr/local/
    #unzip jboss-5.1.0.GA.zip
  3. 建立環境變數[JBOSS_HOME],在這邊有兩種方式選一種來就可以了
    • 修改[/etc/profile],可以用如[vi /etc/profile]命令修改,增加已下內容在最後一行:
      export JBOSS_HOME=/usr/local/jboss-5.1.0.GA
      export PATH=$PATH:$JBOSS_HOME/bin
    • 建立一個[jboss.sh]在[/etc/profile.d]目錄,如[vi /etc/profile.d/jboss.sh],內容如下:
      JBOSS_HOME=/usr/local/jboss-5.1.0.GA
      PATH=$PATH:$JBOSS_HOME/bin
      export JBOSS_HOME PATH
  4. 登出再登入OS
  5. 執行JBoss看看有沒有辦法啟動,測試網址為http://localhost:8080/
    #sh $JBOSS_HOME/bin/run.sh -b 0.0.0.0
    • 如果看到以下錯誤訊息而無法啟動,試著修改[/usr/local/jboss-5.1.0.GA/bin/run.conf]這個檔案中的 java [-Xmx]與[-XX:MaxPermSize]這兩個參數的大小
      Error occurred during initialization of VM
      Could not reserve enough space for object heap
      Could not create the Java virtual machine.
  6. 如果要將JBoss已背景方式執行,並在OS啟動時自動啟動,可參考 http://community.jboss.org/wiki/startjbossonbootwithlinuxhttp://amjet.dyndns.biz/blog/IT/?p=297
    • 增加jboss帳號與修改目錄權限
      #useradd jboss
      #cd /usr/local/jboss-5.1.0.GA
      #chmod -R 700 ./
    • 修改[/usr/local/jboss-5.1.0.GA/bin/run.conf]檔,將以下內容加在最後一行
      JAVA_HOME=/usr/java/latest
      JBOSS_HOME=/usr/local/jboss-5.1.0.GA
      JBOSS_HOST=0.0.0.0
      JAVAPTH=/usr/java/latest
    • 修改[/usr/local/jboss-5.1.0.GA/bin/jboss_init_redhat.sh]檔,將以下內容加在第一行
      . /usr/local/jboss-5.1.0.GA/bin/run.conf
    • 修改[/etc/rc.local]檔,將以下內容加在最後一行
      /usr/local/jboss-5.1.0.GA/bin/jboss_init_redhat.sh start
    • 如果你想開啟/關閉JBoss就執行以下命令
      /usr/local/jboss-5.1.0.GA/bin/jboss_init_redhat.sh start
      /usr/local/jboss-5.1.0.GA/bin/jboss_init_redhat.sh stop

[CentOS]JDK(Java)安裝

序言

此篇簡單的記錄JDK在CentOS的安裝步驟,下一篇將會搭配這個Java環境安裝JBoss。

環境

安裝步驟

  1. 官方網站下載JDK的Linux版的RPM檔如[jdk-6u20-linux-i586-rpm.bin]
  2. 執行安裝命令[sh jdk-6u20-linux-i586-rpm.bin],此時會要求你同意授權條件。安裝完成後預設的安裝路徑會帶版號,如[/usr/java/jdk1.6.0_20]。建立一個jdk的目錄連結。
    #sh jdk-6u20-linux-i586-rpm.bin
    #cd /usr/local
    #ln –s /usr/java/jdk1.6.0_20 jdk
  3. 將此JVM加入系統可用Java
    #alternatives --install /usr/bin/java java /usr/java/latest 99
  4. 修改系統預設Java,執行此命令會要你選擇可用的Java編號
    #alternatives --config java
  5. 輸入已下命令確認是否有出現JAVA版本
    #java –version
  6. 建立環境變數[JAVA_HOME],在這邊有兩種方式選一種來就可以了
    • 修改[/etc/profile],可以用如[vi /etc/profile]命令修改,內容如下:
      export JAVA_HOME=/usr/java/latest
      export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
      export PATH=$PATH:$JAVA_HOME/bin
    • 建立一個[java.sh]在[/etc/profile.d]目錄,如[vi /etc/profile.d/java.sh],內容如下:
      JAVA_HOME=/usr/java/latest
      CLASSPATH=.:$JAVA_HOME/lib.tools.jar
      PATH=$JAVA_HOME/bin:$PATH
      export JAVA_HOME CLASSPATH PATH
  7. 登出再登入OS
  8. 輸入已下命令確認是否有出現環境變數值
    #echo $JAVA_HOME

[CentOS]MySQL安裝

序言

我依據我自己的環境記錄下我的安裝步驟以供自己參考。

環境

安裝步驟

  1. 官方網站下載MySQL的Linux版的TAR檔如[mysql-5.1.45-linux-i686-glibc23.tar.gz]
  2. 依據官方安裝步驟如下,執行最後一步會啟動MySQL
    #groupadd mysql
    #useradd -g mysql mysql
    #cd /usr/local
    #gunzip < /path/to/mysql-5.1.45-linux-i686-glibc23.tar.gz | tar xvf -
    #ln -s /usr/local/mysql-5.1.45-linux-i686-glibc23 mysql
    #cd mysql
    #chown -R mysql .
    #chgrp -R mysql .
    #scripts/mysql_install_db --user=mysql
    #chown -R root .
    #chown -R mysql data
    #bin/mysqld_safe --user=mysql &
  3. 如果有其他非本機的Client要連現這台DB需建立帳號,如果不綁IP安全性(代表從任何IP都能以該帳號連線)的帳號建立方式如下
    • 進入mysql命令模式
      # /usr/local/mysql/bin/mysql -u root
    • 建立帳號
      mysql>grant all on *.* to 帳號@ identified by '密碼' with grant option;
      mysql>FLUSH PRIVILEGES;
      mysql>quit;
  4. 關閉MySQL
    #/usr/local/mysql/bin/mysqladmin -u root shutdown
  5. 啟動MySQL
    #/usr/local/mysql/bin/mysqld_safe &
  6. 資料庫參數設定檔應該是在/etc/my.cnf,如果沒有可以從/usr/local/mysql-5.1.45-linux-i686-glibc23/support-files底下的*.cnf中挑適合的放在/etc/my.cnf
    • my-innodb-heavy-4G.cnf: 這是一個針對 4G RAM(主要運行只有 InnoDB 表的 MySQL 並使用幾個連接數執行複雜的查詢)。
    • my-huge.cnf: 適合 1GB - 2GB RAM的主機使用。
    • my-large.cnf: 適合 512MB RAM的主機使用。
    • my-medium.cnf: 只有 32MB - 64MB RAM 的主機使用,或者有 128MB RAM 但需要運行其他伺服器,例如 web server。
    • my-small.cnf: 記憶體少於 64MB 時適用這個,MySQL 會佔用較少資源。
  7. 將MySQL設為在OS啟動時自動啟動
    #cp /usr/local/mysql-5.1.45-linux-i686-glibc23/support-files/mysql.server /etc/rc.d/init.d/mysqld
    #chmod 700 /etc/init.d/mysqld
    #chkconfig --add mysqld
    #chkconfig --level 345 mysqld on
    

[Java]Http Get與Post函式(Apache HttpClient)

序言

要達到基本的Http get與post方法取得網站內容,Java內的URLConnection就可以達成
但我實作時發現它太過於底層,以致於我不知該如何做到關於Session狀態的延續,也就是不能夠在完成登入後,保留住登入狀態然後進入下個動作。
於是就尋求別的作法,最後發現了Apache有提供了HttpClient套件的JAR檔,能讓我們用更簡單的方式達成工作。
在此參考網路上的文章:用HttpClient來模擬瀏覽器GET,POST,加上可自動轉導的功能,包成函式。
另外再加上可用三種類型來設定傳遞的參數,並控制其連線與中斷狀態。

下載套件

HttpClient Download下載套件,選擇Binary with dependencies的版本(如4.0.1.zip),
我們需要的JAR在該壓縮檔中的lib目錄下。會用到的JAR檔有三個:
  • commons-logging-1.1.1.jar
  • httpclient-4.0.1.jar
  • httpcore-4.0.1.jar

函式原始碼

參數轉換函式
package common.control;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;

public class HTTPParseFunc {

/**
* hashMapToString
*
* @param map
* @param charset編碼
* ,如HTTP.UTF_8
* @return
* @throws UnsupportedEncodingException
*/
@SuppressWarnings("unchecked")
public static String hashMapToString(HashMap<String, String> map,
String charset) throws UnsupportedEncodingException {
StringBuffer result = new StringBuffer();
java.util.Iterator it = map.entrySet().iterator();
boolean isfirst = true;
while (it.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
if (isfirst) {
isfirst = false;
} else {
result.append("&");
}
result
.append(URLEncoder.encode(entry.getKey().toString(),
charset));
result.append("=");
result.append(URLEncoder.encode(entry.getValue().toString(),
charset));
}
return result.toString();
}
/**
* 將inputStream轉為String
*
* @param is
* inputStream
* @param charset
* 編碼,如HTTP.UTF_8
* @return inputStream的內容
* @throws UnsupportedEncodingException
*/
public static String inputStream2String(InputStream is, String charset)
throws UnsupportedEncodingException {
BufferedReader in = new BufferedReader(new InputStreamReader(is,
charset));
StringBuffer buffer = new StringBuffer();
String line = "";
try {
boolean isfirst = true;
while ((line = in.readLine()) != null) {
if (!isfirst) {
buffer.append("\n");
} else {
isfirst = false;
}
buffer.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}

return buffer.toString();
}

/**
* HTTP 傳輸參數分割
* @param param 如name1=value1&name2=value2
* @return
* @throws UnsupportedEncodingException
*/
public static ArrayList<String[]> paramToArray(String param)
throws UnsupportedEncodingException {
ArrayList<String[]> arr = null;
String[] p = param.split("&");
if (param.toLowerCase().contains("&amp;")) {
ArrayList<String> p2 = new ArrayList<String>();
int j = 0;
for (int i = 0; i < p.length; i++) {
if (p[i].toLowerCase().startsWith("amp;")) {
p2.set(j - 1, p2.get(j - 1) + "&amp;" + p[i].substring(4));
j--;
}
p2.add(p[i]);
j++;
}
p2.toArray(p);
}

for (int i = 0; i < p.length; i++) {
String[] item = p[i].split("=");
if (item.length == 2) {
if (arr == null)
arr = new ArrayList<String[]>();
// item[0]=URLDecoder.decode(item[0],charset);
// item[1]=URLDecoder.decode(item[1],charset);
arr.add(item);
}
}
return arr;
}
}

HTTP連線函式
package common;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import common.control.HTTPParseFunc;

public class HTTPBaseIO {
public enum Method {
get, post
}

private DefaultHttpClient httpclient = null;
private boolean isClosedConn = false;
private String newuri = null;
private int statuscode = HttpStatus.SC_NO_CONTENT;

private HttpHost proxy = null;

private Integer timeout=null;

public HTTPBaseIO(){

}
public HTTPBaseIO(String proxyIP,int proxyPort){
setProxy(proxyIP,proxyPort);
}
public HTTPBaseIO(HttpHost proxy){
setProxy(proxy);
}

/**
* 取得使用的proxy
*/
public HttpHost getProxy() {
return proxy;
}

/**
* 設定proxy
*/
public void setProxy(HttpHost proxy) {
this.proxy = proxy;
}

/**
* 設定proxy
*
* @param ip
* proxy的IP(hostname)
* @param port
* proxy的Port
*/
public void setProxy(String ip, int port) {
if(ip!=null)
proxy = new HttpHost(ip, port);
}

/**
* 取得回應後所得到的代碼,可參考org.apache.http.HttpStatus類別
*
* @return org.apache.http.HttpStatus
*/
public int getStatuscode() {
return statuscode;
}

/**
* 如果是轉導的狀態所得到的URI
*
* @return
*/
public String getNewuri() {
return newuri;
}

public void resetNewuri() {
newuri = null;
}

/**
* 取得連線物件
*
* @return
*/
public DefaultHttpClient getHttpclient() {
return httpclient;
}

/**
* 設定連線物件
*
* @param httpclient
*/
public void setHttpclient(DefaultHttpClient httpclient) {
this.httpclient = httpclient;
}

/**
* 是否已關閉連線
*
* @return
*/
public boolean isClosedConn() {
return isClosedConn;
}

/**
* 關閉連線
*/
public void closeConn() {
closeConn(true);
}

/**
* 關閉連線
*
* @param isCloseConn
* 是否關閉
*/
public void closeConn(boolean isCloseConn) {
if (isCloseConn && httpclient != null && !isClosedConn) {
httpclient.getConnectionManager().shutdown();
httpclient = null;
isClosedConn = true;
}
}

public void setHttpConnectionFactoryTimeout(Integer milliseconds){
timeout=milliseconds;
}

/**
* 取得網頁內容
*
* @param urlpath
* 網址
* @param method
* Method.get or Method.post
* @param params
* 參數
* @param charset
* 編碼,如HTTP.UTF_8
* @param isAutoRedirect
* 如果網頁回應狀態為轉導到新網頁,且Header的location有值,則自己以location所指網址取得內容
* @param isCloseConn
* 是否關閉連線
* @return 失敗回傳null,成功回傳網頁HTML
* @throws ClientProtocolException
* @throws IOException
*/
public String doSend(String urlpath, Method method, String params,
String charset, boolean isAutoRedirect, boolean isCloseConn)
throws ClientProtocolException, IOException {
return doSendBase(urlpath, method, StringToHttpEntity(params, charset),
charset, isAutoRedirect, isCloseConn);
}

/**
* 取得網頁內容
*
* @param urlpath
* 網址
* @param method
* Method.get or Method.post
* @param params
* 參數
* @param charset
* 編碼,如HTTP.UTF_8
* @param isAutoRedirect
* 如果網頁回應狀態為轉導到新網頁,且Header的location有值,則自己以location所指網址取得內容
* @param isCloseConn
* 是否關閉連線
* @return 失敗回傳null,成功回傳網頁HTML
* @throws ClientProtocolException
* @throws IOException
*/
public String doSend(String urlpath, Method method,
List<NameValuePair> params, String charset, boolean isAutoRedirect,
boolean isCloseConn) throws ClientProtocolException, IOException {
return doSendBase(urlpath, method, ListToHttpEntity(params, charset),
charset, isAutoRedirect, isCloseConn);
}

/**
* 取得網頁內容
*
* @param urlpath
* 網址
* @param method
* Method.get or Method.post
* @param params
* 參數
* @param charset
* 編碼,如HTTP.UTF_8
* @param isAutoRedirect
* 如果網頁回應狀態為轉導到新網頁,且Header的location有值,則自己以location所指網址取得內容
* @param isCloseConn
* 是否關閉連線
* @return 失敗回傳null,成功回傳網頁HTML
* @throws ClientProtocolException
* @throws IOException
*/
public String doSend(String urlpath, Method method,
HashMap<String, String> params, String charset,
boolean isAutoRedirect, boolean isCloseConn)
throws ClientProtocolException, IOException {
return doSendBase(urlpath, method,
HashMapToHttpEntity(params, charset), charset, isAutoRedirect,
isCloseConn);
}

/**
* 取得網頁內容
*
* @param urlpath
* 網址
* @param method
* Method.get or Method.post
* @param params
* 參數
* @param charset
* 編碼,如HTTP.UTF_8
* @param isAutoRedirect
* 如果網頁回應狀態為轉導到新網頁,且Header的location有值,則自己以location所指網址取得內容
* @param isCloseConn
* 是否關閉連線
* @return 失敗回傳null,成功回傳網頁HTML
* @throws ClientProtocolException
* @throws IOException
*/
public String doSendBase(String urlpath, Method method, HttpEntity params,
String charset, boolean isAutoRedirect, boolean isCloseConn)
throws ClientProtocolException, IOException {
String responseBody = null;
HttpUriRequest httpgetpost = null;

statuscode = HttpStatus.SC_NO_CONTENT;
try {
if (httpclient == null || isClosedConn())
httpclient = new DefaultHttpClient();

if (proxy != null)
httpclient.getParams().setParameter(
ConnRoutePNames.DEFAULT_PROXY, proxy);

if(timeout!=null){
HttpParams param = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(param, timeout);
HttpConnectionParams.setSoTimeout(param, timeout);
}


if (method == Method.post) {
httpgetpost = new HttpPost(urlpath);
if (params != null) {
((HttpPost) httpgetpost).setEntity(params);
}
} else {
if (params != null) {
urlpath += "?"
+ HTTPParseFunc.inputStream2String(params.getContent(), charset);
}
httpgetpost = new HttpGet(urlpath);
}

HttpResponse response = httpclient.execute(httpgetpost);
statuscode = response.getStatusLine().getStatusCode();
if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY)
|| (statuscode == HttpStatus.SC_MOVED_PERMANENTLY)
|| (statuscode == HttpStatus.SC_SEE_OTHER)
|| (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
Header header = response.getFirstHeader("location");

if (header != null) {
newuri = header.getValue();
if ((newuri == null) || (newuri.equals("")))
newuri = "/";
if (isAutoRedirect) {
httpgetpost.abort();
httpgetpost = null;
responseBody = doSendBase(newuri, Method.get, null,
charset, true, false);
}
}
} else if (statuscode == HttpStatus.SC_OK) {
responseBody = HTTPParseFunc.inputStream2String(response.getEntity()
.getContent(), charset);
}
} catch (ClientProtocolException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (httpgetpost != null) {
httpgetpost.abort();
httpgetpost = null;
}
closeConn(isCloseConn);
}
return responseBody;
}

/**
* List<NameValuePair>轉為HttpEntity
*
* @param nvps
* @param charset
* 編碼,如HTTP.UTF_8
* @return
* @throws UnsupportedEncodingException
*/
public static HttpEntity ListToHttpEntity(List<NameValuePair> nvps,
String charset) throws UnsupportedEncodingException {
HttpEntity result = null;
if (nvps != null && nvps.size() > 0) {
result = new UrlEncodedFormEntity(nvps, charset);

}
return result;
}

/**
* String to HttpEntity(
*
* @param nvps
* @param charset
* 編碼,如HTTP.UTF_8
* @return
* @throws UnsupportedEncodingException
*/
public static HttpEntity StringToHttpEntity(String nvps, String charset)
throws UnsupportedEncodingException {
HttpEntity result = null;
if (nvps != null) {
StringEntity reqEntity = new StringEntity(nvps, charset);
reqEntity.setContentType("application/x-www-form-urlencoded");
result = reqEntity;
}
return result;
}

/**
* HashMap To HttpEntity
*
* @param nvps
* @param charset
* 編碼,如HTTP.UTF_8
* @return
* @throws UnsupportedEncodingException
*/
public static HttpEntity HashMapToHttpEntity(HashMap<String, String> nvps,
String charset) throws UnsupportedEncodingException {
HttpEntity result = null;
if (nvps != null) {
result = new StringEntity(HTTPParseFunc.hashMapToString(nvps, charset), charset);
try {
result = StringToHttpEntity(HTTPParseFunc.inputStream2String(result
.getContent(), charset), charset);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}

}

使用範例程式

package common.test;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import common.HTTPBaseIO;
import common.control.HTTPParseFunc;

public class HTTPBaseIOTest {

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void testDoGet() {
String urltest = "http://www.google.com.tw";
String charset = "UTF-8";
HTTPBaseIO.Method method = HTTPBaseIO.Method.get;
HTTPBaseIO reqClient = new HTTPBaseIO();
try {
String html = reqClient.doSendBase(urltest, method, null, charset,
false, false);
System.out.println(html);
if (html == null)
fail("Client get nothing");
} catch (Exception e) {
e.printStackTrace();
} finally {
reqClient.closeConn();
}
}

@Test
public void testDoPost() {
String urlserv1 = "http://localhost/Test1/Serv1";
String urlserv2 = "http://localhost/Test1/Serv2";
String charset = HTTP.UTF_8;
HTTPBaseIO.Method method = HTTPBaseIO.Method.post;
HTTPBaseIO reqClient = new HTTPBaseIO();
try {
HashMap<String, String> map = new HashMap<String, String>();
map.put("jobname", "login");
map.put("id", "aaa");
map.put("pswd", "1234");
String html = reqClient.doSend(urlserv1, method, map, charset,
false, false);
System.out.println(html);

ArrayList<String[]> arr = HTTPParseFunc.paramToArray(html);
for (int i = 0; i < arr.size(); i++)
System.out.println(arr.get(i)[0] + "=" + arr.get(i)[1]);
if (html == null)
fail("Login get nothing");

String param = "jobname=getname";
html = reqClient.doSend(urlserv1, method, param, charset, false,
false);
System.out.println(html);
if (html == null)
fail("getname get nothing");

List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("jobname", "loadserv2"));
nvps.add(new BasicNameValuePair("name", "aaa"));
reqClient.resetNewuri();
html = reqClient.doSend(urlserv1, method, nvps, charset, true,
false);
if (html == null)
fail("loadserv2 get nothing");
nvps.clear();
if (reqClient.getNewuri() != null && html != null) {
nvps.add(new BasicNameValuePair("jobname", "getname2"));
html = reqClient.doSend(urlserv2, method, nvps, charset, false,
false);
System.out.println(html);
if (html == null)
fail("Name get nothing");
nvps.clear();
}
nvps.clear();

nvps.add(new BasicNameValuePair("jobname", "Logout"));
html = reqClient.doSend(urlserv1, method, nvps, charset, false,
false);
System.out.println(html);
if (html == null)
fail("Logout get nothing");
nvps.clear();
} catch (Exception e) {
e.printStackTrace();
} finally {
reqClient.closeConn();
}
}

}

總結

在範例的地方我假設了兩個servlet用來接收傳遞的參數,這部份可能不能直接執行,不過函式我測試過是沒問題的。
使用時可選擇用Hashmap、String、或是List作為參數設定,我分別在範例中都使用過了。
轉跳時可用getNewuri函式來確認是否有取得轉跳的網址,用回傳的html來確認是否有抓到回應的內容。
PS.我發現了Apache提供的這個Client在Windows下會有連線數上限的問題(聽說好像調整XP連線數可以解決)。

[Java]MySQL/Oracle資料庫存取函式

序言

延續上一篇,這篇針對MySQL資料庫的存取寫出的函式提供給大家參考,開發環境與資料庫連接器的設定可參考上一篇。
我在這邊有兩種建立連線物件的方式,預設是來自JNDI的連線設定,另一種是直接產生的方式,可在建立物件時做選擇。
使用範例的部分我改用JUnit來進行我自己的原始碼驗證,大家可直接參考呼叫的方式。
PS.2011/6/21 更新,加入Oracle的連線方法(但分頁查詢的函式只能用在MySQL)

原始碼函式類別

package common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DBBaseIO {
private static boolean _isDebug=false;
public enum DBType{
MySQL
,Oracle
}

public static void setDebug(boolean isDebug) {
_isDebug = isDebug;
}

public static boolean isIsdebug() {
return _isDebug;
}

private Connection con = null; // Database objects
public Connection getConnection() {
return con;
}

private Statement stat = null;
private ResultSet rs = null;
private PreparedStatement pst = null;
private boolean isClosed=false;
public boolean isClosedConn(){
return isClosed;
}

protected void finalize () {
if(!isClosed)CloseConn();
}

/**
* 建立資料庫存取物件(使用JNDI XML設定,名稱為MySqlDS)
* @throws SQLException
* @throws NamingException
*/
public DBBaseIO() throws SQLException, NamingException {
setupConnMySQLByXML();
}
/**
* 建立資料庫存取物件(使用JNDI XML設定)
* @param dsName 設定名稱
* @throws SQLException
* @throws NamingException
*/
public DBBaseIO(String dsName) throws SQLException, NamingException {
setupConnMySQLByXML(dsName);
}
/**
*
* @param sourceType
* @throws ClassNotFoundException
* @throws SQLException
* @throws NamingException
*/
public DBBaseIO(int sourceType) throws ClassNotFoundException, SQLException, NamingException{
switch(sourceType){
case 0:
setupConnMySQL("localhost:3306", "root", "", "mysql");
break;
case 1:
setupConnMySQLByXML();
break;
}
}
/**
* 建立資料庫存取物件
*
* @param str_SQLIP
* 資料庫IP
* @param str_SQLID
* 登入帳號
* @param str_SQLPSWD
* 登入密碼
* @param str_SQLDefaultDBName
* 預設資料庫
* @throws SQLException
* @throws ClassNotFoundException
*/
public DBBaseIO(String str_SQLIP, String str_SQLID, String str_SQLPSWD,
String str_SQLDefaultDBName) throws ClassNotFoundException, SQLException {
setupConnMySQL(str_SQLIP, str_SQLID, str_SQLPSWD, str_SQLDefaultDBName);
}
/**
* 建立資料庫存取物件
*
* @param dbtype
* 資料庫類型
* @param str_SQLIP
* 資料庫IP
* @param str_SQLID
* 登入帳號
* @param str_SQLPSWD
* 登入密碼
* @param str_SQLDefaultDBName
* 預設資料庫
* @throws SQLException
* @throws ClassNotFoundException
*/
public DBBaseIO(DBType dbtype,String str_SQLIP, String str_SQLID, String str_SQLPSWD,
String str_SQLDefaultDBName) throws ClassNotFoundException, SQLException {
if(dbtype==DBType.MySQL)
setupConnMySQL(str_SQLIP, str_SQLID, str_SQLPSWD, str_SQLDefaultDBName);
else if(dbtype==DBType.Oracle)
setupConnOracle(str_SQLIP, str_SQLID, str_SQLPSWD, str_SQLDefaultDBName);
else
throw new ClassNotFoundException("DBType un-define");
}
private void setupConnMySQLByXML() throws NamingException, SQLException{setupConnMySQLByXML("MySqlDS"); }
private void setupConnMySQLByXML(String name) throws NamingException, SQLException{
if(isIsdebug()){
System.out.println("DataSource:"+"java:/" + name);
}

try{
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:/" + name);
con = ds.getConnection();
} catch (NamingException e) {
System.err.println("Connection XML Load Error :" + e.toString());
throw e;
} catch (SQLException e) {
System.err.println("Get Connection Error :" + e.toString());
throw e;
}
}

private void setupConnMySQL(String str_SQLIP, String str_SQLID,
String str_SQLPSWD, String str_SQLDefaultDBName) throws ClassNotFoundException,SQLException {
if(isIsdebug()){
System.out.println("DataSource:"+"jdbc:mysql://" + str_SQLIP + "/"
+ str_SQLDefaultDBName
+ "?useUnicode=true&characterEncoding=UTF8");
System.out.println("ID:"+str_SQLID+"\tPassword:"+str_SQLPSWD);
System.out.println("JDBC Driver:" + "com.mysql.jdbc.Driver");
}
try {
Class.forName("com.mysql.jdbc.Driver");

con = DriverManager.getConnection("jdbc:mysql://" + str_SQLIP + "/"
+ str_SQLDefaultDBName
+ "?useUnicode=true&characterEncoding=UTF8", str_SQLID,
str_SQLPSWD);

} catch (ClassNotFoundException e) {
System.err.println("DriverClassNotFound :" + e.toString());
throw e;
}
catch (SQLException x) {
System.err.println("Exception :" + x.toString());
throw x;
}
}
private void setupConnOracle(String str_SQLIP, String str_SQLID,
String str_SQLPSWD, String str_SQLDefaultDBName) throws ClassNotFoundException,SQLException {
if(isIsdebug()){
System.out.println("DataSource:"+"jdbc:oracle:thin:"+str_SQLID+"/"+str_SQLPSWD+"@//" + str_SQLIP + "/"
+ str_SQLDefaultDBName);
}
try {
Class.forName("oracle.jdbc.OracleDriver");

con = DriverManager.getConnection("jdbc:oracle:thin:"+str_SQLID+"/"+str_SQLPSWD+"@//" + str_SQLIP + "/"
+ str_SQLDefaultDBName);

} catch (ClassNotFoundException e) {
System.err.println("DriverClassNotFound :" + e.toString());
throw e;
}
catch (SQLException x) {
System.err.println("Exception :" + x.toString());
throw x;
}
}

/**
* 執行insert update delete等更新指令用
*
* @param str_SQL
* 查詢語法
* @return 資料庫變動筆數
*/
public int executeUpdate(String str_SQL) throws SQLException,NullPointerException {
return executeUpdate(str_SQL, null);
}

/**
* 執行insert update delete等更新指令用
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @return 資料庫變動筆數
*/
public int executeUpdate(String str_SQL, Object[] param) throws SQLException ,NullPointerException{
return executeUpdate(str_SQL, param, true);
}

/**
* 執行insert update delete等更新指令用
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @param isCloseConn
* 是否關閉連線
* @return 資料庫變動筆數
*/
public int executeUpdate(String str_SQL, Object[] param, boolean isCloseConn) throws SQLException,NullPointerException {
if(isIsdebug()){
System.out.println("executeUpdate:"+str_SQL);
if(param!=null)
for(int i=0;i<param.length;i++)
System.out.println("Parameter "+ i +":"+param[i]);
System.out.println("isCloseConn :"+isCloseConn);
}

int result = 0;
if (con != null) {
try {
int i = 0;
if (param == null) {
stat = con.createStatement();
result = stat.executeUpdate(str_SQL);
} else {
pst = con.prepareStatement(str_SQL);
for (i = 0; i < param.length; i++) {
pst.setObject(i + 1, param[i]);
}
result = pst.executeUpdate();
try {
pst.clearParameters();
} catch (Exception e) {
CloseConn();
}
}
} catch (SQLException e) {
System.err.println("executeUpdate Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}
return result;
}


/**
* 批次執行SQL指令使用
*
* @param str_SQL
* 查詢語法的陣列
* @param isCloseConn
* 是否關閉連線
* @return 資料庫變動筆數的陣列
*/
public int[] executeBatch(String[] str_SQL, boolean isCloseConn) throws SQLException,NullPointerException {
if(isIsdebug()){
System.out.println("executeBatch:"+str_SQL);
}

int[] result=null;
if (con != null) {
try {
int i = 0;
stat = con.createStatement();
for (i = 0; i < str_SQL.length; i++) {
stat.addBatch(str_SQL[i]);
}
result=stat.executeBatch();
if(isIsdebug()){
System.out.println("executeBatch result:");
for (i = 0; i < result.length; i++) {
System.out.println(i+":"+result[i]);
}
}
} catch (SQLException e) {
System.err.println("executeBatch Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}
return result;
}

/**
* 批次執行SQL指令使用
* @param str_SQL 查詢語法
* @param param 以相同數量的參數形成的ArrayList
* @param isCloseConn 是否關閉連線
* @return 資料庫變動筆數的陣列
* @throws SQLException
* @throws NullPointerException
*/
public int[] addBatch(String str_SQL, ArrayList<Object[]> param, boolean isCloseConn) throws SQLException,NullPointerException {

int i = 0;
int j = 0;
if(isIsdebug()){
System.out.println("executeBatch:"+str_SQL);
if(param!=null)
for (i = 0; i < param.size(); i++) {
for (j = 0;j < param.get(i).length; j++) {
System.out.println("Parameter "+ i+","+j +":"+param.get(i)[j]);
}
}
}

int[] result=null;
if (con != null) {
try {
pst = con.prepareStatement(str_SQL);
for (i = 0; i < param.size(); i++) {
for (j = 0;j < param.get(i).length; j++) {
pst.setObject(j + 1, param.get(i)[j]);
}
pst.addBatch();
}
result=pst.executeBatch();
if(isIsdebug()){
System.out.println("executeBatch result:");
for (i = 0; i < result.length; i++) {
System.out.println(i+":"+result[i]);
}
}
} catch (SQLException e) {
System.err.println("executeBatch Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}

return result;
}

/**
* 查詢資料
*
* @param str_SQL
* 查詢語法
* @return 每列一筆資料,每筆資料的欄位存於 Object Array中
*/
public ArrayList<Object[]> executeQuery(String str_SQL) throws SQLException,NullPointerException {
return executeQuery(str_SQL, null);
}
/**
* 查詢資料
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @return 每列一筆資料,每筆資料的欄位存於 Object Array中
*/
public ArrayList<Object[]> executeQuery(String str_SQL, Object[] param) throws SQLException,NullPointerException {
return executeQuery(str_SQL, param, true);
}

/**
* 查詢資料
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @param isCloseConn
* 是否關閉連線
* @return 每列一筆資料,每筆資料的欄位存於 Object Array中
*/
public ArrayList<Object[]> executeQuery(String str_SQL, Object[] param,
boolean isCloseConn) throws SQLException,NullPointerException {
if(isIsdebug()){
System.out.println("executeQuery:"+str_SQL);
if(param!=null)
for(int i=0;i<param.length;i++)
System.out.println("Parameter "+ i +":"+param[i]);
System.out.println("isCloseConn :"+isCloseConn);
}
ArrayList<Object[]> result = new ArrayList<Object[]>();
if (con != null) {
try {
int i = 0;
if (param == null) {
stat = con.createStatement();
rs = stat.executeQuery(str_SQL);
} else {
pst = con.prepareStatement(str_SQL);
for (i = 0; i < param.length; i++) {
pst.setObject(i + 1, param[i]);
}
rs = pst.executeQuery();
pst.clearParameters();
}

ArrayList<Object> arr;
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
while (rs.next()) {
arr = new ArrayList<Object>();
for (i = 1; i < numberOfColumns + 1; i++) {
arr.add(rs.getObject(i));
}
result.add(arr.toArray());
}
} catch (SQLException e) {
System.err.println("executeQuery Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}
return result;
}

/**
* 查詢資料(請記得要關閉Result Set)
*
* @param str_SQL
* 查詢語法
* @return 回傳查詢得到的result set
*/
public ResultSet executeQueryResultset(String str_SQL) throws SQLException,NullPointerException {
return executeQueryResultset(str_SQL,null);
}
/**
* 查詢資料(請記得要關閉Connection)
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @return 回傳查詢得到的result set
*/
public ResultSet executeQueryResultset(String str_SQL, Object[] param) throws SQLException,NullPointerException {
if(isIsdebug()){
System.out.println("executeQuery:"+str_SQL);
if(param!=null)
for(int i=0;i<param.length;i++)
System.out.println("Parameter "+ i +":"+param[i]);
}

ResultSet result = null;
if (con != null) {
try {
int i = 0;
if (param == null) {
stat = con.createStatement();
rs = stat.executeQuery(str_SQL);
} else {
pst = con.prepareStatement(str_SQL);
for (i = 0; i < param.length; i++) {
pst.setObject(i + 1, param[i]);
}
rs = pst.executeQuery();
pst.clearParameters();
}

result=rs;
} catch (SQLException e) {
System.err.println("executeQueryResultset Exception :" + e.toString());
throw e;
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}
return result;
}

/**
* 查詢資料,並傳回查詢所傳回的結果集第一個資料列的第一個資料行
*
* @param str_SQL
* 查詢語法
* @return 每列一筆資料,每筆資料的欄位存於 Object Array中
*/
public Object executescalar(String str_SQL) throws SQLException,NullPointerException {
return executescalar(str_SQL, null);
}
/**
* 查詢資料,並傳回查詢所傳回的結果集第一個資料列的第一個資料行
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @return 每列一筆資料,每筆資料的欄位存於 Object Array中
*/
public Object executescalar(String str_SQL, Object[] param) throws SQLException,NullPointerException {
return executescalar(str_SQL, param, true);
}

/**
* 查詢資料,並傳回查詢所傳回的結果集第一個資料列的第一個資料行
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @param isCloseConn
* 是否關閉連線
* @return 每列一筆資料,每筆資料的欄位存於 Object Array中
*/
public Object executescalar(String str_SQL, Object[] param,
boolean isCloseConn) throws SQLException,NullPointerException {
if(isIsdebug()){
System.out.println("executeQuery:"+str_SQL);
if(param!=null)
for(int i=0;i<param.length;i++)
System.out.println("Parameter "+ i +":"+param[i]);
System.out.println("isCloseConn :"+isCloseConn);
}
Object result = null;
if (con != null) {
try {
int i = 0;
if (param == null) {
stat = con.createStatement();
rs = stat.executeQuery(str_SQL);
} else {
pst = con.prepareStatement(str_SQL);
for (i = 0; i < param.length; i++) {
pst.setObject(i + 1, param[i]);
}
rs = pst.executeQuery();
pst.clearParameters();
}

ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
if (rs.next() && numberOfColumns>=1) {
result=rs.getObject(1);
}
} catch (SQLException e) {
System.err.println("executescalar Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}
return result;
}


/**
* 執行SQL
*
* @param str_SQL
* 查詢語法
* @return 是否成功
*/
public boolean execute(String str_SQL) throws SQLException,NullPointerException {
return execute(str_SQL, null);
}

/**
* 執行SQL
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @return 是否成功
*/
public boolean execute(String str_SQL, Object[] param) throws SQLException,NullPointerException {
return execute(str_SQL, param, true);
}

/**
* 執行SQL
*
* @param str_SQL
* 查詢語法
* @param param
* 參數設定,SQL語法中以?指定,順序即為?的順序,如 where name=? (此參數可為null)
* @param isCloseConn
* 是否關閉連線
* @return 是否成功
*/
public boolean execute(String str_SQL, Object[] param, boolean isCloseConn) throws SQLException,NullPointerException {
if(isIsdebug()){
System.out.println("executeQuery:"+str_SQL);
if(param!=null)
for(int i=0;i<param.length;i++)
System.out.println("Parameter "+ i +":"+param[i]);
System.out.println("isCloseConn :"+isCloseConn);
}
boolean result = false;
if (con != null) {
try {
int i = 0;
if (param == null) {
stat = con.createStatement();
result = stat.execute(str_SQL);
} else {
pst = con.prepareStatement(str_SQL);
for (i = 0; i < param.length; i++) {
pst.setObject(i + 1, param[i]);
}
result = pst.execute();
pst.clearParameters();
}
} catch (SQLException e) {
System.err.println("execute Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
} else {
System.err.println("Connection is null");
throw new NullPointerException("Connection is null");
}
return result;
}
/**
* 關閉連線
*/
public void CloseConn() {
CloseConn(true);
}

/**
* 關閉連線
* @param isCloseConn 是否關閉Connection
*/
public void CloseConn(boolean isCloseConn) {
if(isIsdebug()){
System.out.println("CloseConn:"+isCloseConn);
}
try {
if (rs != null) {
rs.close();
rs = null;
}
if (stat != null) {
stat.close();
stat = null;
}
if (pst != null) {
pst.close();
pst = null;
}
} catch (SQLException e) {
//System.err.println("Close Exception :" + e.toString());
} finally {
try {
if (con != null && isCloseConn) {
con.close();
isClosed=true;
}
} catch (SQLException e) {
//System.err.println("Close Exception :" + e.toString());
}
}
}


int allpage=0;

public int getAllpage() {
return allpage;
}
public void setAllpage(int allpage) {
this.allpage = allpage;
}
/**
* 查詢分頁資料
* @param colunms
* @param from
* @param where
* @param group
* @param order
* @param fpage
* @param pages
* @return
* @throws SQLException
* @throws NullPointerException
*/
public ArrayList<Object[]> selectPage(String colunms,String from,String where,String group,String having,String order,int fpage,int pages) throws SQLException,NullPointerException{
return selectPage(colunms,from,where,group,having,order,fpage,pages,null);
}
/**
* 查詢分頁資料
* @param colunms
* @param from
* @param where
* @param group
* @param order
* @param fpage
* @param pages
* @param param
* @return
* @throws SQLException
* @throws NullPointerException
*/
public ArrayList<Object[]> selectPage(String colunms,String from,String where,String group,String having,String order,int fpage,int pages, Object[] param) throws SQLException,NullPointerException{
return selectPage(colunms,from,where,group,having,order,fpage,pages,param,true);
}
/**
* 查詢分頁資料
* @param colunms
* @param from
* @param where
* @param group
* @param order
* @param fpage
* @param pages
* @param param
* @param isCloseConn
* @return
* @throws SQLException
* @throws NullPointerException
*/
public ArrayList<Object[]> selectPage(String colunms,String from,String where,String group,String having,String order,int fpage,int pages, Object[] param, boolean isCloseConn) throws SQLException,NullPointerException{
return selectPage(colunms, from, where, group, having, order, fpage, pages, true, 0, param, isCloseConn);
}
/**
* 查詢分頁資料
* @param colunms
* @param from
* @param where
* @param group
* @param having
* @param order
* @param fpage
* @param pages
* @param isCountPage
* @param allpageCount
* @param param
* @param isCloseConn
* @return
* @throws SQLException
* @throws NullPointerException
*/
public ArrayList<Object[]> selectPage(String colunms,String from,String where,String group,String having,String order,int fpage,int pages,boolean isCountPage,int allpageCount, Object[] param, boolean isCloseConn) throws SQLException,NullPointerException{
ArrayList<Object[]> result=null;
try{
String sql;
if(!isCountPage){
allpage=allpageCount;
}else{
int intRowCount;
sql="select count(*) from (select ";
if(colunms!=null){
sql+="" + colunms + " \n ";
}else{
sql+="* \n ";
}
sql+="from " + from.toString() + " \n ";
if(where!=null){
sql+="where " + where + " \n ";
}
if(group!=null){
sql+="group by " + group + " \n ";
}
if(having!=null){
sql+="having " + group + " \n ";
}
sql+=") selectcount \n ";

Object temp=executescalar(sql,param,false);
if(temp==null){
return result;
}
intRowCount=Integer.parseInt(temp.toString());
allpage=(intRowCount+fpage-1) / fpage;
}
int spage;

if(pages > allpage ){// pages == 0){
pages = 1;
}
spage=(pages-1)*fpage;
//sql="select " + colunms + " \n from " + from + " \n where " + where + " \n order by " + order + " \n limit "+ spage +","+fpage ;
sql="select ";
if(colunms!=null){
sql+= colunms + " \n ";
}else{
sql+="* \n ";
}
sql+="from " + from + " \n ";
if(where!=null){
sql+="where " + where + " \n ";
}
if(group!=null){
sql+="group by " + group + " \n ";
}
if(having!=null){
sql+="having " + group + " \n ";
}
if(order!=null){
sql+="order by " + order + " \n ";
}
sql+="limit "+ spage +","+fpage;
result=executeQuery(sql, param, false);
} catch (NullPointerException e) {
System.err.println("NullPointerException Exception :" + e.toString());
throw e;
} catch (SQLException e) {
System.err.println("SQLException Exception :" + e.toString());
throw e;
} finally {
CloseConn(isCloseConn);
}
return result;
}

}

使用範例程式

package common.test;

import static org.junit.Assert.*;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import common.DBBaseIO;

public class DBBaseIOTest {

DBBaseIO dbio;
int m_id;

String m_name;
@Before
public void setUp() throws Exception {
dbio=new DBBaseIO(0);
m_id=20100111;
m_name="tester" + m_id;
}

@After
public void tearDown() throws Exception {
dbio.CloseConn();
dbio=null;
}

@Test
public void testExecuteString() {
String msg="\n# testExecuteString\n Drop and Create :\t TestTable" + m_id;
System.out.println(msg);//DROP TABLE IF EXISTS TestTable" + m_id + ";
String str_Sql = "CREATE TABLE TestTable" + m_id + " ( " +
"`test_id` int(10) unsigned NOT NULL auto_increment, " +
"`member_id` int(10) unsigned NOT NULL, "+
"`member_name` varchar(45) NOT NULL, " +
"PRIMARY KEY (`test_id`) "+
") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ";
try{
dbio.execute(str_Sql);

}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}
}

@Test
public void testExecuteUpdateString() {
String msg="\n# testExecuteUpdateString\n Insert :\tID=" + m_id + "\tName=" + m_name;
System.out.println(msg);
String str_Sql="Insert into TestTable" + m_id + " (member_id,member_name) values('" + m_id + "','" + m_name + "')";
try{
int result=dbio.executeUpdate(str_Sql);
if(result<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}
}

@Test
public void testExecuteQueryString() {
String msg="\n# testExecuteQueryString\n Select ALL :";
System.out.println(msg);
String str_Sql="Select * from TestTable" + m_id + "";
try{
ArrayList<Object[]> result=dbio.executeQuery(str_Sql);
if(result.size()<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}else{
for(int i=0;i<result.size();i++){
for(int j=0;j<result.get(i).length;j++){
System.out.print(result.get(i)[j] + "\t");
}
System.out.println();
}
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}
}

@Test
public void testexecuteQueryResultset() {
String msg="\n# testexecuteQueryResultset\n Select ALL :";
System.out.println(msg);
String str_Sql="Select * from TestTable" + m_id + "";
try{

ResultSet rs=dbio.executeQueryResultset(str_Sql);
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
while (rs.next()) {
for (int i = 1; i < numberOfColumns + 1; i++) {
System.out.print(rs.getObject(i) + "\t");
}
System.out.println();
}

dbio.CloseConn();
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}
}

@Test
public void testselectPage() {
String msg="\n# testselectPage\n Insert 98 User";
System.out.println(msg);
String str_Sql="";
try{

for(int i=1;i<=98;i++){
str_Sql="Insert into TestTable" + m_id + " (member_id,member_name) values('" + m_id + i + "','" + m_name + "_" + i + "')";
int result=dbio.executeUpdate(str_Sql,null,false);
if(result<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}
}
str_Sql="";
ArrayList<Object[]> result=dbio.selectPage("member_id,member_name", "TestTable" + m_id, null, "member_id", 10, 10, null, true);
if(result.size()<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}else{
for(int i=0;i<result.size();i++){
for(int j=0;j<result.get(i).length;j++){
System.out.print(result.get(i)[j] + "\t");
}
System.out.println();
}
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}


}


@Test
public void testExecuteUpdateStringObjectArray() {
m_name+="_Updateed";
String msg="\n# testExecuteUpdateStringObjectArray\n Update :\tID=" + m_id + "\tName=" + m_name;
System.out.println(msg);
String str_Sql="Update TestTable" + m_id + " Set member_name=? WHERE member_id=?";
Object[] param={m_name,m_id};
try{
int result=dbio.executeUpdate(str_Sql,param);
if(result<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}
}

@Test
public void testExecuteQueryStringObjectArray() {
String msg="\n# testExecuteQueryStringObjectArray\n Select :\tID=" + m_id;
System.out.println(msg);
String str_Sql="Select * from TestTable" + m_id + " where member_id=?";
Object[] param={m_id};
try{
ArrayList<Object[]> result=dbio.executeQuery(str_Sql,param);
if(result.size()<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}else{
for(int i=0;i<result.size();i++){
for(int j=0;j<result.get(i).length;j++){
System.out.print(result.get(i)[j] + "\t");
}
System.out.println();
}
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}
}

@Test
public void testExecuteUpdateStringObjectArrayBoolean() {
String msg="\n# testExecuteUpdateStringObjectArrayBoolean\n Delete :\tID=" + m_id + "\tName=" + m_name;
System.out.println(msg);
String str_Sql="Delete from TestTable" + m_id + " WHERE member_id=?";
Object[] param={m_id};
try{
int result=dbio.executeUpdate(str_Sql,param,false);
if(result<=0){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}finally{
dbio.CloseConn();
}
}

@Test
public void testExecuteQueryStringObjectArrayBoolean() {
String msg="\n# testExecuteQueryStringObjectArrayBoolean\n Select :\tID=" + m_id;
System.out.println(msg);
String str_Sql="Select * from TestTable" + m_id + " where member_id=?";
Object[] param={m_id};
try{
ArrayList<Object[]> result=dbio.executeQuery(str_Sql,param,false);
if(result.size()>0){
for(int i=0;i<result.size();i++){
for(int j=0;j<result.get(i).length;j++){
System.out.print(result.get(i)[j] + "\t");
}
System.out.println();
}
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + result);
}
}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}finally{
dbio.CloseConn();
}
}





@Test
public void testExecuteStringObjectArrayBoolean() {
String msg="\n# testExecuteStringObjectArrayBoolean\n Drop :\t TestTable_" + m_id;
System.out.println(msg);
String str_Sql="DROP TABLE IF EXISTS TestTable" + m_id + ";" ;

try{
dbio.execute(str_Sql,null,false);

}catch(Exception e){
fail(msg + "\n\n" + str_Sql + "\n\nResult:" + e.getMessage());
}finally{
dbio.CloseConn();
}
}



}

總結

我在開發時採用ArrayList把資料給回傳回來,因此相反的就沒有辦法回傳欄位名稱(不過我想你在寫SQL時應該已經可以指定自己要用的欄位名稱了吧)。

相關文章

這裡是關於技術的手札~

也歡迎大家到

倫與貓的足跡



到噗浪來

關心一下我唷!
by 倫
 
Copyright 2009 倫倫3號Beta-Log All rights reserved.
Blogger Templates created by Deluxe Templates
Wordpress Theme by EZwpthemes