競馬ブログ「ギャンブルからの脱却」

自作の予想ソフトを駆使して投資的競馬に挑戦。

基礎プログラム~JVデータ挿入編①~

今回はダミーデータではなく実際にJRA-VANのデータ(特別登録情報)をダウンロードしレコードに挿入するまでのプログラムを書きます。
予め言っておくと、僕は元々Java専門でVBに関してはほぼ初心者なのでコードの書き方に関してはあまり参考にしないでください。
それから、本記事はJV-Linkの動作確認やMySQL.Dataの参照追加が完了していることを前提に進めていきます。

仕様書を開く

f:id:last3f:20160206092320p:plain
JRA-VAN DAta Lab. SDK Ver4.4.1>ドキュメント内にあるJV-Data441.pdfを開いて7ページ目の「特別登録」の表を見ながら進めていきます。

②テーブル情報の定義

Public Class TableConstants

    '「特別登録」のテーブル名
    Public Const TABLE_NAME_TOKUBETSU_TOROKU As String = "tokubetsu_toroku"
    '「特別登録」テーブルのCREATE文
    Public Const CREATE_TOKUBETSU_TOROKU As String = "CREATE TABLE IF NOT EXISTS " & TABLE_NAME_TOKUBETSU_TOROKU &
        " (id int(10) NOT NULL AUTO_INCREMENT 
            ,record_spec varchar(2)
            ,data_group varchar(1)
            ,make_date varchar(8)
            ,year varchar(4)
            ,month_day varchar(4)
            ,place_code varchar(2)
            ,hold_count varchar(2)
            ,hold_day varchar(2)
            ,race_number varchar(2)
            ,week_code varchar(1)
            ,race_name_main varchar(60)
            ,race_name_sub varchar(60)
            ,race_name_alias varchar(60)
            ,race_name_main_eng varchar(120)
            ,race_name_short_a varchar(10)
            ,race_name_short_b varchar(6)
            ,race_name_short_c varchar(3)
            ,race_name_group varchar(20)
            ,grade_count varchar(12)
            ,grade_code varchar(6)
            ,race_type_code varchar(2)
            ,race_mark_code varchar(3)
            ,weight_type_code varchar(1)
            ,race_condition_code_age_2 varchar(3)
            ,race_condition_code_age_3 varchar(3)
            ,race_condition_code_age_4 varchar(3)
            ,race_condition_code_age_5 varchar(3)
            ,race_condition_code_young varchar(3)
            ,distance varchar(4)
            ,track_code varchar(2)
            ,course_group varchar(2)
            ,handicap_date varchar(8)
            ,registration_number varchar(3)
            ,blood_number text
            ,horse_name text       
            ,PRIMARY KEY (id)) "

    '「特別登録」テーブルのDROP TABLE文
    Public Const DROP_TOKUBETSU_TOROKU As String = "DROP TABLE IF EXISTS " & TABLE_NAME_TOKUBETSU_TOROKU


End Class

仕様書の表を見ながらカラム名を自分で決めて、varchar()内の最大文字数はバイトの欄と説明の欄を参考に設定します。
これは使わなそうだなという項目(競走名副題欧字とか)は無駄になるのでカラム自体を作りません。
インデックスに関してはとりあえずスルーしていますが、仕様書のキー欄に○が付いている項目を設定しておくのが無難かと思います。

③DbConnectorクラスの作成

データベースの接続やトランザクション関連のメソッドをまとめたクラスを作成します。

Imports MySql.Data.MySqlClient

Public Class DbConnector

    Private sqlBuilder = New MySqlConnectionStringBuilder()
    Private connection As MySqlConnection = Nothing
    Private command As MySqlCommand = Nothing
    Private trans As MySqlTransaction = Nothing

    Private Shared ReadOnly instance As New DbConnector

    Public Shared Function getInstance() As DbConnector
        Return instance
    End Function

    Private Sub New()
    End Sub

    Public Function getConnection() As MySqlConnection
        If IsNothing(connection) Then
            connection = New MySqlConnection()
        End If
        Return connection
    End Function

    Public Function getCommand() As MySqlCommand
        If IsNothing(command) Then
            command = New MySqlCommand()
        End If
        Return command
    End Function

    'データベースに接続するためのメソッド
    Public Sub open()
        sqlBuilder.Server = "localhost"
        sqlBuilder.Port = 3306
        sqlBuilder.UserID = "root"
        sqlBuilder.Password = "****"
        sqlBuilder.Database = "test"
        sqlBuilder.CharacterSet = "sjis"
        connection = New MySqlConnection()
        connection.ConnectionString = sqlBuilder.ToString()
        connection.Open()
    End Sub


    'データベースを切断するためのメソッド
    Public Sub close()
        connection.Close()
    End Sub

    Public Sub executeQuery()
        command.ExecuteNonQuery()
    End Sub

    Public Sub beginTransaction()
        trans = DbConnector.getInstance.connection.BeginTransaction()
    End Sub

    Public Sub rollback(ex As String, showMessage As Boolean)
        If IsNothing(trans) = False Then
            trans.Rollback()
            If showMessage Then
                MsgBox("ロールバックしました。")
            End If
        End If
    End Sub

    Public Sub commit()
        If IsNothing(trans) = False Then
            trans.Commit()
        End If
    End Sub

End Class

④DbEditorクラスの作成

実際にクエリを実行してDBを操作するためのメソッドをまとめたクラスです。

Imports MySql.Data.MySqlClient

Public Class DbEditor

    Private Shared ReadOnly instance As New DbEditor

    Public Shared Function getInstance() As DbEditor
        Return instance
    End Function

    Private Sub New()
    End Sub

    'CREATE TABLEを実行するためのメソッド
    Public Sub createTable()
        Dim command As MySqlCommand = DbConnector.getInstance.getCommand()
        command.Connection = DbConnector.getInstance.getConnection()
        command.CommandType = CommandType.Text
        command.CommandText = TableConstants.CREATE_TOKUBETSU_TOROKU
        command.Parameters.Clear()
        DbConnector.getInstance.executeQuery()
    End Sub

    'DROP TABLEを実行するためのメソッド
    Public Sub dropTable()
        Dim command As MySqlCommand = DbConnector.getInstance.getCommand()
        command.Connection = DbConnector.getInstance.getConnection()
        command.CommandType = CommandType.Text
        command.CommandText = TableConstants.DROP_TOKUBETSU_TOROKU
        command.Parameters.Clear()
        DbConnector.getInstance.executeQuery()
    End Sub

    'INSERTを実行するためのメソッド
    Public Function insert(tableName As String, params As ArrayList) As Boolean
        Try
            Dim command As New MySqlCommand
            command.Connection = DbConnector.getInstance.getConnection()
            command.CommandType = CommandType.Text
            Dim query As String = createInsertStatement(tableName, params)
            command.CommandText = query
            command.Parameters.Clear()

            For num = 0 To params.Count - 1
                Dim item As DbParams = params(num)
                command.Parameters.Add("@" + item.columnName, item.dataType, item.maxLength).Value = item.value
            Next

            command.ExecuteNonQuery()

        Catch ex As MySqlException
            Return False
        End Try
        Return True
    End Function

    'INSERT文を生成するためのメソッド
    Private Function createInsertStatement(tableName As String, params As ArrayList) As String
        Dim ret As String = ""
        Dim query As New Text.StringBuilder
        query.Append("INSERT INTO " & tableName & "(")

        For Each item As DbParams In params
            query.Append(item.columnName)
            query.Append(",")
        Next

        removeLast(params.Count, query)

        query.Append(") VALUES (")

        For Each item As DbParams In params
            query.Append("@")
            query.Append(item.columnName)
            query.Append(",")
        Next

        removeLast(params.Count, query)

        query.Append(")")
        ret = query.ToString
        Return ret
    End Function

    'StringBuilderの末尾を削除するためのメソッド
    Private Sub removeLast(number As Integer, target As Text.StringBuilder)
        If 0 < number Then
            target.Remove(target.Length - 1, 1)
        End If
    End Sub

End Class

続く