【问题标题】:How can I create bi-directional mappings with MyBatis 3.0.5?如何使用 MyBatis 3.0.5 创建双向映射?
【发布时间】:2011-12-08 18:28:53
【问题描述】:

假设我有两个域对象和一个映射器接口。

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,听起来我应该能够更新我的映射器接口并添加一个可由调用类提供的自定义结果处理程序。

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());
}

但是,我的 ResultHandlerhandleResult 方法永远不会被调用。我见过this example,但是那里额外的绒毛类使它很难理解。谁能给我一个使用带有映射器接口的自定义ResultHandler 的简单示例?我正在使用 MyBatis 3.0.5+。

我还阅读了 MyBatis 邮件列表,有一些使用缓存和延迟加载来解决循环依赖的建议,但我找不到任何示例。

【问题讨论】:

    标签: mybatis


    【解决方案1】:

    您应该将方法声明替换为:

    interface PersonMapper {
        public void selectAllPersons(ResultHandler handler);
    }
    

    并在您的PersonResultHandler 中填充List&lt;Person&gt;

    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 2020-01-02
      • 2019-05-02
      • 2010-09-23
      • 2016-04-19
      • 2020-05-10
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多