Я решил попробовать использовать mybatis для нового проекта. Я неплохо знаком с SQL, и недавно у меня был плохой опыт с hibernate, поэтому я ищу более низкоуровневый подход к DAO.
Кажется, это очень приятно, за исключением одного, и это обработка коллекций.
У меня есть два POJO, группа и пользователь, которые много-ко-многим. Я решил философию дизайна, что POJO, у которого есть коллекция, должен обновлять отношение M-M между таблицами при сохранении. Так, например, когда я сохраняю групповой объект с коллекцией пользователей, философия дизайна требует, чтобы пользователи уже были сохранены, и мне нужно сохранить отношение группы и group_user в базе данных.
поэтому для функции saveGroup в интерфейсе я сделал это сопоставление XML для mybatis:
<insert id="saveGroup" keyColumn="id"
parameterType="se.myapp.domain.Group">
<choose>
<when test="id == null">
INSERT INTO myapp_group (name, description)
VALUES
(#{username}, #{password});
</when>
<otherwise>
UPDATE myapp_group set name=#{name}, description=#{description}
where id=#{id};
</otherwise>
</choose>
<if test="users != null">
create temporary table tmpnewgroups (group_id integer, user_id integer);
insert into tmpnewgroups (group_id, user_id) values (
<foreach collection="users" item="user" open="" close="" separator="),()">
#{id},#{user.id}
</foreach>
);
insert into myapp_user_group(group_id, user_id)
select tmp.group_id, tmp.user_id
from tmpnewgroups tmp
left outer join myapp_user_group ug
on ug.group_id = tmp.group_id and ug.user_id = tmp.user_id
where ug.group_id is null;
delete from myapp_user_group
where group_id = #{id} and user_id not in (select user_id from tmpnewgroups);
</if>
</insert>
Это работает по назначению (вставляет/обновляет группу, сохраняет коллекцию пользователей как отношения в базе данных). Но я не чувствую, что это лучшая практика. Приложение сделано так, что я могу переключиться на спящий режим, если это необходимо, поэтому логика сохранения коллекции предпочтительно должна находиться в слое базы данных. Есть ли какая-то "магия" в mybatis, что я не знаю, что может оптимизировать такие операции?
Любые мысли о том, как улучшить это? Или я должен переосмыслить дизайн приложения и добавить обработку коллекций в модель?