Connector/Netは.NET環境からMySQLデータベースにアクセスするためのオープンソースなライブラリ。 インストーラが用意されているので、インストーラの指示に従って「Next>」をクリックしていくだけで簡単にインストールすることができる。

ちなみに、Java環境から接続するためのConnector/J 3.2というものも存在する。

§1 準備

§1.1 ポート開放

まず、別のマシンからMySQLサーバーに接続するためには、3306番のポートが開いていなければならないので、開いてなければ開く必要がある。 3306番以外のポートを使用したい場合は、/etc/my.confを編集して使用するポートを指定する。

[client]
# MySQLサーバと接続する場合に使用するポート番号
port = 3306

[mysqld]
# MySQLサーバが使用するポート番号
port = 3306

§1.2 ソース修正

MySQLのテーブルからDateTime値を読もうとした場合に、値が'0000-00-00'(null)だと.NET FrameworkのDateTime型に変換できないため、ソースの以下の場所を修正した。 ここでは、値が'0000-00-00'だった場合は、暫定的にDateTime.MinValueを返すように変更した。

// MySqlData.Types.MySqlDateTime::GetDateTime()

/// <summary>Returns this value as a DateTime</summary>
public DateTime GetDateTime()
{
  if (! IsValidDateTime)
  {
    // throw new MySqlConversionException("Unable to convert MySQL date/time value to System.DateTime");
    return DateTime.MinValue;
  }
  return new DateTime( year, month, day, hour, minute, second );
}

§1.3 プロジェクトの設定

Visual StudioのプロジェクトでConnector/Netを使用するために、「参照の追加」ダイアログでMySQL.Data.dllを追加する。

Connector/Netのソースを修正したい場合は、MySQL.Data.dllのプロジェクト(C:\Program Files\MySQL\MySQL Connector Net 1.0.6\src\D:\Program Files\MySQL\MySQL Connector Net 1.0.6\src\MySql.Data.csproj)をソリューションに追加してから、「参照の追加」ダイアログでMySql.Dataのプロジェクトを追加する。

§2 サンプル

System.Windows.FormやSystem.Dataなどのクラス群と連携するような使用方法は、一緒にインストールされるTable Editor(C:\Program Files\MySQL\MySQL Connector Net 1.0.6\samples\Table Editor)というサンプルが参考になる。 ここではこれらを用いない場合の簡単なサンプルを取り上げる。

§2.1 基本的な流れ

まずは別のマシンからMySQLに接続して、データベースに含まれるテーブルの一覧を表示するためのVB.NETコード。 接続→コマンドの送信→結果の表示という基本的にな流れを記述している。

Imports System

Imports MySql.Data.MySqlClient

Public Class MySQLSample

    Public Shared Sub Main()

        Dim connection As MySqlConnection = Nothing

        Dim reader As MySqlDataReader = Nothing
        Dim command As MySqlCommand = Nothing

        Try

            ' 接続する
            Dim connectionString As String = String.Format( _
                "server={0}; uid={1}; pwd={2}; database={3};", _
                "192.168.0.1", _ ' MySQLサーバーのアドレス
                "username", _    ' ユーザー名
                "password", _    ' パスワード
                "testdb")        ' 参照するデータベース

            connection = New MySqlConnection(connectionString)

            connection.Open()

            ' テーブルの一覧を表示するコマンドを作成
            command = New MySqlCommand("show tables;", connection)

            ' コマンドを実行
            reader = command.ExecuteReader()

            ' 実行した結果を表示する
            While (reader.Read())

                For index As Integer = 0 To reader.FieldCount - 1

                    Console.Write(reader.GetString(index))

                Next

                Console.WriteLine()

            End While

        Catch ex As MySqlException

            Console.WriteLine("Failure: {0}", ex.Message)

        Finally

            If Not reader Is Nothing Then reader.Close()

            If Not command Is Nothing Then command.Dispose()

            If Not connection Is Nothing Then connection.Close()

        End Try

    End Sub

End Class

これを実行すると、testdbに含まれるテーブルの一覧が表示される。

test
sample
Press any key to continue

§2.2 ユーティリティメソッドの作成

コマンドを実行する度に、MySqlCommandのインスタンス生成と結果解析をするのは面倒なので、この処理をまとめて使いやすくするメソッドを作成する。 このメソッドは、コマンドをString型の引数として受け取り、結果をString()()型のジャグ配列として返却する。

Shared Function ExecuteCommand(ByVal commandString As String, ByVal connection As MySqlConnection) As String()()

    Dim reader As MySqlDataReader = Nothing
    Dim command As MySqlCommand = Nothing
    Dim resultCells As String()
    Dim resultLines As ArrayList = New ArrayList
    Dim results As String()() = New String()() {}

    Try

        ' コマンドを作成
        command = New MySqlCommand(commandString, connection)

        ' コマンドを実行
        reader = command.ExecuteReader()

        ' コマンドの結果をString()()型の配列にコピー
        While (reader.Read())

            resultCells = DirectCast(Array.CreateInstance(GetType(String), reader.FieldCount), String())

            For index As Integer = 0 To reader.FieldCount - 1

                resultCells(index) = reader.GetString(index)

            Next

            resultLines.Add(resultCells)

        End While

        results = DirectCast(resultLines.ToArray(GetType(String())), String()())

        ' 結果を表示
        Console.WriteLine(commandString)

        For Each line As String() In results

            Console.Write("  ")

            For Each cell As String In line

                Console.Write("{0}, ", cell)

            Next

            Console.WriteLine()

        Next

        Console.WriteLine("{0} rows found.", results.Length)
        Console.WriteLine()

    Catch ex As MySqlException

        Console.WriteLine("EXCEPTION: {0} {1}", ex.GetType().Name, ex.Message)

        Throw ex

    Finally

        If Not reader Is Nothing Then reader.Close()

        If Not command Is Nothing Then command.Dispose()

    End Try

    Return results

End Function

このメソッドを使用する例は以下の通り。

Imports System

Imports MySql.Data.MySqlClient

Public Class MySQLSample

    Public Shared Sub Main()

        Dim connection As MySqlConnection = Nothing

        Try

            ' 接続する
            Dim connectionString As String = String.Format( _
                "server={0}; uid={1}; pwd={2}; database={3};", _
                "192.168.0.1", _ ' MySQLサーバーのアドレス
                "username", _    ' ユーザー名
                "password", _    ' パスワード
                "testdb")        ' 参照するデータベース

            connection = New MySqlConnection(connectionString)

            connection.Open()

            ' DBの一覧表示
            ExecuteCommand("show databases;", connection)

            ' DBを選択
            ExecuteCommand("use sampledb;", connection)

            ' テーブルの一覧
            ExecuteCommand("show tables;", connection)

            ' テーブルのカラムを表示
            ExecuteCommand("desc sample;", connection)

            ' SQL文を実行
            Dim result As String()() = ExecuteCommand("select name,age from sample where age<=30;", connection)

            For Each row As String() In result

                Console.WriteLine("{0}, {1} years old.", row(0), row(1))

            Next
 
        Catch ex As MySqlException

            Console.WriteLine("Failure: {0}", ex.Message)

        Finally

            If Not connection Is Nothing Then connection.Close()

        End Try

    End Sub
 
    Shared Function ExecuteCommand(ByVal commandString As String, ByVal connection As MySqlConnection) As String()()
        ' 省略
    End Function

End Class

実行例は下記の通り。

show databases;
  testdb,
  sampledb,
2 rows found.

use sampledb;
0 rows found.

show tables;
  test,
  sample,
2 rows found.

desc sample;
  id, varchar(3), , PRI, , ,
  name, text, YES, , , ,
  age, smallint(6), YES, , 0, ,
3 rows found.

select name,age from sample where age<=30;
  test, 22,
  hoge, 15,
2 rows found.

test, 22 years old.
hoge, 15 years old.