String query = "select m from Member m join fetch m.team";
일단 fetch를 사용하지 않고 아래를 실행해보자.
Team team = new Team(); team.setName("teamA"); em.persist(team); Team team1 = new Team(); team1.setName("teamB"); em.persist(team1); Member member = new Member(); member.setUsername("userA"); member.setAge(10); member.setType(MemberType.ADMIN); Member member1 = new Member(); member1.setUsername("userB"); member1.setAge(70); member1.setType(MemberType.USER); Member member2 = new Member(); member2.setUsername("userC"); member2.setAge(90); member2.setType(MemberType.USER); member.setTeam(team); member1.setTeam(team1); member2.setTeam(team1); em.persist(member); em.persist(member1); em.persist(member2); em.flush(); em.clear(); String query = "select m from Member m"; List<Member> resultList = em.createQuery(query, Member.class).getResultList(); for (Member member : resultList) { System.out.println("member = " + member.getUsername()+","+member.getTeam().getName()); }
System.out.println(" ======================================================= "); tx.commit(); //이시점에 DB 쿼리가 날라감
실행을 하면 em.clear(); 이후에 쿼리는 select m from Member m 이때 member만 일단 select 쿼리가 나가게 된다.
왜냐하면 Member 에서 Team변수에 지연로딩을 걸어놨기 때문에 조인이 안된 상태로 Member만 select 때린다.
이때 proxy 객체를 얻어온다. (그냥 객체가 아니다, 왜냐면 지연로딩이기 때문에 - 지연로딩= 프록시객체 얻어옴)
그리고 아래에 member3.getTeam().getName() 을 딱 호출하면 team과 연관된 데이터를 건드렸기 때문에 team select
문이 호출되면서 프록시 객체가 없어지고 그냥 일반 객체로 변하게 된다.
그러면 teamA에 관한 첫번째 member가 출력이 된다. 만약 teamA가 2명이면 2명의 member가 출력되겠지?
그러고 또다시 루프를 돌면서 두번째 member에 대해 member.getTeam().getName() 를 할것이고 이때 Team은
teamA가 아니라 teamB라서 또다시 DB에서 쿼리를 가져온다.... 뭔가 복잡하다.
이때 teamB는 2명이다. 두번째 member일때 select 쿼리를 때리고 세번째 member는 또다시 teamB이기 때문에
영속성 컨텍스트에 이미 담긴 놈을 불러오므로 DB에 쿼리를 안때리는것이다..
개어렵노.ㅡㅡ
지금 적는것 조차 뭔가 복잡하고 알아듣기 어렵지만... 내 자신은 이해를 완벽히 해서 다행일뿐이다.
Team team = new Team(); team.setName("teamA"); em.persist(team); Member member = new Member(); member.setUsername("userA"); member.setAge(10); member.setType(MemberType.ADMIN); Member member1 = new Member(); member1.setUsername("userB"); member1.setAge(70); member1.setType(MemberType.USER); member.setTeam(team); member1.setTeam(team); em.persist(member); em.persist(member1); em.flush(); em.clear(); String query ="select case when m.age<=10 then '학생요금'" + "when m.age>=60 then '경로요금'" + "else '일반요금' end" + " from Member m"; List<String> resultList = em.createQuery(query, String.class).getResultList(); for (String s : resultList) { System.out.println("s = " + s); }
System.out.println(" ======================================================= "); tx.commit(); //이시점에 DB 쿼리가 날라감
Team team = new Team(); team.setName("teamA"); em.persist(team); Member member = new Member(); member.setUsername("member1"); member.setAge(10); member.setTeam(team); em.persist(member); em.flush(); em.clear(); String query = "select m from Member m join m.team t where t.name=:teamName"; List<Member> result = em.createQuery(query, Member.class) .setParameter("teamName","teamA").getResultList(); System.out.println(" ======================================================= "); tx.commit(); //이시점에 DB 쿼리가 날라감
LEFT OUTER JOIN(또는 RIGHT) (outer 생략가능 - 오라클과 같음)
String query = "select m from Member m left join m.team t where t.name=:teamName"; List<Member> result = em.createQuery(query, Member.class) .setParameter("teamName","teamA").getResultList();
세타조인(크로스조인, 카티션 프로덕트, 막조인)
String query = "select m from Member m, Team t where m.username=t.name"; List<Member> result = em.createQuery(query, Member.class) .getResultList();
List<Member> result = em.createQuery("select m from Member m order by m.agedesc",Member.class) .setFirstResult(45).setMaxResults(10).getResultList();
그냥 위처럼 사용하면 된다. 타입을 아니까 타입 적어서 List로 빼면 된다.
뺄때 setFirstResult()와 setMaxResults() 를 써주면 개꿀빤다.
rownum에 인라인뷰 3개에 뭐 이딴 짓 안해도됨.ㅡㅡ
desc를 써주는것은 최근 게시물일 경우 니까 쓰는것이것지.
for (int i=0; i<100; i++){ Member member = new Member(); member.setUsername("member"+i); member.setAge(i); em.persist(member); }
em.flush(); em.clear(); List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class) .setFirstResult(45).setMaxResults(10).getResultList(); System.out.println("result.size() = " + result.size()); for (Member member1 : result) { System.out.println("member1 = " + member1); }