JPA 객체지향 쿼리 언어(JPQL) - JPQL 함수

2022. 7. 18. 23:52·공부/JPA
반응형

출처 : 자바 ORM 표준 JPA 프로그래밍 인프런 강의

 

JPA 게시글은 대부분 인프런의 김영한님의 강의인 '자바 ORM 표준 JPA 프로그래밍' 기반으로 내용을 정리했습니다.

 

JPQL 함수

JPQL 기본 함수

  • JPQL이 제공하는 표준 함수이다. DB와 상관없이 그냥 사용하면 된다.
  • CONCAT : 문자열을 이어주는(더하는) 함수
String query = "select concat('a', 'b') from Member m ";


// 출력 로그
Hibernate: 
    /* select
        concat('a',
        'b') 
    from
        Member m  */ select
            ('a'||'b') as col_0_0_ 
        from
            Member member0_
s = ab //** a와 b가 이어져서 출력된다.

concat 같은 경우는 하이버네이트에서 || 으로도 지원한다.

String query = "select 'a' || 'b' from Member m ";

그런데 위 코드를 작성하면 || 부분에 빨간 줄이 그어진다. 이 빨간 줄은 Mac 기준 option + enter → Un-inject Language/Reference를 선택하면 없어진다.

 

  • SUBSTRING : 문자열을 잘라내는 함수
String query = "select substring(m.username,2, 3) from Member m ";

substring의 인자로는 대상, startIndex, length로 구성된다. startIndex부터 length의 길이만큼 문자열을 잘라 반환한다. 현재 member에 셋팅되어 있는 username은 Admin이므로 다음과 같이 출력된다.

Hibernate: 
    /* select
        substring(m.username,
        2,
        3) 
    from
        Member m  */ select
            substring(member0_.username,
            2,
            3) as col_0_0_ 
        from
            Member member0_
s = dmi //** 원래는 Admin이다.

만약 매개변수로 대상과 startIndex만 있을 시 startIndex에서부터 문자의 마지막까지 잘라 반환해준다.

String query = "select substring(m.username,2) from Member m ";

// 출력
s = dmin

 

  • TRIM : 문자열의 양 끝 공백을 제거해주는 함수로 LTRIM(왼쪽 공백만 제거), RTRIM(오른쪽 공백만 제거) 모두 사용 가능하다.
member.setUsername("   Ad mi n   ");

username이 위와 같은 값을 가졌을 때 trim을 사용하면 다음과 같이 출력된다.

String query = "select trim(m.username) from Member m ";

// 출력 로그
Hibernate: 
    /* select
        trim(m.username) 
    from
        Member m  */ select
            trim(member0_.username) as col_0_0_ 
        from
            Member member0_
s = Ad mi n//** 양쪽 끝 공백이 없어졌다.

 

  • LOWER, UPPER : LOWER의 경우 모든 문자를 소문자로 변환, UPPER의 경우 모든 문자를 대문자로 변환해주는 함수이다.
member.setUsername("Admin");
String query = "select LOWER(m.username) from Member m ";

// 출력
s = admin
String query = "select upper(m.username) from Member m ";

// 출력
s = ADMIN

 

  • LENGTH : 문자의 길이를 반환한다.
member.setUsername("Admin");

String query = "select length(m.username) from Member m ";
List<Object[]> resultList = em.createQuery(query).getResultList();

for (Object s : resultList) {
    System.out.println("s = " + s);
}

// 출력
s = 5

 

  • LOCATE : 원하는 문자의 시작 INDEX를 알려주는 함수이다.
String query = "select locate('de', 'abcdefg') from Member m ";
List<Object[]> resultList = em.createQuery(query).getResultList

// 출력
s = 4

'de'가 'abcdefg'에서 존재하면 시작 index를 반환해준다. 대상 문자열이 찾는 문자열에 없을 경우엔 0을 반환한다.

 

  • ABS(절댓값 반환), SQRT(제곱근 반환), MOD(나눗셈 나머지 반환)
String query = "select abs(-3) from Member m ";

// 출력
s = 3
String query = "select sqrt(9) from Member m ";

// 출력
s = 3.0
String query = "select mod(10, 3) from Member m ";

// 출력
s = 1

 

  • SIZE(컬렉션의 크기 반환), INDEX(JPA 용도)
Team team = new Team();
team.setName("teamA");
em.persist(team);

Member member = new Member();
member.setUsername("Admin");
member.setAge(10);
member.setTeam(team);
member.setType(MemberType.ADMIN);
em.persist(member);

em.flush();
em.clear();

String query = "select size(t.members) from Team t";

// 출력
s = 1

 

index의 경우에는 일반적으로 사용할 수는 없고 값 타입 컬렉션에서 @OrderColumn를 사용했을 때 사용할 수 있는 함수이다. 근데 값 타입 컬렉션의 위치값을 구할 때 사용할 수 있는데.. 그냥 안 쓰는게 좋다.

 

 

사용자 정의 함수 호출

  • JPQL에서 제공하는 표준 함수 외 DB에서 제공하는 함수를 불러서 사용하는 방법이다.
  • 하이버네이트는 사용 전 방언에 추가해야 한다.
    • 사용하는 DB 방언을 상속받고, 사용자 정의 함수를 등록한다.
  • 하이버네이트에 대부분의 DB에서 사용하는 함수들이 다 선언되어 있기 때문에 그냥 호출해서 사용하면 된다.

예시를 위해 'group_concat'이라는 사용자 정의 함수가 있다고 치자(원래 구현되어 있는 함수임). 이 사용자 정의 함수를 등록하려면 먼저 새로운 패키지와 클래스를 만들어줘야한다.

패키지는 dialect, 클래스 명은 MyH2Dialect로 생성해준다.

public class MyH2Dialect extends H2Dialect {

    public MyH2Dialect() {
        registerFunction("group_concat", new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
    }
}

그리고 persistence.xml도 수정해준다.

<property name="hibernate.dialect" value="dialect.MyH2Dialect"/>

그리고 실행 클래스에서 아래와 같이 사용하면 된다.

Member member = new Member();
member.setUsername("Admin1");
em.persist(member);

Member member2 = new Member();
member2.setUsername("Admin2");
em.persist(member2);

em.flush();
em.clear();


String query = "select function('group_concat', m.username) from Member m";
List<String> resultList = em.createQuery(query, String.class).getResultList();

for (String s : resultList) {
    System.out.println("s = " + s);
}

// 출력
s = Admin1,Admin2

하이버네이트를 사용하는 경우엔 아래와 같이 간단하게 사용해도 된다.

String query = "select group_concat(m.username) from Member m";

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • JPA 객체지향 쿼리 언어(JPQL) - 패치 조인(기본)
  • JPA 객체지향 쿼리 언어(JPQL) - 경로 표현식
  • JPA 객체지향 쿼리 언어(JPQL) - 조건식(CASE 등)
  • JPA 객체지향 쿼리 언어(JPQL) - JPQL 타입 표현과 기타식
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    SQL
    인프런
    Java
    oracle
    JPA
    react
    egov
    에러해결
    스프링부트
    알고리즘
    IT
    프론트엔드
    Spring
    넥사크로
    springboot
    MSA
    전자정부프레임워크
    백준
    프로그래머스
    자바스크립트
    SpringBoot를 이용한 RESTful Web Service 개발
    방통대
    개발자
    기출문제
    QueryDSL
    운영체제
    토비의스프링부트
    토이프로젝트
    RESTful
    코딩테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
JPA 객체지향 쿼리 언어(JPQL) - JPQL 함수
상단으로

티스토리툴바