@RepositoryDefinition(domainClass = 에티티.class, idClass = Long.class)
public interface CommonRepository{

}

@NoRepositoryBean
public interface MyRepository<T, ID extends Serializable> extends Repository<T, ID>{
  <E extends T> E save(E entity);
  List<T> findAll();
}



@Size(max=5, message="상품코드는 5자여야 합니다.")
@Pattern(regexp="^[0-9]{5}$", message="상품코드는 5자리 숫자여야 합니다.")
protected String goodCd;

@NotNull(message="상품명은 필수 입력값입니다.")
@Size(max=100, message="상품명은 50자 이내여야 합니다.")
protected String goodNm;

=========================================================================================
@Query("SELECT p FROM #{#entityName} p where p.title = :title")
List<Post> findByTitle(@Param("title") String title, Sort sort);

@Query("SELECT p FROM #{#entityName} p where p.id = :id and p.title = :title")
List<Post> findByTitle2(@Param("id") Long id, @Param("title") String title);

@Modifying(clearAutomatically = true)
@Query("update #{#entityName} p set p.title = :title where p.id = :id")
int updateTitle(@Param("id") Long id, @Param("title") String title);

postRepository.findByTitle("jpa", Sort.by("title"));
//postRepository.findByTitle("jpa", Sort.by("LENGTH(title)"));
postRepository.findByTitle("jpa", JpaSort.unsafe("LENGTH(title)"));
postRepository.findByTitle2(1l,"jpa");
===============================================================================================

===== EntityGraph ==========================================================================
@NamedEntityGraph(
        name = "Comment.post",
        attributeNodes = @NamedAttributeNode("post")
)
@Entity
@Getter
@Setter
public class Comment {


@EntityGraph(value = "Comment.post", type = EntityGraph.EntityGraphType.LOAD)
Optional<Comment> queryById(Long id);
----------------------------------------------------------------------------------

@EntityGraph(attributePaths = {"post"})
Optional<Comment> queryById(Long id);
================================================================================================

===== Projection ==========================================================================
<T> List<T> findByPost_Id(Long id, Class<T> type);

commentRepository.findByPost_Id(savedPost.getId(), CommentSummary.class)

public interface CommentSummary {
    String getComment();
    int getUp();
    int getDown();

//    @Value("#{target.up + ' ' + target.down}")
//    String getVotes();

    default String getVotes(){
        return getUp() + " " + getDown();
    }
}
==============================================================================================

==== Query by Example ===============================================================
public Page<User> getUsers(SearchForm searchForm, Character useYn, Pageable pageable) {
        try {
            User example = User.builder() //user 객체 생성
                    .useYn(useYn=='Y'?useYn:null)
                    .id(searchForm.getId())
                    .name(searchForm.getName())
                    .serialNo(searchForm.getSerialNo())
                    .phone(searchForm.getPhone())
                    .organization(searchForm.getOrganization())
                    .grade(searchForm.getGrade())
                    .build();
            ExampleMatcher matcher = ExampleMatcher.matchingAll()
                    .withMatcher("id",contains().ignoreCase())
                    .withMatcher("name", contains().ignoreCase())
                    .withMatcher("serialNo", contains().ignoreCase())
                    .withMatcher("phone", contains().ignoreCase())
                    .withMatcher("organization", contains().ignoreCase())
                    .withMatcher("grade", contains().ignoreCase());
            return userRepository.findAll(Example.of(example, matcher), pageable);
        }catch (Exception e) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "BAD REQUEST");
        }
    }
=====================================================================

querydsl BooleanExpression
BooleanExpression be = user.username.contains(text);
if(be) be.and(user.username.eq("Hi")