5.DBアクセス-コマンド編
コマンドオブジェクトのExecute*メソッドを使用した、DBに対して直接的にデータ操作を行うサンプルコード(C#)について解説します。
サンプルコードの簡単な処理の流れとしては以下になります。
- DBコネクションオブジェクト作成
- DBコネクションオープン
- DBコマンドオブジェクト作成
- DBコマンド実行
- DBコネクションクローズ
コマンド編基本
SELECT文の実行によるデータの取得を行うサンプルコードについて、およびその他基本的な事項について解説します。
Mono 1.9.1では、2つのSQLite用データプロバイダアセンブリが提供されています。そして、使用するアセンブリと接続文字列の違いから、次の2つのサンプルコードを試してみました。
1.1 profile and the old assembly
using System; using System.Data; using Mono.Data.SqliteClient; namespace SqliteExample { public class OldType { public static void Main(string[] args) { // 接続文字列 string constr = "URI=file:/home/sta/data/TestData.db,version=3"; // SQL文字列 string sqlstr = "SELECT ProductID, ProductName, " + "Price, ProductDescription " + "FROM Products"; // 1.DBコネクションオブジェクト作成 using (IDbConnection dbcon = new SqliteConnection(constr)) { // 2.DBコネクションオープン dbcon.Open(); try { // 3.DBコマンドオブジェクト作成 using (IDbCommand dbcmd = dbcon.CreateCommand()) { dbcmd.CommandText = sqlstr; // 4.DBコマンド実行 using (IDataReader reader = dbcmd.ExecuteReader()) { while(reader.Read()) { string ProductID = reader[0].ToString(); string ProductName = reader[1].ToString(); string Price = string.Empty; if(reader[2] != null) { Price = reader[2].ToString(); } string ProductDescription = string.Empty; if(reader[3] != null) { ProductDescription = reader[3].ToString(); } Console.WriteLine( "ID:{0} NAME:{1} PRICE:{2} DESCRIPTION:{3}", ProductID, ProductName, Price, ProductDescription); } } } } finally { if (dbcon != null) { // 5.DBコネクションクローズ dbcon.Close(); } } } } } } /* * ビルド: * * mcs old.cs -r:System.Data.dll -r:Mono.Data.SqliteClient.dll * * 実行: * * mono old.exe * */
2.0 profile and the new assembly
using System; using System.Data; using Mono.Data.Sqlite; namespace SqliteExample { public class NewType { public static void Main(string[] args) { // 接続文字列 string constr = "Data Source=/home/sta/data/TestData.db"; // SQL文字列 string sqlstr = "SELECT ProductID, ProductName, " + "Price, ProductDescription " + "FROM Products"; // 1.DBコネクションオブジェクト作成 using (IDbConnection dbcon = new SqliteConnection(constr)) { // 2.DBコネクションオープン dbcon.Open(); try { // 3.DBコマンドオブジェクト作成 using (IDbCommand dbcmd = dbcon.CreateCommand()) { dbcmd.CommandText = sqlstr; // 4.DBコマンド実行 using (IDataReader reader = dbcmd.ExecuteReader()) { while(reader.Read()) { string ProductID = reader[0].ToString(); string ProductName = reader[1].ToString(); string Price = string.Empty; if(reader[2] != null) { Price = reader[2].ToString(); } string ProductDescription = string.Empty; if(reader[3] != null) { ProductDescription = reader[3].ToString(); } Console.WriteLine( "ID:{0} NAME:{1} PRICE:{2} DESCRIPTION:{3}", ProductID, ProductName, Price, ProductDescription); } } } } finally { if (dbcon != null) { // 5.DBコネクションクローズ dbcon.Close(); } } } } } } /* * ビルド: * * gmcs new.cs -r:System.Data.dll -r:Mono.Data.Sqlite.dll * * 実行: * * mono new.exe * */
両者の違い
アセンブリ
1.1 profile and the old assembly(以下、old):Mono.Data.SqliteClient 2.0 profile and the new assembly(以下、new):Mono.Data.Sqlite
従来からのものがoldアセンブリ、こちらを元に追加されたのがnewアセンブリとなります。newアセンブリは、SQLite version 3専用、完全なADO.NET 2.0 APIインターフェース対応とのことです。
接続文字列
old:URI=file:/home/sta/data/TestData.db,version=3 new:Data Source=/home/sta/data/TestData.db
oldの方はversion=3を指定しないとSQLite3 DBファイルにアクセスできません。newの方は、Mono Database Access SQLiteによると「Data Source=file:/home/sta/data/TestData.db」という記述が可能なはずですが、筆者の環境では、認識してくれず、アクセスエラーとなりました。
ビルド
old:mcs old.cs -r:System.Data.dll -r:Mono.Data.SqliteClient.dll new:gmcs new.cs -r:System.Data.dll -r:Mono.Data.Sqlite.dll
MonoではC#コンパイラとして「mcs」「gmcs」が用意されています。man mcsによると、
mcs : .NET 1.x 対応、C# 1.0(generics と null値可能型を除く、2.0)実装 gmcs: .NET 2.0 対応、C# 2.0 実装
ということになりますが、実際のところ、Mono 1.9からはC# 3.0相当ということなるようです(少々ややこしいですが)。mcs、gmcsの詳細についてはman mcsを確認してください。また、
new:mcs new.cs -r:System.Data.dll -r:Mono.Data.Sqlite.dll
は可能ですが、今記事ではC#コンパイラとして、gmcsを使用します。ビルドを行うと、プログラムソースと同じディレクトリにプログラムソース名.exeファイルが作成されます。
ビルド後の実行にはmonoランタイムコマンドの指定が必要です。
> mono [program.exe]
以上の違いはありますが、同様のコード内容と言えます。
プロバイダファクトリ
さらに、new.csを基に、プロバイダファクトリを使用した、より汎用的な記述を試してみました。
using System; using System.Data; using System.Data.Common; namespace SqliteExample { public class NewType2 { public static void Main(string[] args) { // プロバイダ識別文字列 string dpstr = "Mono.Data.Sqlite"; string constr = "Data Source=/home/sta/data/TestData.db"; string sqlstr = "SELECT ProductID, ProductName, " + "Price, ProductDescription " + "FROM Products"; // プロバイダファクトリ作成 DbProviderFactory dpf = DbProviderFactories.GetFactory(dpstr); // 1.DBコネクションオブジェクト作成 using (DbConnection dbcon = dpf.CreateConnection()) { dbcon.ConnectionString = constr; // 2.DBコネクションオープン dbcon.Open(); try { // 3.DBコマンドオブジェクト作成 using (DbCommand dbcmd = dbcon.CreateCommand()) { dbcmd.CommandText = sqlstr; // 4.DBコマンド実行 using (DbDataReader reader = dbcmd.ExecuteReader()) { while(reader.Read()) { string ProductID = reader[0].ToString(); string ProductName = reader[1].ToString(); string Price = string.Empty; if(reader[2] != null) { Price = reader[2].ToString(); } string ProductDescription = string.Empty; if(reader[3] != null) { ProductDescription = reader[3].ToString(); } Console.WriteLine( "ID:{0} NAME:{1} PRICE:{2} DESCRIPTION:{3}", ProductID, ProductName, Price, ProductDescription); } } } } finally { if (dbcon != null) { // 5.DBコネクションクローズ dbcon.Close(); } } } } } } /* * ビルド: * * gmcs new2.cs -r:System.Data.dll * * 実行: * * mono new2.exe * */
old.cs、new.cs、new2.cs、3者それぞれ、ビルド→実行を行い同様の結果を示しました。
ID:1 NAME:Clamp PRICE:12.48 DESCRIPTION:Workbench clamp ID:50 NAME:Flat Head Screwdriver PRICE:3.17 DESCRIPTION:Flat head ID:75 NAME:Tire Bar PRICE: DESCRIPTION:Tool for changing tires. ID:3000 NAME:3mm Bracket PRICE:0.52 DESCRIPTION:
今記事では、new2.csをベースにしたサンプルコードについて解説を行います。