본문 바로가기
캠퍼스/Java

56.Service

by Sylar 2022. 8. 17.

저번에 쓰던거 그대로 들고옴.

 

 

이런 기능들을 추가해볼 예정이다.

 

 

 

EmpDao와 DeptDao를 컴포지션 했다.

 

서비스는 Dao를 엮어서 써야 할 수도 있고 하나만 쓸 수도 있다.
서비스를 만드는 이유는 외부에서는 Dao를 직접 건드리지 않고 해당 서비스를 이용하여 건드린다.

MyService 는 EmpDao와 DeptDao에 의존하는 모습이다.
둘이 없으면 MyService가 없으면 사용 할 수없는 프로그램이다.

 

 

이렇게 MyService에 EmpDao와 DeptDao를 의존시켰다.

이걸 의존성 주입을 했다고 한다.

 

의존성 주입(dependency injection)

주입 : 서비스(의존성)를 사용하려는 클라이어언트(객체)로 전달하는것을 의미.

의존성 주입의 의도 : 객체의 생성과 사용의 관심을 분리하는 것이다. 
 -> 클라이언트가 주입자와 서비스 구성방식 또는 사용중인 실제 서비스에 대해 알필요가 없음.
 -> 회원가입을 할때 아이디와 비밀번호는 어느 테이블에 저장되고 어떻게 분할되고 이런거 알 필요 없단 소리.
클라이언트는 서비스의 사용 방식을 서비스의 고유한 인터페이스에 대해서만 알면 된다. 
 -> 뭐 누르면 장바구니에 담기고 이런거만 알면됨 

 

 

전 포스팅에서 다 만들어놓은거 연결했다.

 

 

이게 오늘의 문제. 두가지 이상의 일을 해야하는 코드이다.

 

insert와 update를 같이 써야 하고, 동적으로 만들어야 한다 ( 고르는 인원이 몇명일지 모름 )
1. 체크의 갯수를 알아야함 . ( 인원을 몇명 골랐는가 )
2. 직원의 프라이머리 키 가 필요. ( 업데이트를 해야 하기 때문 )

 

TF팀 제작순서 

1. Dept entity를 먼저 받아야함. ( 팀창설 먼저 )
2. ArrayList<Integer>로 받아내야 함. ( 몇개 올지모름 )
이런식으로 만들면 됨.

 

부서추가가 성공하면 r1에 1이 대입된다. 변화가 없으면 0, 오류시 -1

r1 == 1 일경우 부서내 인원을 배치시키는 작업이다.

성공하면 for문이 한번 더 돌고 실패 또는 변화가 없으면 break로 빠져나간다.

 

 

MyService heap 공간에 EmpDao,DeptDao 둘다 뜨게 만들었다.

 

MyService는 EmpDao나 DeptDao를 상속할 순 없다 ( 다형성 무시됨 ). 상속으로 안되면 컴포지션을 써라.


-컴포지션 ? 

다른객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 메서드를 호출

 -> 다른객체의 인스턴스를 상태로 등록하고 생성자로 주입 받아라.

MyService myService = new MyService(empDao, deptDao);

이렇게.

 

 

전달할 데이터를 작성하고 실행시키면 된다.

 

 

정상적으로 들어간 모습.

하지만 저런 코드는 문제가 있다.

Connection conn = DBConnection.connection();이 3번 들어갔다.

이소리는 DB에 세션을 3번이나 한다는 소리.

 

try가 끝나면 사라지긴 하지만 바로 사라지지 않음
가비지 컬렉션은 바로바로 사라지게 만들지 않고 한번에 모아서 가기 때문
그래서 Connection 할때 close를 달아줘야 한다. -> 가비지컬렉션을 이용하지 않고 직접 끊어버림.


커넥션 객체를 들어올때 마다 만드는것 보다 풀링( 미리 만들어놓음 )하여 재사용 하는게 효과적이다.

 

다시 코드로 돌아와서, 우리는 세션을 종료할때 자동으로 commit하게 짜놨다.

 

여기서 문제가 터진다.

부서추가 에서 conn이 한번 된다. ( 성공시 넘어가고 실패시 여기서 프로그램이 끝남 )

만약 부서추가에 성공한 후에 직원수정이 실패하면 

부서는 추가되고 직원만 안들어 간다. ( 직원은 실패해서 commit이 안되지만 부서는 성공했으니 commit )

 

이 문제를 해결하기 위해서는 conn을 한번만 한 후에 모든걸 성공할때만 commit하게 하고 아닌경우

rollback을 하게 만들어야한다.

 

 

Connection conn = DBConnection.connection();을 모조리 다 지우고 위에 private로 conn의 잡았다.

 

 

MyApp에서 Connection을 잡은 후에 두군데에 뿌렸다.

 

 

오토커밋을 꺼준다 ( 뭐 할때마다 커밋을 하면 트렌직션 관리가 안되기 때문 )

 

트렌직션의 독립성 

 

커밋을 안하면 트렌직션이 안끝나면 다른 트렌직션 접근시 셀렉트만 가능

( 다른한명이 커밋하기 전까지 수정 및 추가불가 ) 

간단히 말하면 오라클에서 변경중일때 자바로 변경하려고 하면 안됨.

 int count =0;	
 count = count+  deptDao.부서추가(dept); 
 //부서추가가 성공하면 +1 아니면 0 또는 -1
  for (int i = 0; i < empnos.size(); i++) {
   count = count + empDao.직원수정(empnos.get(i), dept.getDeptno());
   // 직원수정 성공시 마다 +1 아니면 0 또는 -1
 }
 try {
  if(count == empnos.size() +1) {
  //count가 empnos.size+1과 같냐? ( +1은 부서추가 성공 여부 물어보는거 )
   conn.commit();
   System.out.println("커밋됨");
  }else {
   conn.rollback();
   System.out.println("롤백됨");
 }
 } catch (Exception e) {
  e.printStackTrace();
 }
}

이렇게 코드를 바꿨다.

 

 

70번 부서를 생성했다. 정상적으로 커밋되었다고 나왔으니 확인해보자

 

 

재대로 들어갔다.

 

 

일부러 오류낸 모습

'캠퍼스 > Java' 카테고리의 다른 글

58.Try, Catch  (0) 2022.08.23
57.DB와 JAVA 연결하기  (0) 2022.08.19
55. JAVA로 DB추가,수정,삭제  (0) 2022.08.16
54.JAVA로 DB 리드  (0) 2022.08.16
53.Select, Push  (0) 2022.08.16