You will be fine

<토비의스프링> 7.5~7.6.1 내장형 데이터베이스

by BFine
반응형

7.5 DI를 이용해 다양한 구현방법 적용하기 

 7.5.1 ConcurrentHashMap을 이용한 수정 가능 SQL 레지스트리 

  - 운영시스템에서 실시간 변경 작업을 할때 항상 생각해야 하는 것은 동시성이다.

        => 안전한 업데이트가 가능하도록 SqlRegistry로 변경하자!

  - 기존 HashMap보다는 ConcurrentHashMap을 사용하자

        => 데이터 조작시 전체데이터에 락을 걸지 않으며 조회에는 락이 없다!, 성능 Good

 

 7.5.2 내장형 데이터 베이스 

  -  ConcurrentHashMap 성능이 좋기 하지만 데이터양이 많아지거나 복잡한 데이터를 조회 할 경우에 한계가 있다.

  -  어플리케이션에 내장돼서 어플리케이션과 함께 시작 종료되는 DB(H2,HSQL)

  -  메모리에 저장되기 때문에 IO로 인한 부하가 적어서 성능이 뛰어남

  -  어플리케이션 내에서 DB를 기동시키고 데이터를 실행하는 등 초기화 작업이 별도로 필요

       => 초기화 작업을 지원하는 내장형 DB 빌더를 제공 (URL, 드라이버 등 초기화)

  -  DB 빌더는 엔진 생성하고 초기화 하며 Connection을 생성해주는 DataSource 객체를 돌려준다.

new EmbeddedDatabaseBuilder() // 빌더오브젝트 생성
.setType(내장형DB종류)
.addScript(초기화에 사용할 DB 스크립트의 리소스)// 하나이상 저장가능
.build();

- EmbeddedDatabaseBuilder 는 적절한 메소드를 호출해주는 초기화 코드가 필요

     => 초기화 코드가 필요하면 팩토리 빈으로 만드는 것이 좋다.

- SpringXml 전용 코드로 팩토리 빈을 쉽게 만들 수 있다.

- Test Class도 상속이 가능 하다.

public abstract class AbstractUpdatableSqlRegistryTest {
	UpdatableSqlRegistry sqlRegistry;
	
	@Before
	public void setUp() {
		sqlRegistry = createUpdatableSqlRegistry();
		sqlRegistry.registerSql("KEY1", "SQL1");
		sqlRegistry.registerSql("KEY2", "SQL2");
		sqlRegistry.registerSql("KEY3", "SQL3");
	}
	
	abstract protected UpdatableSqlRegistry createUpdatableSqlRegistry();

	@Test(expected=SqlNotFoundException.class)
	public void unknownKey() {
		sqlRegistry.findSql("SQL9999!@#$");
	}
	
	protected void checkFind(String expected1, String expected2, String expected3) {
		assertThat(sqlRegistry.findSql("KEY1"), is(expected1));		
		assertThat(sqlRegistry.findSql("KEY2"), is(expected2));		
		assertThat(sqlRegistry.findSql("KEY3"), is(expected3));		
	}
	
	
	
	@Test(expected=SqlUpdateFailureException.class)
	public void updateWithNotExistingKey() {
		sqlRegistry.updateSql("SQL9999!@#$", "Modified2");
	}
}
public class EmbeddedDbSqlRegistryTest extends AbstractUpdatableSqlRegistryTest {
	EmbeddedDatabase db;
	
	@Override
	protected UpdatableSqlRegistry createUpdatableSqlRegistry() {
		db = new EmbeddedDatabaseBuilder()
			.setType(HSQL)
			.addScript("classpath:springbook/user/sqlservice/updatable/sqlRegistrySchema.sql")
			.build();
		
		EmbeddedDbSqlRegistry embeddedDbSqlRegistry = new EmbeddedDbSqlRegistry();
		embeddedDbSqlRegistry.setDataSource(db);
		
		return embeddedDbSqlRegistry;
	}
	
	@After
	public void tearDown() {
		db.shutdown();
	}

}

 7.5.3 트랜잭션 적용 

  -  하나이상의 SQL을 맵으로 한번에 수정해야하는 경우 심각한 문제 생길 수도 있음

  -  템플릿/콜백 패턴을 적용하여 Transcation을 적용하자

public class EmbeddedDbSqlRegistry implements UpdatableSqlRegistry {
	SimpleJdbcTemplate jdbc;
	TransactionTemplate transactionTemplate;
	
	public void setDataSource(DataSource dataSource) {
		jdbc = new SimpleJdbcTemplate(dataSource);
		transactionTemplate = new TransactionTemplate(
				new DataSourceTransactionManager(dataSource));
		transactionTemplate.
        	setIsolationLevel(TransactionTemplate.ISOLATION_READ_COMMITTED);
	}
 }
 
 public void updateSql(final Map<String, String> sqlmap) throws SqlUpdateFailureException {
	transactionTemplate.execute(new TransactionCallbackWithoutResult() {
		protected void doInTransactionWithoutResult(TransactionStatus status) {
			for(Map.Entry<String, String> entry : sqlmap.entrySet()) {
				updateSql(entry.getKey(), entry.getValue());
			}
		}
	});
}

 

7.6 스프링 3.1의 DI 

 - 어노테이션이 활성화 되면서 메타정보를 이용한 프로그래밍 방식으로 많이 사용됨

 - 자바는 소스코드가 컴파일된 이후에 클래스 파일에 저장됐다가 JVM에 의해 메모리로 로딩되어 실행된다.

     => 이외에도 다른 자바코드에 의해 데이터처럼 취급되기도함

 - 어노테이션은 자바코드가 실행되는데에는 직접 참여하지 못함

     => 복잡한 리플렉션 API를 이용해 메타정보를 조회하고 설정된값을 가져와 참고하는 방법이 전부

 - 이런데도 활용이 늘어난 이유는?

     => 핵심로직을 담은 자바코드, 이를 활용한 IoC 프레임워크, 프레임워크가 참조하는 메타정보 세가지로

          구성하는 방식에 잘어울리기 때문

 - UserDao가 한가지가 아니라면 DaoFactory 같은 단순 자바코드로 만든 관계설정은 불편함

     => Xml 설정으로 진화(작성하기 편함, 빌드과정 필요없음)

     => 하지만 어노테이션은 자바코드로 작성 

  - XML 보다 어노테이션이 유리한점

      1. 직관적으로 타입레벨에 적용하는지 알 수 있음

      2. 해당 타깃의 다양한 부가 메타정보를 얻을 수 있음 (패키지,접근제한자, 구현 인터페이스, 필드&메서드구성)

            

7.6.1 자바코드를 이용한 빈설정

  -  스프링 3.1 부터는 XML을 어노테이션으로 대체하여 사용이 가능하다.

  -  @ContextConfiguration(location=) 은 DI 정보를 어디서 가져오는지 지정 

  -  XML을 대신하여 자바 클래스에 @Configration을 사용

  -  @ImportResource로는 DI 설정정보를 xml로 가져와서 주입( 이것도 제거됨 )

  -  클래스로 변경하면 기존의 <context: annotation-config/> 코드는 제거해도 된다.

        => 컨테이너가 직접 @PostConstruct 를 처리하는 빈후처리기를 등록해줌

  -  @Resource는 필드 이름 기준,  @Autowired 필드 타입 기준 으로 DI

  -  <tx:annotation-driven/>@EnableTransactionManagement로 사용 가능

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기