Scott 과 함께 - Inner Join 을 Java 로 구현하기
Inner join with Java
이번에는 SQL Join과 집계를 Java로 구현한다. 예제는 부서와 Job별 월급의 평균을 가져오는 것이 목적이다.
SQL
Java의 결과는 순서에 상관없이 위 그림과 같이 나타나야 한다. 다만 평균급여는 '*'을 사용해 100단위로 표기한다.
select dept.dname, emp.job, avg(emp.sal) from emp inner join dept on emp.deptno = dept.deptno group by dept.dname, emp.job order by 1, 2;
Java
JPQL로 필요한 컬럼 조회 후, Java로 집계.
JPQL로 데이터로 직원들의 부서이름, Job, 급여 데이터를 가져온다. 가져온 데이터를 Collectors.groupingBy로 평균급여를 계산한다.
부서이름, Job, 급여는 객체가 이닌 스칼라 타입이기 때문에 결과는 List<Object[]>이다. 배열보다는 편하게 데이터를 꺼내기 위해서 DTO 객체를 만들었다.
public class DeptJobCountDto { private String departmentName; private EmployeeJob job; private Double amount; ... } ... Strin sql = "select new dto.DeptJobCountDto(d.name, e.job, e.salary) from Department d join d.employees e";
결과
![]() |
ScottTest.innerJoin_Stream() 결과. |
연관관계로 조회 후, Java 로 집계.
이번에는 모든 직원정보를 JPQL로 가져와 집계한다. 이 때 부서는 지연로딩으로 가져온다. 결과는 DTO 조회와 동일하다.
@Test public void innerJoin_JPA_Association_Stream() { String sql = "select e from Employee e"; List<Employee> employees = entityManager.createQuery(sql, Employee.class) .getResultList(); Map<Department, Map<EmployeeJob, Double>> results = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.groupingBy(Employee::getJob, Collectors.averagingDouble(Employee::getSalary)))); ... }
결과
![]() |
ScottTest.innerJoin_JPA_Association_Stream() 결과 |
마치며
이번 Post에서는 Inner Join을 구현했다. 좋은 방법이 생각나면 Update하겠다.. 소스는 Github를 참조하자.
참조
- https://akageun.github.io/2019/08/06/java-stream-groupby.html
- https://www.baeldung.com/java-groupingby-collector
- https://dzone.com/articles/using-java-collectors
- https://mingggu.tistory.com/77
- https://blog.jooq.org/2015/08/13/common-sql-clauses-and-their-equivalents-in-java-8-streams/
- http://blog.weirdx.io/post/55568
댓글
댓글 쓰기