Spring bootにてWebアプリ開発を勉強中です。Domaでのデータアクセスをしようと思った時に疑問が出たので質問します。
参考にしているプロジェクト内でDaoとRepositoryを分けているプロジェクトを見つけたため何が違うのかと調べていたのですが、イマイチ理解できないでいます。
その中でDaoとRepositoryを分けている箇所は以下のような実装をしています。
userdaojava
1package com.sample.domain.dao.users; 2 3import java.util.List; 4import java.util.Optional; 5import java.util.stream.Collector; 6 7import org.seasar.doma.*; 8import org.seasar.doma.boot.ConfigAutowireable; 9import org.seasar.doma.jdbc.SelectOptions; 10 11import com.sample.domain.dto.user.User; 12import com.sample.domain.dto.user.UserCriteria; 13 14@ConfigAutowireable 15@Dao 16public interface UserDao { 17 18 /** 19 * ユーザーを取得します。 20 * 21 * @param criteria 22 * @param options 23 * @return 24 */ 25 @Select(strategy = SelectType.COLLECT) 26 <R> R selectAll(final UserCriteria criteria, final SelectOptions options, final Collector<User, ?, R> collector); 27 28 /** 29 * ユーザーを1件取得します。 30 * 31 * @param id 32 * @return 33 */ 34 @Select 35 Optional<User> selectById(Long id); 36 37 /** 38 * ユーザーを1件取得します。 39 * 40 * @param criteria 41 * @return 42 */ 43 @Select 44 Optional<User> select(UserCriteria criteria); 45 46 /** 47 * ユーザーを登録します。 48 * 49 * @param user 50 * @return 51 */ 52 @Insert 53 int insert(User user); 54 55 /** 56 * ユーザーを更新します。 57 * 58 * @param user 59 * @return 60 */ 61 @Update 62 int update(User user); 63 64 /** 65 * ユーザーを論理削除します。 66 * 67 * @param user 68 * @return 69 */ 70 @Update(excludeNull = true) // NULLの項目は更新対象にしない 71 int delete(User user); 72 73 /** 74 * ユーザーを一括登録します。 75 * 76 * @param users 77 * @return 78 */ 79 @BatchInsert 80 int[] insert(List<User> users); 81 82 /** 83 * ユーザーを一括更新します。 84 * 85 * @param users 86 * @return 87 */ 88 @BatchUpdate 89 int[] update(List<User> users); 90} 91
UserRepository
1package com.sample.domain.repository.users; 2 3import static com.sample.domain.util.DomaUtils.createSelectOptions; 4import static java.util.Optional.ofNullable; 5import static java.util.stream.Collectors.toList; 6 7import java.util.Optional; 8 9import org.springframework.beans.factory.annotation.Autowired; 10import org.springframework.stereotype.Repository; 11 12import com.sample.domain.dao.system.UploadFileDao; 13import com.sample.domain.dao.users.UserDao; 14import com.sample.domain.dao.users.UserRoleDao; 15import com.sample.domain.dto.common.Page; 16import com.sample.domain.dto.common.Pageable; 17import com.sample.domain.dto.user.User; 18import com.sample.domain.dto.user.UserCriteria; 19import com.sample.domain.dto.user.UserRole; 20import com.sample.domain.exception.NoDataFoundException; 21import com.sample.domain.service.BaseRepository; 22 23import lombok.val; 24 25@Repository 26public class UserRepository extends BaseRepository { 27 28 @Autowired 29 UserDao userDao; 30 31 @Autowired 32 UserRoleDao userRoleDao; 33 34 @Autowired 35 UploadFileDao uploadFileDao; 36 37 /** 38 * ユーザーを取得します。 39 * 40 * @param criteria 41 * @param pageable 42 * @return 43 */ 44 public Page<User> findAll(UserCriteria criteria, Pageable pageable) { 45 // ページングを指定する 46 val options = createSelectOptions(pageable).count(); 47 val data = userDao.selectAll(criteria, options, toList()); 48 return pageFactory.create(data, pageable, options.getCount()); 49 } 50 51 /** 52 * ユーザーを取得します。 53 * 54 * @param criteria 55 * @return 56 */ 57 public Optional<User> findOne(UserCriteria criteria) { 58 // 1件取得 59 val user = userDao.select(criteria); 60 61 // 添付ファイルを取得する 62 user.ifPresent(u -> { 63 val uploadFileId = u.getUploadFileId(); 64 val uploadFile = ofNullable(uploadFileId).map(uploadFileDao::selectById); 65 uploadFile.ifPresent(u::setUploadFile); 66 }); 67 68 return user; 69 } 70 71 /** 72 * ユーザー取得します。 73 * 74 * @return 75 */ 76 public User findById(final Long id) { 77 return userDao.selectById(id).orElseThrow(() -> new NoDataFoundException("user_id=" + id + " のデータが見つかりません。")); 78 } 79 80 /** 81 * ユーザーを追加します。 82 * 83 * @param inputUser 84 * @return 85 */ 86 public User create(final User inputUser) { 87 88 // 1件登録 89 userDao.insert(inputUser); 90 91 // 役割権限紐付けを登録する 92 val userRole = new UserRole(); 93 userRole.setUserId(inputUser.getId()); 94 userRole.setRoleKey("users"); 95 userRoleDao.insert(userRole); 96 97 return inputUser; 98 } 99 100 /** 101 * ユーザーを更新します。 102 * 103 * @param inputUser 104 * @return 105 */ 106 public User update(final User inputUser) { 107 108 val uploadFile = inputUser.getUploadFile(); 109 if (uploadFile != null) { 110 // 添付ファイルがある場合は、登録・更新する 111 val uploadFileId = inputUser.getUploadFileId(); 112 if (uploadFileId == null) { 113 uploadFileDao.insert(uploadFile); 114 } else { 115 uploadFileDao.update(uploadFile); 116 } 117 118 inputUser.setUploadFileId(uploadFile.getId()); 119 } 120 121 // 1件更新 122 int updated = userDao.update(inputUser); 123 124 if (updated < 1) { 125 throw new NoDataFoundException("user_id=" + inputUser.getId() + " のデータが見つかりません。"); 126 } 127 128 return inputUser; 129 } 130 131 /** 132 * ユーザーを論理削除します。 133 * 134 * @return 135 */ 136 public User delete(final Long id) { 137 val user = userDao.selectById(id) 138 .orElseThrow(() -> new NoDataFoundException("user_id=" + id + " のデータが見つかりません。")); 139 140 int updated = userDao.delete(user); 141 142 if (updated < 1) { 143 throw new NoDataFoundException("user_id=" + id + " は更新できませんでした。"); 144 } 145 146 return user; 147 } 148} 149
このようにRepositoryにてDaoをAutoweredしてメソッドを使用しています。
私の中のDaoとRepository
私の中で2つは「デザインパターンレベルでのデータを取得したり、操作するもの」という認識で、大きな違いはないと理解していました。
ただ今回使い分けているんだからなんか違うんだろう、そして同じプロジェクトで同じ階層で使用すべきものなのだろうと思って調査をしました。
1.DaoとRepositoryのすみ分け
Repositoryはドメインオブジェクトを見て、DAOはデータ・ソースのマッピングするDTOの方を見る
「ベクトルが違うのはなんとなく伝わるけどまだわからない」
次!!!
2.リポジトリとDaoの住み分け方より
・リポジトリはドメインオブジェクトのコレクション ・DAOはデータアクセスのメカニズムを隠蔽する ・リポジトリの実装はドメインオブジェクトの構築です。
んー、頭の中で噛み砕けない。。。
恥ずかしながら私はデザインパターンを学んだ事がなく、こういう話は理解するのに苦労します。
SESの世界に例えた時に、簡単に言うと「二次請け企業と三次請け企業」のようにレイヤーが異なるという事でしょうか?
もう少し抽象的で構わないので子供に理解できるレベルの日本語で解説するとしたらどのような感じになりますでしょうか?
ご意見をよろしくお願いします。
また、皆さんの現場ではDaoとRepositoryは分けられていますか?
回答1件
あなたの回答
tips
プレビュー