« iBatisでINSERT(自動採番値の利用) | メイン | Tapestry JavaScript(2) »

iBatisでSELECT(2つのテーブルからデータ取得)

データベースを利用しているシステムでは、必ず複数のテーブルが存在し、かつ、リレーションしています。
今回は、複数のテーブルからの情報取得について、書こうと思います。

今回も基本的な環境は同じで、テーブルを新たに追加します。
IDITEM_NAME
1ITEM1
1ITEM2
1ITEM3
2ITEM1
2ITEM2
3ITEM3

IDの部分は、今まで利用してきた、USER_TABLEのIDを外部キーとしたものです。
ユーザが複数のアイテムを持っているようなケースと考えてください。
(ただし、複数のテーブルから情報を取得することが目的なので、正規化等の話はまったくなしで進めます。)

追加、変更した部分だけ記述します。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
  <transactionManager type="JDBC">
    <dataSource type="SIMPLE">
      <property value="org.postgresql.Driver" name="JDBC.Driver"/>
      <property value="jdbc:postgresql://localhost/testdb" name="JDBC.ConnectionURL"/>
      <property value="testuser" name="JDBC.Username"/>
      <property value="testpassword" name="JDBC.Password"/>
    </dataSource>
  </transactionManager>

  <sqlMap resource="mappings/User.xml" />
  <sqlMap resource="mappings/Item.xml" />
</sqlMapConfig>

sqlMapにmapping/Item.xmlを追加しました。

次にItem.xmlの内容です。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Item">
  <select id="getItems" parameterClass="java.lang.Long" resultClass="sample.iBatis.Item">
    SELECT ID AS id,
           ITEM_NAME AS itemName
      FROM ITEM_TABLE
     WHERE ID=#value#
  </select>
</sqlMap>

今までのUser.xmlと内容はほとんど変わりません。

次に、データを格納するJavaのクラスを作成します。
package sample.iBatis;
public class Item {
	private Long id;
	private String itemName;

	public Long getId() {
		return this.id;
	}

	public void setId(Long aId) {
		this.id = aId;
	}

	public String getItemName() {
		return this.itemName;
	}

	public void setItemName(String aItemName) {
		this.itemName = aItemName;
	}
	
	@Override
	public String toString(){
		return "ID[" + this.id + "]:"
		      + "ItemName[" + this.itemName + "]";
	}
}


package sample.iBatis;
import java.util.List;
public class User {
	private Long id;
	private String name;
	private List<Item> items;

	public Long getId() {
		return this.id;
	}
	public void setId(Long aId) {
		this.id = aId;
	}
	public String getName() {
		return this.name;
	}
	public void setName(String aName) {
		this.name = aName;
	}
	public List<Item> getItems() {
		return this.items;
	}
	public void setItems(List<Item> aItems) {
		this.items = aItems;
	}
	@Override
	public String toString(){
		return "ID[" + this.id + "]:"
		      + "Name[" + this.name + "]";
	}
}

Item.javaを新規作成し、Userのメンバとして、Itemのリストを加えました。
< br /> 今までやってきたことだけで取得する場合、TestMainのMainを以下のように修正します。
	public static void main(String[] args) throws Exception {
		String RESOURCE_FILE = "mappings/sql-map-config.xml";
		
		Reader reader = Resources.getResourceAsReader(RESOURCE_FILE);
		SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
		
		// SELECT
		User user = (User) sqlMap.queryForObject("getUser", new Long(1));
		System.out.println(user);
		user.setItems(sqlMap.queryForList("getItems", user.getId()));
		for(Item item: user.getItems()){
			System.out.println(item);
		}

	}


実行してみると、
ID[1]:Name[User1]
ID[1]:ItemName[item1]
ID[1]:ItemName[item2]
ID[1]:ItemName[item3]
と表示され、Itemのリストが取得されました。


これでは今までと変わらないので、User.xmlのgetUserを以下のように修正してみます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="User">
  <resultMap id="resultUser" class="sample.iBatis.User">
    <result property="id" column="ID" />
    <result property="name" column="NAME" />
    <result property="items" column="ID" select="getItems" />
  </resultMap>

  <select id="getUser" resultMap="resultUser">
    SELECT
        ID AS id,
        NAME AS name
      FROM USER_TABLE
     WHERE ID=#value#
  </select>
</sqlMap>

resultMapを新たに作成し、getUserのresultClassを作成したresultMapに変更しています。
注意すべき点は、<result property="items" column="ID" select="getItems" />の箇所です。
これば、getUserで取得した、IDをキーとして、getItemsのselectを実行し、その結果はitemsに設定しなさいという指定の方法です。

ついでに、呼び出し部分も変更して動作を確認します。
	public static void main(String[] args) throws Exception {
		String RESOURCE_FILE = "mappings/sql-map-config.xml";
		
		Reader reader = Resources.getResourceAsReader(RESOURCE_FILE);
		SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
		
		// SELECT
		User user = (User) sqlMap.queryForObject("getUser", new Long(1));
		System.out.println(user);
		for(Item item: user.getItems()){
			System.out.println(item);
		}

	}


user.setItems(sqlMap.queryForList("getItems", user.getId())); の部分を削除しました。
実行してみると、
ID[1]:Name[User1]
ID[1]:ItemName[item1]
ID[1]:ItemName[item2]
ID[1]:ItemName[item3]
と表示され、Itemのリストが取得されました。
getUserを実行すると、getItemsも実行され想定どおりの結果がえられました。

resultMap等細かい部分の説明は、また別途やっていこうと思います。

ブログ内の関連する記事

トラックバック

このエントリーのトラックバックURL:
http://www.taosoftware.co.jp/mt/mt-tb.cgi/15