C#でMySQL用のDAO作成(以前教えてもらったAccess用DAO使用)
MyDummySQLという、MySQL用のダミーデータ作成ツールを作ろうかと思い、まずはMySQL用のDAOを作ってみました。Access用から流用したものです。
まだテストしていません。orz 明日か。。。
追記:テストしました。テストコードも以下に付加しています。
あ、MySQL Connector/NETが必要です。
http://dev.mysql.com/downloads/connector/net/5.0.html#downloads
ver6.3.8を使っています。
ソリューションエクスプロラーの参照設定を右クリックして、ダイアログの「参照タブ」から「C:/ProgramFiles/MySQL・・・・/v4.0/MySQL.Data.dll」を選択する必要があります。
以下のサイトを参考にしました。
http://www2.pf-x.net/~rafysta/memo/wiki.cgi?page=C%23%A4%C7MySQL%A4%CB%C0%DC%C2%B3
http://d.hatena.ne.jp/levin_gsp/20071204/1196754042
MySQLDAOContext.cs(MySQLのコネクションやトランザクションの管理オブジェクト)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MySql.Data.MySqlClient; namespace MyDummySQL.MySQLDAO { class MySQLDAOContext : IDisposable { //コネクション private MySqlConnection con_ = null; //private mysqlProviderFactory fac_ = null; //トランザクション private MySqlTransaction tran_ = null; //コネクション public MySqlConnection Connection { get { return this.con_; } private set { this.con_ = value; } } /*//DBファクトリは使わない public DbProviderFactory Factory { get { return this.fac_; } private set { this.fac_ = value; } } */ //トランザクション public MySqlTransaction Transaction { get { return this.tran_; } private set { this.tran_ = value; } } //デフォルトコンストラクタ //これはAccess用の接続文字列で他のコンストラクタを入れている->NGになる public MySQLDAOContext() : this("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|abc.mdb") { } //接続文字列を受け取るコンストラクタ public MySQLDAOContext(/*string providerName, */string connectionString) { //if (providerName == null) throw new ArgumentNullException("providerName"); if (connectionString == null) throw new ArgumentNullException("connectionString"); //this.Factory = DbProviderFactories.GetFactory(providerName); //this.Connection = this.Factory.CreateConnection(); this.Connection = new MySqlConnection(connectionString); this.Connection.ConnectionString = connectionString; } //コネクションオープン public void OpenConnection() { if (this.Connection == null) throw new InvalidOperationException("Object is diposed."); if (this.Connection.State == System.Data.ConnectionState.Closed) { this.Connection.Open(); this.Connection.GetSchema(); } } //コネクションクローズ public void CloseConnection() { if (this.Connection == null) throw new InvalidOperationException("Object is diposed."); if (this.Connection.State == System.Data.ConnectionState.Open) this.Connection.Close(); } //データベース変更 public void changeDatabase(string dbName) { this.Connection.ChangeDatabase(dbName); } //トランザクション開始(トランザクション分離レベルを指定) public void BeginTransaction(System.Data.IsolationLevel isolationLevel) { if (this.Transaction != null) throw new InvalidOperationException("There is already a transaction."); this.OpenConnection(); this.Transaction = this.Connection.BeginTransaction(isolationLevel); } //トランザクションコミット public void CommitTransaction() { if (this.Transaction == null) throw new InvalidOperationException("There is no transaction."); this.Transaction.Commit(); this.Transaction = null; } //トランザクションロールバック public void RollbackTransaction() { if (this.Transaction == null) throw new InvalidOperationException("There is no transaction."); this.Transaction.Rollback(); this.Transaction = null; } //アンマネージドリソース解放 public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); //ガベージコレクタファイナライズ処理 } //Dispose protected virtual void Dispose(bool disposing) { if (disposing) //Dispose中? { try { if (this.Transaction != null) { this.RollbackTransaction(); //トランザクションをロールバック this.Transaction = null; } } finally //最終的に必ず行われる処理 { if (this.Connection != null) { this.Connection.Dispose(); //コネクション(アンマネージドリソース)解放 this.Connection = null; } } } } } }
MySQLDAOBase.cs(MySQL用DAOのベースクラス)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MySql.Data.MySqlClient; using System.Data; namespace MyDummySQL.MySQLDAO { class MySQLDAOBase { //SQL文中のバインド変数 private readonly Listparameters = new List (); //コネクションなど private MySQLDAOContext context_ = null; //コネクションなど public MySQLDAOContext Context { get { return this.context_; } private set { this.context_ = value; } } //バインド変数(IListに変換) public IList Parameters { get { return this.parameters; } } //コンストラクタ public MySQLDAOBase(MySQLDAOContext context) { if (context == null) throw new ArgumentNullException("context"); this.Context = context; } //バインド変数追加 public void AddParameter(string parameterName, DbType dbType, object value) { MySqlParameter p = new MySqlParameter(); p.ParameterName = parameterName; p.DbType = dbType; p.Value = value; this.parameters.Add(p); } //バインド変数クリア public void ClearParameters() { this.parameters.Clear(); } //SQL実行。実行ロジック自体は、actionデリゲートで行う。 protected void ExecuteCommand(string commandText, IEnumerable parameters, Action action) { MySqlCommand command = new MySqlCommand(commandText, this.Context.Connection); command.Connection = this.Context.Connection; command.Transaction = this.Context.Transaction; foreach (MySqlParameter parameter in parameters) command.Parameters.Add(parameter); action(command); } //DML(SELECT以外)実行。(独自のパラメータを指定してよい) protected int ExecuteNonQuery(string commandText, IEnumerable parameters) { int count = 0; this.ExecuteCommand(commandText, parameters, delegate(MySqlCommand command) { count = command.ExecuteNonQuery(); }); return count; } //DML(SELECT以外)実行。(パラメータはこのDAOのプロパティ) protected int ExecuteNonQuery(string commandText) { return this.ExecuteNonQuery(commandText, this.parameters); } //SELECT。DataTableで受け取る。(独自のパラメータを指定してよい) protected DataTable GetTable(string commandText, IEnumerable parameters) { DataTable table = new DataTable(); this.ExecuteCommand(commandText, parameters, delegate(MySqlCommand command) { using (MySqlDataReader reader = command.ExecuteReader()) { table.Load(reader); } }); return table; } //SELECT。DataTableで受け取る。(パラメータはこのDAOのプロパティ) protected DataTable GetTable(string commandText) { return this.GetTable(commandText, this.Parameters); } } }
MySQLConString.cs(接続文字列生成):
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyDummySQL.MySQLDAO { class MySQLConString { private string conString_ = ""; public MySQLConString(string serverName, string userId, string password, string dbName, int port, bool isPooling) { string strgPooling = ""; if (isPooling) { strgPooling = "true"; } else { strgPooling = "false"; } this.conString_ = String.Format("server={0};user id={1}; password={2}; database={3}; port={4};pooling={5}; ", serverName, userId, password, dbName, port.ToString(), strgPooling); } public string ConString { get { return this.conString_; } } } }
テストテーブルt_table1用DAO:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MySql.Data.Types; using System.Data; namespace MyDummySQL.MySQLDAO { class t_table1Dao : MySQLDAOBase { public t_table1Dao(MySQLDAOContext con) : base(con) { } public DataTable select(int id) { string sql = @"select * from t_table1 where id = @pid"; this.ClearParameters(); this.AddParameter("pid", DbType.Int32, id); DataTable tbl = base.GetTable(sql); return tbl; } public DataTable selectAll() { string sql = @"select * from t_table1"; this.ClearParameters(); DataTable tbl = base.GetTable(sql); return tbl; } public int insert(string strgName) { string sql = @"insert into t_table1( name ) values( @pname )"; this.ClearParameters(); this.AddParameter("pname", DbType.String, strgName); return base.ExecuteNonQuery(sql); } public int update(int id, string name) { string sql = @"update t_table1 set name = @pname where id = @pid"; this.ClearParameters(); this.AddParameter("pname", DbType.String, name); this.AddParameter("pid", DbType.Int32, id); return base.ExecuteNonQuery(sql); } public int delete(int id) { string sql = @"delete from t_table1 where id = @pid"; this.ClearParameters(); this.AddParameter("pid", DbType.Int32, id); return base.ExecuteNonQuery(sql); } } }
テストテーブルt_table1のMySQLのDDL(テーブル作成SQL):
- -
- テーブルの構造 `t_table1`
- -
テストコード(Form1.cs内イベントハンドラ):
private MySQLDAO.MySQLConString getObjConstring() { int port = 0; int.TryParse(tbxPortNo.Text, out port); MySQLDAO.MySQLConString objConString = new MySQLDAO.MySQLConString( tbxServername.Text, tbxUserName.Text, tbxPassword.Text, tbxDbName.Text, port, false); return objConString; } private void btnTest1_Click(object sender, EventArgs e) { MySQLDAO.MySQLConString objConString = this.getObjConstring(); try { using (MySQLDAO.MySQLDAOContext con = new MySQLDAO.MySQLDAOContext(objConString.ConString)) { con.OpenConnection(); con.CloseConnection(); MessageBox.Show("success"); } } catch (MySql.Data.MySqlClient.MySqlException excep) { MessageBox.Show("error"); } } private void btnSqlTest_Click(object sender, EventArgs e) { MySQLDAO.MySQLConString objConString = this.getObjConstring(); using (MySQLDAO.MySQLDAOContext con = new MySQLDAO.MySQLDAOContext(objConString.ConString)) { con.OpenConnection(); t_table1Dao dao = new t_table1Dao(con); //insert dao.insert("test1"); int id = 1; //select DataTable tbl = dao.selectAll(); if (tbl.Rows.Count > 0) { MessageBox.Show(tbl.Rows[0]["name"].ToString() + "がInsertされました。"); id = (int)tbl.Rows[0]["id"]; } else { MessageBox.Show("insert失敗"); } //update dao.update(id, "test2"); //select DataTable tbl2 = dao.select(id); if (tbl2.Rows.Count > 0) { string name = tbl2.Rows[0]["name"].ToString(); if ("test2".Equals(name)) { MessageBox.Show(name + "にupdateされました。"); } else { MessageBox.Show("updateに失敗しました。"); } } //delete dao.delete(id); //select DataTable tbl3 = dao.select(id); if (tbl3.Rows.Count > 0) { MessageBox.Show("deleteに失敗しました。"); } else { MessageBox.Show("deleteに成功しました。"); } con.CloseConnection(); MessageBox.Show("success"); } }