現在、データベースのクエリ要件として、特定のニュースカテゴリのIDを与え、その親カテゴリ、親の親カテゴリといった情報を再帰的に取得する必要があります。
データベースのテーブル設計は以下の通りです。
エンティティクラスの設計:
package model;
public class Category {
private Integer id;
private String name;
private Category parent;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Category getParent() {
return parent;
}
public void setParent(Category parent) {
this.parent = parent;
}
@Override
public String toString() {
return "Category [id=" + id + ", name=" + name + ", parent=" + parent + "]";
}
}
SQLクエリインターフェースの定義:
public interface ICategoryDao {
Category selectCategoryWithParent(int categoryId);
}
SQLはmapper.xmlファイルで定義されています。クエリは"selectCategoryWithParent"というIDのSQLを呼び出し、結果をマッピング(resultMap)しています。resultMapのIDは"categoryMapper"です。"categoryMapper"にはidとnameのマッピングに加え、<association/>要素が含まれており、ここで関連関係が定義されています。
property="parent": マッピングするプロパティがparentであることを示します。javaType="Category": マッピングする型がCategoryであることを示します。column="parent_id": 親カテゴリを再度クエリするためにparent_idをパラメータとして渡します。select="selectCategoryWithParent":parentプロパティを取得するために実行するSQLステートメントです。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.ICategoryDao">
<resultMap type="Category" id="categoryMapper">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="parent"
javaType="Category"
select="selectCategoryWithParent"
column="parent_id"/>
</resultMap>
<select id="selectCategoryWithParent" resultMap="categoryMapper">
SELECT id, name, parent_id FROM categories WHERE id = #{categoryId}
</select>
</mapper>
テストクラス:
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CategoryTest {
private ICategoryDao categoryDao;
private SqlSession sqlSession;
@Before
public void setUp() {
sqlSession = MyBatisUtils.getSqlSession();
categoryDao = sqlSession.getMapper(ICategoryDao.class);
}
@Test
public void testSelectCategoryWithParent() {
Category category = categoryDao.selectCategoryWithParent(7);
System.out.println(category);
}
@After
public void tearDown() {
if (sqlSession != null) {
sqlSession.close();
}
}
}
クエリ結果:
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ==> Preparing: SELECT id, name, parent_id FROM categories WHERE id = ?
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ==> Parameters: 7(Integer)
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ====> Preparing: SELECT id, name, parent_id FROM categories WHERE id = ?
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ====> Parameters: 4(Integer)
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ======> Preparing: SELECT id, name, parent_id FROM categories WHERE id = ?
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ======> Parameters: 2(Integer)
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ========> Preparing: SELECT id, name, parent_id FROM categories WHERE id = ?
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - ========> Parameters: 0(Integer)
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - <======== Total: 0
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - <====== Total: 1
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - <==== Total: 1
[main] DEBUG dao.ICategoryDao.selectCategoryWithParent - <== Total: 1
Category [id=7, name=北京金瓯, parent=Category [id=4, name=CBA, parent=Category [id=2, name=体育新闻, parent=null]]]