패키지 구성 기본 뼈대
- service
-- <entity 명칭>
--> interface, 구현체 쌍으로 구성
엔티티 서비스 인터페이스에 메서드 정의하고,
엔티티 서비스 구현체에 메서드 개발하는 포맷으로 정의
서비스 로직 부분 주요 역할 : Repository와 같은 Bean 들을 주입받아서 실제 businsess 로직을 구현함
아래는 서비스 부분 예시 코드
@Service
@RequiredArgsConstructor
public class ApplicationServiceImpl implements ApplicationService{
private final ApplicationRepository applicationRepository;
private final TermsRepository termsRepository;
private final AcceptTermsRepository acceptTermsRepository;
private final ModelMapper modelMapper;
@Override
public Response create(Request request) {
Application application = modelMapper.map(request, Application.class);
application.setAppliedAt(LocalDateTime.now());
Application applied = applicationRepository.save(application);
return modelMapper.map(applied, Response.class);
}
@Override
public Response get(Long applicationId) {
Application application = applicationRepository.findById(applicationId).orElseThrow(()->{
throw new BaseException(ResultType.SYSTEM_ERROR);
});
return modelMapper.map(application, Response.class);
}
@Override
public Response update(Long applicationId, Request request) {
Application application = applicationRepository.findById(applicationId).orElseThrow(()->{
throw new BaseException(ResultType.SYSTEM_ERROR);
});
application.setName(request.getName());
application.setCellPhone(request.getCellPhone());
application.setEmail(request.getEmail());
application.setHopeAmount(request.getHopeAmount());
applicationRepository.save(application);
return modelMapper.map(application, Response.class);
}
@Override
public void delete(Long applicationId) {
Application application = applicationRepository.findById(applicationId).orElseThrow(()->{
throw new BaseException(ResultType.SYSTEM_ERROR);
});
application.setIsDeleted(true);
applicationRepository.save(application);
}
@Override
public Boolean acceptTerms(Long applicationId, AcceptTerms request) {
// check 1 - 대출 신청 정보가 존재해야 함
applicationRepository.findById(applicationId).orElseThrow(()->{
throw new BaseException(ResultType.SYSTEM_ERROR);
});
// check 2 - 약관이 하나라도 있어야 함
List<Terms> termsList = termsRepository.findAll(Sort.by(Sort.Direction.ASC, "termsId"));
if(termsList.isEmpty()){
throw new BaseException(ResultType.SYSTEM_ERROR);
}
// check 3 - 만든 약관 수와, 고객이 넘긴 약관 수가 동일해야 한다. 근데 이건 대출 상품 1개에 약관 N개 존재한다는 가정에서만 작성된 코드인듯
List<Long> acceptTermsIds = request.getAcceptTermsIds();
if(termsList.size() != acceptTermsIds.size()){
throw new BaseException(ResultType.SYSTEM_ERROR);
}
List<Long> termsIds = termsList.stream().map(Terms::getTermsId).collect(Collectors.toList());
Collections.sort(acceptTermsIds);
if(!termsIds.containsAll(acceptTermsIds)){
throw new BaseException(ResultType.SYSTEM_ERROR);
}
for(Long termsId : acceptTermsIds){
com.fastcampus.loan.domain.AcceptTerms accepted = com.fastcampus.loan.domain.AcceptTerms.builder()
.termsId(termsId)
.applicationId(applicationId)
.build();
acceptTermsRepository.save(accepted);
}
return true;
}
}
@Service
@RequiredArgsConstructor
public class PostService {
private final PostEntityRepository postEntityRepository;
private final UserEntityRepository userEntityRepository;
private final LikeEntityRepository likeEntityRepository;
private final CommentEntityRepository commentEntityRepository;
private final AlarmEntityRepository alarmEntityRepository;
private final AlarmService alarmService;
@Transactional
public void create(String title, String body, String userName){
// user find
UserEntity userEntity = getUserEntityOrException(userName);
// post save
postEntityRepository.save(PostEntity.of(title, body, userEntity));
}
@Transactional
public Post modify(String title, String body, String userName, Integer postId){
UserEntity userEntity = getUserEntityOrException(userName);
// post exist
PostEntity postEntity = getPostEntityOrException(postId);
// post permission
if (postEntity.getUser() != userEntity){
throw new SnsApplicationException(ErrorCode.INVALID_PERMISSION, String.format("%s has no permission with %s", userName, postId));
}
postEntity.setTitle(title);
postEntity.setBody(body);
return Post.fromEntity(postEntityRepository.saveAndFlush(postEntity));
}
@Transactional
public void delete(String userName, Integer postId){
UserEntity userEntity = getUserEntityOrException(userName);
// post exist
PostEntity postEntity = getPostEntityOrException(postId);
// post permission
if (postEntity.getUser() != userEntity){
throw new SnsApplicationException(ErrorCode.INVALID_PERMISSION, String.format("%s has no permission with %s", userName, postId));
}
likeEntityRepository.deleteAllByPost(postEntity);
commentEntityRepository.deleteAllByPost(postEntity);
postEntityRepository.deletePost(postEntity.getId());
}
public Page<Post> list(Pageable pageable){
return postEntityRepository.findAll(pageable).map(Post::fromEntity);
}
public Page<Post> my(String userName, Pageable pageable){
UserEntity userEntity = getUserEntityOrException(userName);
return postEntityRepository.findAllByUser(userEntity, pageable).map(Post::fromEntity);
}
@Transactional
public void like(Integer postId, String userName){
// post exist
PostEntity postEntity = getPostEntityOrException(postId);
UserEntity userEntity = getUserEntityOrException(userName);
// check liked -> throw
likeEntityRepository.findByUserAndPost(userEntity, postEntity).ifPresent(it->{
throw new SnsApplicationException(ErrorCode.ALREADY_LIKED, String.format("userName %s already like post %d", userName, postId));
});
// like save
likeEntityRepository.save(LikeEntity.of(userEntity, postEntity));
AlarmEntity alarmEntity = alarmEntityRepository.save(AlarmEntity.of(postEntity.getUser() , AlarmType.NEW_LIKE_ON_POST, new AlarmArgs(userEntity.getId(), postEntity.getUser().getId())));
alarmService.send(alarmEntity.getId(), alarmEntity.getUser().getId());
}
@Transactional
public long likeCount(Integer postId){
// post exist
PostEntity postEntity = getPostEntityOrException(postId);
// // count like
// List<LikeEntity> likeEntities = likeEntityRepository.findAllByPost(postEntity);
// // like save
// return likeEntities.size();
return likeEntityRepository.countByPost(postEntity);
}
@Transactional
public void comment(Integer postId, String userName, String comment){
PostEntity postEntity = getPostEntityOrException(postId);
UserEntity userEntity = getUserEntityOrException(userName);
// comment save
commentEntityRepository.save(CommentEntity.of(userEntity, postEntity, comment));
AlarmEntity alarmEntity = alarmEntityRepository.save(AlarmEntity.of(postEntity.getUser() , AlarmType.NEW_COMMENT_ON_POST, new AlarmArgs(userEntity.getId(), postEntity.getUser().getId())));
alarmService.send(alarmEntity.getId(), alarmEntity.getUser().getId());
}
public Page<Comment> getComments(Integer postId, Pageable pageable){
PostEntity postEntity = getPostEntityOrException(postId);
return commentEntityRepository.findAllByPost(postEntity, pageable).map(Comment::fromEntity);
}
// post exist
private PostEntity getPostEntityOrException(Integer postId){
return postEntityRepository.findById(postId).orElseThrow(()->
new SnsApplicationException(ErrorCode.POST_NOT_FOUND, String.format("%s not founded", postId)));
}
// user exist
private UserEntity getUserEntityOrException(String userName){
return userEntityRepository.findByUserName(userName).orElseThrow(()->
new SnsApplicationException(ErrorCode.USER_NOT_FOUND, String.format("%s not founded", userName)));
}
}
'스프링 관련 > 스프링' 카테고리의 다른 글
controller (0) | 2023.01.15 |
---|---|
repository (0) | 2023.01.15 |
domain (0) | 2023.01.14 |
config (0) | 2023.01.14 |
스프링 프로젝트 패키지 구조 정리 및 항목별 index url 정리 (0) | 2023.01.13 |
댓글