java и mybatis - неправильное понимание отношения "один ко многим" - только аннотации

У меня есть две таблицы: Человек и Собака. Вы знаете, что у этого человека может быть более одной собаки.
Моя модель такова:

public class {
  int personId;
  List <Dog> dogs;
  String name;
  String surname;
}
public class Dog{
   String name;
   int dogId;
}

Когда дело доходит до базы данных, это довольно похоже:

PersonID(PK), Name (String), surname(String)   
dogId(PK), name(String), IdOwner(FK)   

Можете ли вы помочь мне написать select в mybatis? Я пытался читать о @one и @many.


person Community    schedule 22.11.2016    source источник


Ответы (1)


Если вы используете MyBatis, у вас есть два варианта, описанные в справочной документации:

  • Вложенный выбор: путем выполнения другого сопоставленного оператора SQL, который возвращает требуемый сложный тип.
  • Вложенные результаты: использование сопоставлений вложенных результатов для работы с повторяющимися подмножествами объединенных результатов.

В вашем случае, поскольку вы хотите загрузить множество ассоциаций, вы должны использовать Вложенный выбор, потому что вы не можете загрузить множество ассоциаций с помощью fetch outer join (только ассоциации с одной выбранной строкой)

Вложенный выбор

В этой опции вам нужно добавить ссылку на выбор, который загружает дайю по отношению внешнего ключа (в вашем случае внешний ключ человека), отношения, которое в вашем случае dogs в `ResultMap.

Итак, у вас должен быть запрос, загружающий таблицу Person:

<select id="findById" resultMap="personResult">
  SELECT * FROM PERSON WHERE NAME = #{name}
</select>

Его метод:

Person findById(String name); 

Затем запрос, который загружает собак по ключевым отношениям человека:

<select id="findDogsByPerson" resultType="Dog">
  SELECT * FROM DOG WHERE ID_PERSON = #{namePerson}
</select>

И его метод:

List<Dog> findDogsByPerson(String namePerson);

Затем вы должны добавить выбор как ассоциацию в карту результатов, ссылающуюся на выбор по внешнему ключу (findDogsByPerson). В вашем случае много ассоциаций, поэтому вы должны использовать тег collection вместо association.

<resultMap id="personResult" type="Person">
  <!--Other properties maps -->
  <!-- ..... -->
  <collection property="dogs" column="id_person" javaType="Dog" select="selectDogByPerson"/>
  <!-- ..... -->
</resultMap>

Альтернатива аннотации

Если хотите, можете использовать annotations для этого. Это почти то же самое, но ResultMap и Select идут выше методов. Это будет использовать аннотацию @Many, ссылающуюся на многие отношения.

@Select("SELECT * FROM PERSON WHERE NAME = #{name}")
    @Results(value = {
          @Result(property="name", column="name"),
          @Result(property="surname", column="surname"),
          @Result(property="dogs", javaType=List.class, column="name",
                             many=@Many(select="findDogsByPerson"))})
Person findById(String name); 

@Select("SELECT * FROM DOG WHERE ID_PERSON = #{namePerson}")
@Results(value = {
          @Result(property="name", column="name"),
          @Result(property="dogId", column="dogId")})
List<Dog> findDogsByPerson(String namePerson);
person Pau    schedule 24.11.2016
comment
А как насчет тех же запросов с использованием аннотаций? Переводить его непросто - я имею в виду ‹resultMap...› - person ; 25.11.2016
comment
И какую карту он возвращает? (Int -> Person), где Int — это Id? для меня достаточно вернуть собак ровно для одного (указанного в качестве параметра) идентификатора - person ; 25.11.2016
comment
Да делал, теперь исправлено - person Pau; 25.11.2016
comment
Спасибо, скажите мне одну вещь: что здесь означает столбец: @Result(property="dogs", javaType=List.class, column="name", many=@Many(select="findDogsByPerson"))})? - person ; 02.12.2016