🧩 프로젝션
- select 절에 조회할 대상을 지정하는 것
 
- select m from Member m
-> Member 엔티티 조회  
- select m.team from Member m
-> Member와 관련된 team을 가지고 온다. 
- select m.username, m.age from Member m
-> Member 엔티티에 있는 username, age를 조회 
@Entity
@Getter @Setter
public class Member {
	@Id @GeneratedValue
	private Long id;
	private String username;
	private int age;
	
	@ManyToOne
	@JoinColumn(name = "TEAM_ID")
	private Team team;
}
@Entity
@Getter @Setter
public class Team {
	@Id @GeneratedValue
	@Column( name = "TEAM_ID")
	private Long id;
	private String name;
	
	@OneToMany(mappedBy = "team")
	private List<Member> members = new ArrayList<Member>();
}
@Entity
@Getter @Setter
@Table(name = "Orders")
public class Order {
	@Id @GeneratedValue
	private Long id;
	private int orderAmount;
	@Embedded
	private Address address;
	
}
@Embeddable
@Getter @Setter
public class Address {
	private String city;
	private String street;
	private String zipcode;
	
}
insert
			Member member = new Member();
			member.setUsername("member1");
			member.setAge(10);
			em.persist(member);
			
			em.flush();
			em.clear();

영속성을 비워낸 이후 영속성 컨텍스트 관리
- result라는 결과값이  select문을 날림으로 인해서 영속성 컨텍스트에 관리가 될까 안될까?
 
update가 된다 -> 영속성 컨텍스트에서 관리가 된다. (O) 
update가 안된다 -> 영속성 컨텍스트에서 관리가 안된다.  
			List<Member> result = em.createQuery("select m from Member m",Member.class)
									.getResultList();
			
			
			Member findMember = result.get(0);
			findMember.setAge(20);
			System.out.println(findMember.getAge());

join
		
		List<Team> result = em.createQuery("select m.team from Member m", Team.class)
								.getResultList();
        
		List<Team> result = em.createQuery("select t from Member m join m.team t",
					Team.class).getResultList();

embeded타입 프로젝션 select
			
			em.createQuery("select o.address from Order o", Address.class)
				.getResultList();
			
			
			em.createQuery("select o.address from Address o", Address.class)
				.getResultList();
			
			em.createQuery("select distinct m.username , m.age from Member m")
				.getResultList();
- orders라는 테이블에서 그 안에있는 address 라는 컬럼만을 조회

 
 

 
 
결과 값을 받아오는 방법
			
			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]);
			
			
			List<Object[]> resultList =  em.createQuery("select m.username , m.age from Member m")
									.getResultList();
			Object[] result = resultList.get(0);
			System.out.println("username = " + result[0]);
			System.out.println("age = " + result[1]);			
  			
			
			List<MemberDTO> result 
				=  em.createQuery("select new com.koreait.jpql.MemberDTO( m.username , m.age ) from Member m")
					.getResultList();
			
			MemberDTO memberDTO = result.get(0);
			System.out.println("username : " + memberDTO.getUsername());
			System.out.println("age : " + memberDTO.getAge());
- 3번 방법 DTO설정, 특정 결과값만을 따로 받아오는 DTO가 필요시 사용
 
@Getter @Setter @ToString
public class MemberDTO {
	private String username;
	private int age;
	
	public MemberDTO(String username, int age) {
		super();
		this.username = username;
		this.age = age;
	}
}

🧩 페이징 처리
setFirstResult(int startPoint)		: 조회 시작 위치(0부터 시작) 
setMaxResults(int maxResults)		: 조회할 데이터 수 
- 몇 번째부터 몇 개 가지고 올래?
 
	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();
			
			
			String jpql = "select m from Member m order by m.id";
			List<Member> resultList = em.createQuery(jpql, Member.class)		
										.setFirstResult(30)
										.setMaxResults(10)
										.getResultList();
			
			System.out.println("result.size : " + resultList.size());	
			
			for(Member member1 : resultList) {
				System.out.println("member1 = " +member1.toString());
			}

🧩 JPA서브쿼리 한계
where, having 절에서 사용가능 -> JPA 표준 스펙 
select 절에서도 가능 -> 하이버네이트에서 지원 
from 절의 서브쿼리는 현재 JPQL에서 불가능 
			
		String sql = "select m from Member m inner join m.team t where 	t.name = :teamName";
		List<Member> resultList = em.createQuery(sql, Member.class)
										.getResultList();
			
		
		String sql = "select m from Member m left outer join m.team t";
		List<Member> resultList = em.createQuery(sql, Member.class)
				.getResultList();
			
			String sql = "select m from Member m where m.age > (select avg(m2.age) from Member m2)";
			List<Member> resultList = em.createQuery(sql, Member.class)
										.getResultList();