이 글은 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 강의를 듣고 정리한 글입니다.
List<Member> result = em.createQuery(
"select m From Member m where m.username like '%kim%'",
// 데이터베이스의 테이블 Member가 아닌 엔티티 Member를 말함
Member.class
).getResultList();
for (Member member : result) {
System.out.println("member = " + member);
}
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
Root<Member> m = query.from(Member.class); // 루트 클래스 (조회를 시작할 클래스)
//쿼리 생성
CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("name"), "kim"));
List<Member> resultList = em.createQuery(cq).getResultList();
PAFactoryQuery query = new JPAQueryFactory(em);
QMember m = QMember.member;
List<Member> list = query
.selectFrom(m)
.where(m.name.like("kim"))
.orderBy(m.id.desc())
.fetch();
String sql = "SELECT ID, NAME FROM MEMBER WHERE NAME = 'kim'";
List<Member> resultList = em.createNativeQuery(sql, Member.class).getResultList();
select_문 ::=
select_절
from_절
[where_절]
[groupby_절]
[having_절]
[orderbt_절]
update_문 ::= update_절 [where_절]
delete_문 ::= delete_절 [where_절]
엔티티
와 속성
은 대소문자 구분O (Member, age)JPQL 키워드
는 대소문자 구분X (select, from, where)@Entity(name = “Member”)
의 name 값select
COUNT(m), //회원 수
SUM(m.age), //나이 합
AVG(m.age), //평균 나이
MAX(m.age), //최대 나이
MIN(m.age) //최소 나이
from Member m
TypedQuery<Member> query = em.createQuery("SELECT m FROM Member m", Member.class);
TypedQuery<String> query2 = em.createQuery("select m.username from Member m", String.class);
Query query = em.createQuery("SELECT m.username, m.age from Member m");
TypedQuery<Member> query = em.createQuery("select m from Member m", Member.class);
List<Member> resultList = query.getResultList(); // 컬렉션 반환
for (Member member1 : resultList) {
System.out.println("member1 = " + member1);
}
TypedQuery<Member> singleQuery = em.createQuery("select m from Member m where m.id = 1", Member.class);
Member singleResult = singleQuery.getSingleResult(); // 값이 정확히 1개여야 한다.
System.out.println("singleResult = " + singleResult);
SELECT m FROM Member m where m.username = :username // 💡 :이름
query.setParameter("username", usernameParam); // usernameParam = "member1"
// => chainging
Member singleResult = em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "member1")
.getSingleResult();
SELECT m FROM Member m where m.username = ?1 // 💡 ?위치
query.setParameter(1, usernameParam); // usernameParam = "member1"
List<Member> resultList = em.createQuery("select m from Member m", Member.class)
.getResultList();
Member findMember = resultList.get(0);
findMember.setAge(20); // 💡 값이 바뀜 => resultList가 영속성 컨텍스트에서 관리가 됨
List<Team> resultList = em.createQuery("select t from Member m join m.team t", Team.class)
.getResultList();
1. Query 타입으로 조회
List resultList = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[]) o; // 타입 캐스팅
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
2. Object[] 타입으로 조회
List<Object[]> resultList = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
3. new 명령어로 조회
public class MemberDTO {
private String username;
private int age;
public MemberDTO(String username, int age) {
this.username = username;
this.age = age;
}
}
List<MemberDTO> resultList5 = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
.getResultList();
MemberDTO memberDTO = resultList5.get(0);
System.out.println("memberDTO.getUsername() = " + memberDTO.getUsername());
System.out.println("memberDTO.getAge() = " + memberDTO.getAge());
String jpql = "select m from Member m order by m.age desc"
List<Member> resultList = em.createQuery(jpql, Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
System.out.println("resultList.size() = " + resultList.size());
for (Member member1 : resultList) {
System.out.println("member1 = " + member1);
}
Member.class에
toString()
추가 (단축키: Alt+Insert)@Override public String toString() { return "Member{" + "id=" + id + ", username='" + username + '\'' + ", age=" + age + //", team=" + team + // 양방향에서 무한루프 주의! 삭제하는 것이 좋다. '}'; }
SELECT
M.ID AS ID,
M.AGE AS AGE,
M.TEAM_ID AS TEAM_ID,
M.NAME AS NAME
FROM
MEMBER M
ORDER BY
M.NAME DESC LIMIT ?, ?
SELECT * FROM
( SELECT ROW_.*, ROWNUM ROWNUM_
FROM
( SELECT
M.ID AS ID,
M.AGE AS AGE,
M.TEAM_ID AS TEAM_ID,
M.NAME AS NAME
FROM MEMBER M
ORDER BY M.NAME
) ROW_
WHERE ROWNUM <= ?
)
WHERE ROWNUM_ > ?
SELECT m FROM Member m [INNER] JOIN m.team t
SELECT m FROM Member m LEFT [OUTER] JOIN m.team t
SELECT count(m) FROM Member m, Team t WHERE m.username = t.name
SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'A'
SELECT m.*, t.* FROM
Member m LEFT JOIN Team t ON m.TEAM_ID=t.id and t.name='A'
// PK = FK
SELECT m, t FROM Member m LEFT JOIN Team t on m.username = t.name
SELECT m.**, t.** FROM Member m LEFT JOIN Team t ON m.username = t.name
select m from Member m
where m.age > (select avg(m2.age) from Member m2) // 괄호 속 SELECT 절
select m from Member m
where (select count(o) from Order o where m = o.member) > 0 // 괄호 속 SELECT 절
select m from Member m
where exists (select t from m.team t where t.name = ‘팀A') // 💡 exists
select o from Order o
where o.orderAmount > ALL (select p.stockAmount from Product p) // 💡 ALL
select m from Member m
where m.team = ANY (select t from Team t) // 💡 ANY
select (select avg(m1.age) from Member m1)
as avgAge from Member m left join Team t on m.username = t.name
select mm.age, mm.username
from (select m.age, m.username from Member m) as mm
String query13 = "select m.username, 'HELLO', true From Member m " +
"where m.type = :userType";
List<Object[]> resultList8 = em.createQuery(query13)
.setParameter("userType", MemberType.ADMIN)
.getResultList();
select i from Item i where type(i) = Book
@DiscriminatorValue(name=”DTYPE”)
select
case when m.age <= 10 then '학생요금'
when m.age >= 60 then '경로요금'
else '일반요금'
end
from Member m
select
case t.name
when '팀A' then '인센티브110%'
when '팀B' then '인센티브120%'
else '인센티브105%'
end
from Team t
select coalesce(m.username,'이름 없는 회원') from Member m
select NULLIF(m.username, '관리자') from Member m
select 'a' || 'b' From Member m
select substring(m.username, 2,3) From Member m
select locate('de', 'abcdegf') From Member m
@OrderColumn
과 함께 쓰는데, List 값 타입 컬렉션에서 옵션을 주어 위치값을 구할 때 쓸 수 있음. 쓰는 것을 추천하지 않음. select size(t.members) From Team t
public class MyH2Dialect extends H2Dialect {
public MyH2Dialect() { // 실제 소스 코드를 열어보면 자세히 나와 있음
registerFunction("group_concat",
new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
}
}
// persistence.xml
<!--<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>-->
<property name="hibernate.dialect" value="dialect.MyH2Dialect"/>
select function('group_concat', m.username) from Member m