假设我有两个域对象和一个映射器接口。
class Person {
int id;
List<Problem> problems = new ArrayList<Problem>();
}
class Problem {
int id;
Person person;
}
interface PersonMapper {
public List<Person> selectAllPersons();
}
两个数据库表。
create table person (
id integer not null generated always as identity constraint person_pk primary key,
)
create table problem (
id integer not null generated always as identity constraint problem_pk primary key,
person_id integer not null constraint problem_person_fk references person
)
我可以创建一个获取我想要的数据的映射文件。
<resultMap id="personMap" type="Person">
<id column="person_id" property="id" />
<collection column="problem_person_id" property="problems"
javaType="ArrayList" ofType="Problem" resultMap="problemMap" />
</resultMap>
<resultMap id="problemMap" type="Problem">
<id column="problem_id" property="id" />
<!-- Adding an association here will cause a circular dependency -->
<!-- The circular dependency results in a StackOverflowException -->
</resultMap>
<select id="selectAllPersons" resultMap="personMap">
select
person.id as person_id,
problem.id as problem_id
from person left outer join problem on person.id = problem.person_id
</select>
但是,由于MyBatis不进行双向映射,因此返回集合中的Problem
个对象都不会正确设置其Person
引用。
根据this issue,听起来我应该能够更新我的mapper接口并添加一个可以由调用类提供的自定义结果处理程序。
interface PersonMapper {
public List<Person> selectAllPersons(ResultHandler handler);
}
class PersonResultHandler implements ResultHandler {
@Override
public void handleResult(ResultContext context) {
System.out.println(context.getResultObject());
}
}
class PersonDAO {
// Get SqlSession sqlSession
sqlSession.getMapper(PersonMapper.class).selectAllPersons(new PersonResultHandler());
}
但是,我handleResult
的{{1}}方法永远不会被调用。我见过this example,但那里额外的绒毛课让人很难理解。任何人都可以给我一个使用映射器接口的自定义ResultHandler
的简单示例吗?我正在使用MyBatis 3.0.5 +。
我还阅读了MyBatis邮件列表,并提出了一些使用缓存和延迟加载来解决循环依赖关系的建议,但我找不到任何有关如何执行此操作的示例。
答案 0 :(得分:1)
您应该将方法声明替换为:
interface PersonMapper {
public void selectAllPersons(ResultHandler handler);
}
并在List<Person>
PersonResultHandler
class PersonResultHandler implements ResultHandler {
List<Person> persons = new ArrayList<Person>();
@Override
public void handleResult(ResultContext context) {
Object result = context.getResultObject();
if (result instanceof Person) {
Person person = (Person) result;
for (Problem problem : person.getProblems()) {
problem.setPerson(person);
}
persons.add(person);
}
}
public List<Person> getPersons() {
return persons;
}
}