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

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

ID ITEM_NAME
1 ITEM1
1 ITEM2
1 ITEM3
2 ITEM1
2 ITEM2
3 ITEM3

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等細かい部分の説明は、また別途やっていこうと思います。

ブログ内の関連する記事