大分間があいてしまいましたが、第7回です。
今回は、1対1の関連を取得してみます。
前回、1対Nをやっていますので、実際1対1は同じ事をやるだけです。
違いは、resultMapにgroupByが付いているかいないかくらいです。
今回も、ポイントはresultMapの設定にあります。
取得SQLの結果を大元のresultMapに渡し、その中からさらに他のresultMapに渡す事で
JOINの設定ができます。
以下、サンプルです。
今回のサンプルでは、MemosテーブルにあらかじめMemoIdが1のデータが存在し、Authorsテーブルに
あらかじめAuthorIdが1のデータが存在している事を前提としています。
[Author.cs]
using System; using System.Collections.Generic; namespace Gsf.Samples.IBatisNet.Models { public class Author { int _authorId; string _name; int _age; public int AuthorId{ get{ return _authorId; } set{ _authorId = value; } } public string Name{ get{ return _name; } set{ _name = value; } } public int Age{ get{ return _age; } set{ _age = value; } } public override string ToString() { return string.Format("id:{0}, name:{1}, age:{2}", AuthorId, Name, Age); } } }
[MemoAndAuthor.cs]
using System; using System.Collections.Generic; namespace Gsf.Samples.IBatisNet.Models { public class MemoAndAuthor { int _memoId; Author _author; string _title; string _memoData; public int MemoId{ get{ return _memoId; } set{ _memoId = value; } } public Author MemoAuthor{ get{ return _author; } set{ _author = value; } } public string Title{ get{ return _title; } set{ _title = value; } } public string MemoData{ get{ return _memoData; } set{ _memoData = value; } } public override string ToString() { return string.Format("memo-id:{0}, author-[{1}], title:{2}, data:{3}", MemoId, MemoAuthor, Title, MemoData); } } }
<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="MemoAndAuthor" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <alias> <typeAlias type="Gsf.Samples.IBatisNet.Models.Author" alias="Author"/> <typeAlias type="Gsf.Samples.IBatisNet.Models.MemoAndAuthor" alias="MemoAndAuthor"/> </alias> <resultMaps> <!-- MemoAndAuthor用の結果マッピング設定です。 --> <resultMap id="find-memo-result" class="MemoAndAuthor"> <result column="MemoId" property="MemoId"/> <!-- MemoAndAuthorクラス内にて定義されているAuthor型へのマッピング設定。 別のresultMapに、現在の情報を引き渡し、その結果をマッピングする。 その際に、resultMapping属性に指定する値は必ず名前空間付きで指定すること。 --> <result property="MemoAuthor" resultMapping="MemoAndAuthor.find-author-result"/> <result column="MemoTitle" property="Title"/> <result column="MemoData" property="MemoData"/> </resultMap> <!-- Author用の結果マッピング設定です。 --> <resultMap id="find-author-result" class="Author"> <result column="AuthorId" property="AuthorId"/> <result column="AuthorName" property="Name"/> <result column="AuthorAge" property="Age"/> </resultMap> </resultMaps> <statements> <!-- 指定されたMemoIdを条件として、該当するメモデータと作者データを取得します。 --> <select id="FindMemoAndAuthor" parameterClass="int" resultMap="find-memo-result"> <![CDATA[ select m.MemoId as MemoId ,a.AuthorId as AuthorId ,a.Name as AuthorName ,a.Age as AuthorAge ,m.Title as MemoTitle ,m.MemoData as MemoData from Authors a ,Memos m where m.MemoId = #value# and m.AuthorId = a.AuthorId ]]> </select> </statements> </sqlMap>
上記のような設定で、以下のようにテストコードを記述したとします。
using System; using System.Collections.Generic; using NUnit.Framework; using Gsf.Samples.IBatisNet.Models; using IBatisNet.DataMapper; using IBatisNet.Common; namespace Gsf.Samples.IBatisNet { [TestFixture] public class IBatisSample007 { [Test] public void JOINの動作を確認してみる_1_to_1(){ // // 対象となるデータを取得し、出力. // MemoAndAuthor data = Mapper.Instance().QueryForObject("MemoAndAuthor.FindMemoAndAuthor", 1); Assert.IsNotNull(data); Assert.IsNotNull(data.MemoId); Assert.IsNotNull(data.MemoAuthor.AuthorId); Console.WriteLine(data); } } class DummyEntryPoint007{ static void Main(){ // // nop; // } } }
例えば、以下のようなデータがデータベース上にあった場合
- Authors
AuthorId | Name | Age | Inserted | Updated |
1 | gsf_zero1 | 28 | 2007/11/12 15:53:38 | 2007/11/12 15:53:38 |
- Memos
MemoId | AuthorId | CategoryId | Title | MemoData | Inserted | Updated |
1 | 1 | 1 | Title-001 | MemoData-001 | 2007/11/12 15:00:00 | 2007/11/12 15:00:00 |
以下のように表示されます。
memo-id:1, author-[id:1, name:gsf_zero1, age:28], title:Title-001, data:Memo-001