JPA 와 함께 - 느낀점

이미지
Java Persistence API(JPA)  김영한님의 JPA 기초편 을 끝까지 수강했다. 작년부터 새벽에 짬내서 들었지만, 아이들의 방해(?)로 6개월 걸렸다. 듣고 많은 내용에 대해서 생각이 들었다. JPA 란?  자바 퍼시스턴스 API 이라 불리는 객체와 관계형 DB 를 관리하는 자바 API다. 2006년 1.0을 발표했으며 현재 2.1버젼까지 발전했다. Mybatis도 좋지만...  Mybatis로 Web개발을 하면, 마음 한켠이 찝찝(?)했다. 분명 Mybatis가 직관적으로 SQL을 관리해서 편하다. 하지만 점점 SQL 중심 개발로 진행할 수록, Spring의 역활에 의구심이 들었다. Web 서버, JSON 변환 외 비즈니스 로직은 점점 Mybatis 중심으로 만들어졌다.  그러다 객체설계 책을 접하고, Spring JPA를 알게 되었고, 유료 강의수강를 수강했다. Oracle Forms와 비교   가장 오래한 직업인 Oracle Forms 개발 관점에서 봤을 때, 비슷하면서 더 발전한 API라고 생각한다. 비슷한 점은 Primary Key 기준 CRUD Transaction 자동 실행과 부모-자식 관계 자동 설정이다.   더 발전한 API로 느낀 이유는 특정 DB를 위한 API가 아닌 범용 API라는 점이다. ANSI 표준 SQL과 Dialect로 DB Vendor별 차이를 좁히기도 한다. 그래서 개발자는 SQL보다는 객체에 좀더 집중할 수 있도록 도와준다. 객체지향으로 가는 길.  이제 비즈니스 로직을 객체에 자연스럽게 녹일 수 있다. 비즈니스 로직과 SQL 문장을 만들필요 없이 객체의 로직의 결과가 저장되어야 한다면 JPA를 사용하면 된다.  마치며... 홍보글은 아니지만, 꼭 듣기를 바란다. 이제 DB 없는 프로그램은 상상하기 힘들다. 객체와 DB설계 중 고민 하나를 덜어낼 수 있는 좋은 기회다. (물론 DB를 전혀 신경쓰지 않아도 되는 건 아니다.)

Oracle SQLDeveloper 성능 향상 방법 정리.

이미지
Oracle SQLDeveloper More Faster~!! SQLDeveloper  오라클에서 무료로 제공하는 DB 관리와 SQL 쿼리 기능을 가진 Tool이다. 좋은 Tool인데 처음 실행이 너무 느리다. 몇년간 봐왔지만 개선이 잘 안되는 것 같다. 이번 Post에서 성능 향상 방법 3가지와 도움되는 설정 2가지를 이야기한다. 시작시간 단축 1. Extension 끄기  최초 SQLDeveloper는 모든 기능이 활성화 되어있다. SQL 개발만 설정하기 위해서는 '도구 > 기능' 메뉴로 들어가 기능을 비활성화 시키자  Database 이전과 버젼제어 기능을 해지한다. Database 이전은 DB Vendor별 Migration을 지원한다. 버젼제어는 Git과 Subversion을 지원한다.  그리고 데이터베이스 옵션에서는 'Oracle OLAP'만 설정하자. 그러면 SQL 개발을 위한 기능들만 자동으로 설정된다. 2. IndexPreferencesTask 기능 Off.  이 기능이 성능하향의 주범(?)이다. 경험 상, 이 기능이 없어서 문제된 적이 없으니 사용하지 말자. 기능을 사용하지 않기 위해서는 실행 Option에 추가해야 한다. 경로는 아래와 같다. sqldeveloper폴더\sqldeveloper\bin\ sqldeveloper.conf  파일 내부에 아래 Option을 추가하자. AddVMOption -DIndexedPreferencesCommand = false 3. Window 테마로 변경  이론상 SQLDeveloper의 'Oracle' 테마는 '화면실행 > OS에 맞는 화면구성 > Oracle 테마 덧씌우기'라고 한다...

Finance와 함께 - Java로 구현하는 리스부채

이미지
Lease Accounting in Java  이번 Post는 2019년부터 적용한 회계법인 리스부채에 대한 이야기를 한다. 기본적인 원리와 등록예제를 설명한다. 리스부채  'K-IFRS 1116'가 도입되었다. 기존 사용권 자산(Righ-of-use assets, 이하 리스자산)은 비용 지불 분개만 기재하면 끝났다. 앞으로는 자산과 부채를 현재가치 금액으로 분개를 기재해야 한다.  리스 부채 분개  모든 리스자산를 등록하는 것이 아니다. USD 5,000 이하 또는 리스기간이 1년 이내인 리스거래는 비용만 처리해도 된다. 효과  리스효과에 대해서 부정적인 기사들이 많다. 부채나 이자비용이 높아져 회사운영에 나쁜 영향을 준다는 기사들이다. 사실 결과적으로 리스부채는 경제적 득실이 없다. 하지만 관리적인 측면이 크다. 빌린 자산을 비용으로 운영했을 때와 부채로 운영했을 때는 제무제표의 부채비율이 다르기 때문이다.  부채비율은 재무 건전성을 확인하는 지표다. 이 지표의 정확한 정보제공이 주주들의 의사결정에 영향을 끼치기 때문에 세분화시킬 필요가 있다. 그러므로 투자자는 이 항목을 잘 볼 필요가 있다. Java Lease Class Diagram LeaseContract.class  리스계약 정보를 가지고 있다. 기간, 이자율, 계약금액, LeaseSchedule의 정보를 가지고 있다. Lease Schedule과 연관관계를 맺기 위해 addSchedule()만 Public으로 선언했다. LeaseSchedule.class  리스회사에 지급할 계획정보를 가진다....

Scott 과 함께 - Cross Join 을 Java 로 구현하기

이미지
Cross Join in Java  이번 Post는 Cross Join을 Java로 구현한다. Cross Join은 조건없이 테이블 2개를 합치는 Join이다. 조건이 없다보니 데이터는 2개 테이블의 행 개수의 곱셈이다. 만약 A 테이블(2건)과 B 테이블(3건)을 Cross Join한다면, 행 개수는 2 x 3 = 6 이다.  그런데 궁금한 점은 이런 Join은 어디에 사용하는가? 개인적으로 집계 데이터의 Driving Table로 사용한다. Scott 도메인에서 예를 만든면, '모든 부서 x 모든 Job'의 급여평균을 구할 때 사용할 수 있다. 그래서 경험상 보면, Cross Join은 단독으로 사용하지 않고 Outer Join과 같이 사용한다. SQL with job as ( select distinct emp . job as job_name from emp ) select dept . dname , job . job_name , avg ( emp . sal ) from job cross join dept left outer join emp on ( job . job_name = emp . job and dept . deptno = emp . deptno ) group by dept . dname , job . job_name order by dept . dname , job . job_name    아래 그림처럼 부서에 Job이 없더라도 같은 형식을 유지하기 위해서 Cross Join을 사용한다. 여기서 알아야 할 이슈가 있는데, Cross Join으로 만들어진 Driving Table은 Index가 없기 때문에 Join에 대한 Cost가 높다. 그래서 Driving ...

Finance와 함께 - Java로 구현하는 현재가치

이미지
Present Value with Java  이번 Post는 현재가치를 Java로 구현한다. 재무업무 상 필요한 개념이며 우리가 살아가는데 요긴하게 쓰일 수 있으니 꼭 알아가길 바란다. PV(Present Value)  미래에 얻게 될 확실한 부의 가치를 현재의 가치로 환산한 값이다. 줄여서 현가( 現價 )라고 한다.  2000년의 1,000원이 2021년의 1,000원과 동일한 가치를 가지지 않는다. 예를 들어보자.  연 금리가 2%라고 생각하면자. 국민연금 납입기간이 끝나 1억원의 연금을 받으려고 한다. 이 때, 2가지 선택지가 있다.  지금 당장 1억원을 받는다. 2년 후에 이자 붙여서 1억 4백만원을 받는다.  어떤 선택이 더 이득일까? 1번을 선택 후 은행에 저금해보자. 2년 후 2번과 비교했을 때, 1번이 4만원이 더 이득이다. 이처럼 현재의 기준으로 미래를 예측한 가치를 현재가치라고 한다. 기준은 금리, 이자율,...이 있다. 2년 후의 금리로 계산한 최종금액 구현  현재가치를 구하는 공식은 이  Link 를 참조하자. @Test public void calculatePV_just_function () { double interestRate = 0.02d ; double amount = 100000000 ; double year = 2 ; double pv = amount * Math . pow (( 1 + interestRate ), year ); String formattedPV = NumberFormat . getNumberInstance (). format ( pv ); Sy...

Scott 과 함께 - Outer Join 을 Java 로 구현하기.

이미지
Outer Join  이번 Post는 Outer Join을 Java로 구현한다. 이전 Inner Join Post와 동일하게 부서의 Job 별 평균급여를 구하지만, 이번에는 직원이 없는 부서도 같이 출력해야 한다. SQL 부서/Job 평균 급여에 Operations 부서도 추가.  Operations 부서는 직원이 없는 부서라서, Job과 평균급여는 Null이다. Operations의 Job은 Null이고 평균급여는 0으로 Java에서 표현한다. select d . dname , e . job , avg ( e . sal ) from dept d left outer join emp e on d . deptno = e . deptno where 1 = 1 group by d . dname , e . job ; Java 부서 Stream + 직원 Stream  처음 생각했던 방법은 부서 Stream의 map()에서 직원 Stream으로 Job별 평균급여를 가져오려고 했지만 실패 했다. Operations의 직원이 없어 직원 Stream의 결과가 Null이면, Operation이 부서 Stream에서 사라졌다. depts . stream () . map ( department -> employees . stream () . filter ( employee -> employee . getDepartment () == department ) . collect ( Collectors . groupingBy (...)) ); 부서 List + 부...

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" ; 결과 ...