JAVA/SPRING 2009. 5. 6. 11:58



1.클라이언트의 요청이 DispatcherServlet에 전달
2.DispatcherServlet은 HandlerMapping을 사용하여 클라이언트의 요청을 처리할 컨트롤러 객체를 구한다
3.DispatcherServlet은 컨트롤러 객체의 handleRequest()메소드를 호출하여 클라이언트 요청 처리
4.컨트롤러의 handleRequest()메소드는 처리결과 정보를 담은 ModleAndView객체를 리턴
5.DispatcherServlet은 viewResolver로부터 응답 결과를 생성할 뷰 객체를 구한다.
6.뷰는 클라이언트에 전송할 응답을 생성

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 <display-name>
 SpringTest</display-name>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
 
 <servlet>
  <servlet-name>
   dispatcher
  </servlet-name>
  <servlet-class>
   org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>
   dispatcher
  </servlet-name>
  <url-pattern>*.htm
  </url-pattern>
 </servlet-mapping>

 
</web-app>

dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!--핸들러-->
<bean id = "handlerMapping"
 class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name = "/hello.htm"
 class = "kame.spring.chap04.HelloController" />
<bean id="viewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/view/" />
  <property name="suffix" value=".jsp" />
 </bean>  
</beans>

web.xml에 DispatcherServlet설정과 어플리케이션 컨텍스트 설정
.hml으로 들어오는 클라이언트의 요청을 DispatcherServlet이 처리하도록 설정.
DispatcherServlet은 WEB-INF/에 위치한 [서블릿이름]-servlet.xml파일을 설정 파일로 사용

package kame.spring.chap04;
import java.util.Calendar;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HelloController extends AbstractController{
 @Override
 protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception{
  ModelAndView mav = new ModelAndView();
  mav.setViewName("hello");
  mav.addObject("greeting",getGreeting());

  return mav;
 }
 private String getGreeting(){
  int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
  if(hour >= 6 && hour <= 10){
   return "좋은아침";
  }else if(hour > 12 && hour <= 15){
   return "점심해써?";
  }else if(hour >= 18 && hour <= 22){
   return "좋은밥";
  }
  return "안녕하세요";
 }
}

처리결과를 ModelAndView에 담아 DispatcherServlet에 전달. ModelAndView는 컨트롤러의 처리결과에 대한 응답 화면을 생성할 뷰 정보저장.

<bean id = "handlerMapping"
 class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name = "/hello.htm"
 class = "kame.spring.chap04.HelloController" />


BeanNameUrlHandlerMapping은 URL과 일치하는 이름을 갖는 컨트롤러를 사용. http://localhost/contextpath/hello.htm으로 요청이 들어올 경우, 이름이 "/hello.htm"인 컨트롤러를 이용하여 클라이언트의 요청을 처리한다.

처음해보면서 안되었는데... 톰캣의 server.xml 올바르게 잡고,, 소스 오타수정 모두 하고.. 모두 완벽했었는데 안되었다.
http://localhost/spring/view/hello.htm 주소창에 요렇게 치니까 404에러... 톰캣에서 docBase를 WebContent까지 패스에 잡아주었으므로 WebContent폴더 안에 있는 view폴더부터 쓰는것이 당연하다.. view에 있는 hello.jsp로 직접 접근하니 되었는데...(물론 매핑이 안되서 결과물은 안나왔다..)
안되서... 예제도 설치해서 해봤는데.. 예제는 이상한 에러 쫘악... 별짓다해봤다.. 자바버전도 수정해보고 폴더를 옮겨보기도 했는데...
어쨌든 해결했는데.... 주소창에
http://localhost/spring/hello.htm 로 view폴더를 빼고 치니까 되는거다!!. 프레임워크니까!! 괜히 프레임워크겠어!! spring이 톰캣에 설정한 패스이름이다.... 결론은 폴더고 나발이고간에 xml에 설정해놓으면 패스명/xxx.htm하면 되는거다!!

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>인사</title>
</head>
<body>
인사말 " <strong>${greeting}</strong>
</body>
</html>
신기한것은 스트럿츠2처럼 태그라이브러리를 상단에 정의해주지 않았는데도 요 $ 태그가 먹힌거..(요걸머라고하나..) 왜인지는 모른다..
 
mav.setViewName("hello");

뷰이름을 가지고 viewResolver가 이 이름을 이용하여 알맞은 view객체를 선택한다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:55


스프링 컨테이너의 주요 인터페이스


1.1 BeanFactory인터페이스 

org.springframework.beans.factory.BeanFactory는 빈 객체를 관리하고 각 빈 객체 간의 의존 관계를 설정해 주는 기능을 제공.
XmlBeanFactory클래스가 구현.
Resource인터페이스를 사용하여 다양한 종류의 자원을 동일한 방식으로 표현.
Resourcce res = new FileSystemResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
ParserFactory factory = (ParserFactory)factory.getBean("parserFactory");

특정 리소스로부터 설정 정보를 읽어와 XmlBeanFactory객체를 생성한 뒤에는 getBean()메소드를 이용하여 알맞은 빈을 가져와 사용하면 된다.

1.2 ApplicationContext , WebApplicationContext 인터페이스
빈팩토리인터페이스를 상속받은 인터페이스로서 빈팩토리가 제공하는 빈 관리 기능 이외에 파일과 같은 자원처리추상화, 메시지 지원 및 국제화지원, 이벤트 지원등 추가적인 기능을 제공하고 있다. BeanFactory보다 ApplicationContext 구현 클래스르 주로 사용한다.

빈(Bean)의 생성과 의존관계 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">


<bean id = "writeArticleService"  class = "kame.spring.chap02.WriteArticleServiceImpl" >
    <constructor-arg>
        <ref bean = "articleDao" />
    </constructor-arg>

</bean>

<bean id = "articleDao" class = "kame.spring.chap02.OracleArticleDao" >
</bean>


bean의 id는 객체명이다. class는 이 객체를 참조하는 클래스가 있는 경로를 써주면 된다.
생성자를 통해 의존하는 객체르 전달받는 경우 <constructor-arg>태그를 이용하여 의존하는 객체를 전달할 수 있다.
위 코드는 WriteArticleServiceImpl클래스의 생성자에 식별 값이 "articleDao"인 빈 객체를 전달한다는 것을 의미한다.
코드로는....
OracleArticleDao articleDao = new OracleArticleDao();
WriteArticleServiceImpl writeArticleService = new WriteArticleServiceImpl(articleDao);

ref bean을 안쓰고 직접 constructor-arg ref="articleDao" 도 가능하다. 또한 <value>값도 설정할 수 있는데...
<constructor-arg>
        <value>10</value>
</constructor-arg>

이런식으로 가능핟. value값은 String타입으로 처리된다. 따라서 숫자 3000의 value를 전달해도 파라미터가 String타입의 파라미터가 정의되어있으면 매핑되고,, 만약 스트링이 없고 int타입이 있으면 int타입으로 매핑된다.

프로퍼티

프로퍼티는 익숙하지... setXXXXX()형태의 메소드를 매핑한다. 앞의 set을 빼고 XXXXX가 이름이 된다.
이렇게 생각하자... 
bean은 객체
property는 (set)메소드.. 


<bean name = "monitor" class = "kame.spring.chap02.SystemMonitor" >
    <property name = "periodTime" value = "10" />
    <property name = "sender" value = "smsSender" />
</bean>

setPeriodTime메소드에 파라미터값으로 10을 전달, setSender메소드에 smsSender값을 전달한다. 쉽지 않은가..ㅋ
이외에도 컬렉션타입(set,map,list,제네릭)으로도 의존관계 설정이 가능하니 책을 참조하자.

의존관계 자동 설정

byName : 프로퍼티의 이름과 같은 이름을 갖는 빈 객체를 설정한다.
byType : 프로퍼티의 타입과 같은 타입을 갖는 빈 객체를 설정한다.
constructor : 생성자 파라미터 타입과 같은 타입을 갖는 빈 객체를 생성자에 전달한다.
autodetect : 생성자방식을 먼저 적용하고 byType방식을 적용하여 의존객체 설정한다.


<bean id = "monitor" class = " ....SystemmMonitor" autowire = " byName" />

1)프로퍼티 이름을 이용한 의존 관계 자동 설정
<bean name = "writeArticleService"
         class = "kame.spring.chap02.WriteArticleServiceImpl" 
autowire = "byName" />
<bean name = "articleDao" class = "kame.spring.chap02.MysqlArticlDao" >
<bean name = "myArticleDao" class = "kame.spring.chap02.MysqlArticlDao" >

WriteArticleServiceImpl클래스가 이름이 "articlDao"인 프로퍼티를 갖고 있다면, 이름이 "articleDao"인 빈 객체가 프로퍼티의 값으로 전달된다.

2)타입을 이용한 의존 관계 자동 설정
<bean name = "writeArticleService"
         class = "kame.spring.chap02.WriteArticleServiceImpl"
autowire = "byType" >
<bean name = "myArticleDao" class = "kame.spring.chap02.MysqlArticlDao" >
<bean name = "oracleArticleDao" class = "kame.spring.chap02.OracleArticlDao" >

위코드에서 myArticleDao빈 객체와 oracleArticleDao 빈 객체는 둘 다 ArticleDao 타입이기 때문에 어떤걸 프로퍼티에 넣어야 할 지 결정할 수가 없다. 이럴때 예외를 발생시킨다.

posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:48


최범균님의 책.. 스프링2.5를 보고 공부하고있다.
서평이나 사람들 말을 들어보면 완벽한 책이라고... 베스트셀러에다..
인정한다. 헌데 나랑 좀 맞지 않는 듯... 아..그것보다 내 실력이 쓰레기이기 때문이겠지...ㅋㅋ
구성은 좋은데 너무 딱딱하여 이해가 잘 가지 않는다. 논문보는듯..;;

아무튼 AOP.. 부분.. 다 훑어봤지만 20%정도 이해한듯 하다. 헐..어려워..

AOP
어플리케이션 전반에 걸쳐 필요한 기능. 핵심 비즈니스 기능과 구분하기 위해 공통기능을 공통관심사항(cross-cutting concern)
핵심 로직을 핵심관심사항(core concern)이라고 한다.

AOP용어
Advice : 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의하고 있다. 예를 들어, 메소드를 호출하기 전에 트랜잭션을 시작한다(공통기능) 기능을 적용한다는 것을 정의하고 있다.
Joinpoint :  Advice를 적용 가능한 지점을 의미한다. 메소드호출, 필드값 변경 등이 해당된다.
Pointcut : Joinpoint의 부분 집합으로써 실제로 Advice가 적용되는 Joinpoint를 나타낸다. 스프링에서는 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의할 수 있다.
Weaving : Advice를 핵심 로직 코드에 적용하는 것을 위빙이라 한다. 공통코드를 핵심 로직 코드에 삽입하는 것이 위빙이다.!
Aspect : 여러 객체에 공통으로 적용되는 공통 관심 사항을 Aspect라고 한다. 트랜잭션이나 보안 등이 Aspect의 좋은 예이다.

스프링 API를 이용한 AOP
(1)MethodBeforeAdvice
대상 객체의 메소드를 실행하기 전에 공통 기능을 적용하고 싶을때에 사용되는 Advice인터페이스.

void before(Method method, Object[] args, Object target) throws Throwable;

Method method : 대상 객체에서 실제로 호출될 메소드를 나타내는 Method객체
Object[] args : 메소드 호출시 전달된 인자 목록
Object target : 실제 대상 객체

이외에..
(2)AfterReturningAdvice : 대상객체의 메소드를 실행한 후 공통기능 적용.
(3)ThrowsAdvice : 예외가 발생했을때 공통기능을 적용하고 싶을 때 사용.
(4)MethodInterceptor : 앞의 어드바이스를 모두 합쳐 놓은 인터페이스


Pointcut 및 Advisor 설정
Advice를 작성했다면,, Advice를 어떤 Joinpoint에 적용할지를 지정할 차례이다. 즉, Pointcut을 설정할 차례.

org.springframework.aop.support.JdkRegexMethodPointcut : 정규표현식을 이용하여 포인트컷 정의.
org.springframework.aop.aspectj.AspectJExpressionPointcut : aspectj의 표현식을 이용하여 포인트컷 정의

<bean id = "beforeLogAdvice" class = "kame.......MethodBeforeLogAdvice" />
<bean id = "writePointcut" class = "org.springframework.aop.support.JdkRegexpMethodPointcut">
     <property name = "pattern" value = ".*write.*" />
</bean>

<bean id = "writeAdvisor" class = "org.....DefaultPointcutAdvisor">
    <property name = "advice" ref = "beforeLogAdvice" />
    <property name = "pointcut" ref = "writePointcut" />
</bean>

위 설정은 writeAdvisor는 beforeLogAdvice 어드바이스가 writePointcut 포인트컷에 적용된다는 것을 정의하고 있다. 즉, 메소드 이름에 write를 포함하고 있는 메소드를 호출할때 beforeLogAdvice를 적용하라고 설정하였다.
위 작업은 꾀 성가신 작업인데 RegexMethodPointcutAdvisor를 이용해 작업을 줄일수 있다.

<bean id = "beforeLogAdvice" class = "kame.......MethodBeforeLogAdvice" />

<bean id = "writeAdvisor" class = "org.....RegexMethodPointcutAdvisor">
    <property name = "advice" ref = "beforeLogAdvice" />
    <property name = "pattern" ref = ".*write.*" />
</bean>


AspectJExpressionPointcut

expression프로퍼티를 이용하여 Pointcut을 정의하는 표현식을 설정한다.
<bean id = "getPoint" class = "org......AspectJExpressionPointcut">
      <property name = "expression" value = "execution(public !void get*(..))" />
</bean>

<bean id = "getAdvisor" class = "org.....DefaultPointcutAdvisor" >
       <property name = "advice" ref ="cacheadvice" />
       <property name = "pointcut" ref = "getPoint" />
</bean>
expression프로퍼티는 포인트컷을 표현하는 표현식을 값으로 갖는다. 위 코드에서 excution 명시자는 메소드의 실행을 명시하며, 접근제어가 public 이고 리턴타입이 void가 아니며 메소드의 이름은 get으로 시작하고 0개 이상의 파라미터를 갖는 메소드의 실행 시점을 Pointcut으로 설정함을 의미한다.
posted by 나는너의힘
:
ANT 2009. 5. 6. 11:43


설명을 안써서...
매뉴얼에 나와있지만 써본다.
Apache Ant is a Java-based build tool. In theory, it is kind of like make, without make's wrinkles.

사실 설치하는 것을 설명할 필요는 없다.
http://ant.apache.org/manual/index.html
매뉴얼이 친절하게 알려준다.

여기서 중요한 점은 환경변수 설정인데
- Add the bin directory to your path.
- Set the ANT_HOME environment variable to the directory where you installed Ant. On some operating systems, Ant's startup scripts can guess ANT_HOME (Unix dialects and Windows NT/2000), but it is better to not rely on this behavior.
라고 나와있다.
PATH에 빈디렉터리를 추가해주고 ANT_HOME을 만들어서 ANT의 경로를 추가해주면 된다.
도스창에 들어가서 ant를 치면 메시지가 띡-하고 뜬다. 그 다음에 버전을 체크하면 버전표시가 띡-하고 뜬다.

그 다음 중요한 점은 buildfile 작성하기.
ant의 빌드파일은 xml로 되어있다.

빌드파일의 예제

<project name="MyProject" default="dist" basedir=".">
    <description>
        simple example build file
    </description>
  <!-- set global properties for this build -->
  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist"  location="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init"
        description="compile the source " >
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile"
        description="generate the distribution" >
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}/lib"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
  </target>

  <target name="clean"
        description="clean up" >
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

http://pcguy7.springnote.com/pages/546569
다음에 올라온 예제를 실행해본 결과,

Buildfile: E:\project\ztest\WebContent\build.xml
prepare:
     [echo] Build Start!! ======> 2009.03.04-10:41
clean:
   [delete] Deleting directory E:\project\ztest\WebContent\dist
compile:
    [mkdir] Created dir: E:\project\ztest\WebContent\build
mkjar:
    [mkdir] Created dir: E:\project\ztest\WebContent\dist
      [jar] Warning: skipping jar archive E:\project\ztest\WebContent\dist\1.0_helloprint.jar because no files were included.
      [jar] Building MANIFEST-only jar: E:\project\ztest\WebContent\dist\1.0_helloprint.jar
dist:
     [copy] Copied 1 empty directory to 1 empty directory under E:\project\ztest\WebContent\dist\lib
     [copy] Copied 1 empty directory to 1 empty directory under E:\project\ztest\WebContent\dist\src
      [zip] Building zip: E:\project\ztest\WebContent\2009.03.04_1.0_helloprint.zip
BUILD SUCCESSFUL
Total time: 203 milliseconds
경고만 빼면...그럭저럭 돌아가는 듯하다.
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:41


7.1 SQL에서의 릴레이션(테이블)과 4장에서 정의한 릴레이션의 차이점은 무엇인가? 용어상의 기타 차이점도 설명하라. 왜 SQL은 테이블이나 질의 결과에 중복 투플들을 허용하는가?
SQL의 테이블(릴레이션)은 모든 애트리뷰트 값이 동일한 투플을 하나 이상 가질 수 있다. 일반적으로 집합은 두 개의 동일한 원소를 허용하지 않기 때문에 SQL테이블은 투플들의 집합이 아니고 투플들의 다중 집합이다.
SQL 질의 결과에서 중복된 투플이 나타나는 이유
- 중복을 없애는 것은 비용(시간)이 많이 드는 연산이다. 한 가지 구현 방법은 먼저 투플들을 정렬하고 중복된 투플들을 제거하는 것이다.
- 사용자가 질의 결과에 중복된 투플들이 나타나는 것을 원하는 경우가 있다.
- 집단 함수가 투플들에 적용될 때 대부분의 경우에 중복 삭제가 필요하지 않다.

7.2 SQL 애트리뷰트에 허용되는 데이터 타입들을 나열하라.
숫자 -  integer, int, smallint,  float, real, double precision
문자열 - char, varchar, clob
비트열 - blob
불리언 - true, false, unknown
날짜,시간 - date, time
타임스탬프 - timestamp

7.3 SQL에서는 4장에서 설명한 엔티티 무결성과 참조 무결성 제약조건을 어떻게 구현하였는가? 참조 트리거된 동작이란 무엇인가?
엔티티 무결성을 나타내는 제약조건은 not null로 한다. 일반적으로 애트리뷰트의 정의에 대한 디폴트값은 null이며 널 값이 허용되지 않을 때는 not null을 명시한다.
키와 참조 무결성을 위한 절로 primary key 절이 있다. primary key 절은 릴레이션의 기본키를 구성하는 하나 이상의 애트리뷰트를 명시한다. 만약 기본키가 하나의 애트리뷰트로 되어 있다면 이 절은 그 애트리뷰트 바로 뒤에 직접 올 수 있다. foreign key절도 참조 무결성을 명시한다. 투플들을 삽입 또는 삭제하거나 외래키 애트리뷰트 값을 수정할 때 참조 무결성 제약조건을 위반할 수 있다. SQL에서 무결성 제약조건을 위반할 때 취하는 디폴트 동작은 위반을 초래한 갱신 연산을 거절하는 것이다. 그러나 외래키 제약조건에 참조 트리거된 동작절을 추가하여 참조 무결성 제약조건이 위반된 경우에 취할 다른 동작을 명시할 수 있다. 참조 트리거된 동작에는 set null, cascade, set default가 있으며 위반된 경우를 가리키는 on delete나 on update 와 함께 사용해야 한다.

7.4 SQL 질의 구문 내의 6개의 절을 설명하고 6개의 절 각각에서 명시할 수 있는 구문 유형은 무엇인지 보여라. 6개의 절 중에서 필수적인 것은 무엇이며 선택적인 것은 무엇인가?
select 애트리뷰트 리스트 : 질의를 통해 값들이 검색되는 애트리뷰트 이름들의 리스트(필)
from 테이블 리스트 : 질의 처리를 위해 필요한 릴레이션들의 리스트(필)
where 조건 : 질의를 통해 검색되는 투플들을 식별하기 위한 조건식(선)
group by 컬럼 조건에 따른 연산(선)
having group에 대한 제한 : 그룹을 새로운 조건으로 분류(선)
order by 정렬 : 하나 이상의 애트리뷰트를 기준으로 질의 결과에 들어 있는 투플들을 정렬(선)

7.5 각 6개의 절을 실행하는 개념적 순서를 명시함으로써 어떻게 SQL 질의가 수행되는가를 개념적으로 설명하라.
from절, where절, group by절, having절 의 순서로 적용함으로써 평가된다. 개념적으로 order by절은 질의 결과를 정렬하기 위해 마지막에 적용된다.

7.6 SQL 내의 비교 연산자에서 널은 어떻게 다루는지 설명하라. SQL 질의에 집계 함수가 적용될 때 널을 어떻게 다루는가? 그룹핑 애트리뷰트에 널이 존재할 때는 어떻게 다루는가?
SQL에서는 참true, 거짓false, 모름unknown의 세 가지 값을 가진 논리를 사용한다. SQL에서는 애트리뷰트를 널과 비교학기 위하여 IS나 IS NOT을 사용한다. 그 이유는 SQL에서 각 널값은 모든 다른 널값과는 다르다고 간주하므로 = 형태의 비교가 적당하지 않다. 집계 함수에서 널인 투플들은 계산에 포함되지 않는다. 일반적으로 널값은 버린다. 그룹핑 애트리뷰트에 널이 존재하면 그 널값을 가진 모든 투플들을 위한 별도의 그룹을 만든다.
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:40


6.1 모델 구문과 관계 모델 구문 간의 대응에 관하여 논하라. 각 ER 모델 구문이 관계 모델로 어떻게 사상되는지를 보이고, 또 다른 사상에 관하여 논하라.

 ER 모델 관계 모델 
 엔티티 타입 엔티티 릴레이션 
 1:1 또는 1:N 관계 타입 외래키(또는 관계 릴레이션) 
 M:N 관계 타입 관계 릴레이션과 두 외래키 
 n차 관계 타입 관계 릴레이션과 n개의 외래키 
 단순 애트리뷰트 애트리뷰트 
 복합 애트리뷰트 단순 요소 애트리뷰트들의 집합 
 다치 애트리뷰트 릴레이션과 외래키 
 값의 집합 도메인 
 키 애트리뷰트 기본키(또는 보조키) 

정규 엔티티 타입의 사상
ER스키마의 각 정규 엔티티 타입 또는 강한 엔티티 타입 E에 대하여 E의 모든 단순 애트리뷰트들을 포함하는 릴레이션 R을 생성, 복합 애트리뷰트의 단순 요소 애트리뷰트들만을 포함시킨다. E의 키 애트리뷰트 하나를 선택하여 R의 기본키로 한다. 만약 E에서 선택된 키가 복합 애트리뷰트이면 그것을 구성하는 모든 단순 애트리뷰트의 모임이 R의 기본키가 된다.

약한 엔티티 타입의 사상
ER스키마에서 소유 엔티티 타입 E를 갖는 각 약한 엔티티 타입 W에 대하여 릴레이션 R을 생성하고 W의 모든 단순 애트리뷰트를 R의 애트리뷰트들로 포함시킨다. 또한 소유 엔티티 타입에 해당되는 릴레이션의 기본키를 R의 외래키로 포함시킨다. 이는 W의 관계 타입을 명시하기 위함이다. R의 기본키는 소유자 릴레이션의 기본키와 약한 엔티티 타입 W의 부분키의 조합이다.

이진 1:1 관계 타입의 사상
ER스키마의 각 이진 1:1 관계 타입 R에 대하여 R에 참여하는 엔티티 타입에 해당하는 릴레이션 S와 R을 나열한다. 가능한 접근 방식은 다음의 세 가지가 있다.
1) 외래키 접근 방식
2) 합병된 관계 접근 방식
3) 교차 참조 또는 관계 릴레이션 접근 방식
첫 번째 접근 방식이 가장 유용하다.

이진 1:N 관계 타입의 사상
모든 정규 이진 1:N 관계 타입 R에 대하여 관계 타입의 N측의 참여 엔티티 타입을 S라고 할 때, 관계 타입 R에 참여하는 다른 릴레이션 T의 기본키를 S의 외래키로 포함시킨다. 이는 관계 타입의 모든 N측 엔티티 인스턴스가 최대한 하나의 1측 엔티티 인스턴스와 관계가 있기 때문이다. 1:N 관계 타입의 모든 단순 애트리뷰트도 S의 애트리뷰트들로 포함시킨다.

이진 M:N 관계 타입의 사상
각 이진 M:N 관계 타입 R에 대하여 R을 표현하기 위한 새로운 릴레이션 S를 생성한다. 참여 엔티티 타입에 해당하는 릴레이션들의 기본키를 S에 외래키 애트리뷰트로 포함시킨다. 그들의 조합이 S의 기본키가 될 것이다. 또한 M:N 관계 타입의 모든 단순 애트리뷰트를 S의 애트리뷰트로 포함시킨다. 주의할 점은 M:N 카디날리티 비율때문에 참여 릴레이션 중에서 한 릴레이션에만 외래키 애트리뷰트를 포함시키는 것으로는 M:N 관계 타입을 표현할 수 없다는 것이다. 이 경우 반드시 별도의 관계 릴레이션S를 생성해야 한다.

다치 애트리뷰트의 사상
각 다치 애트리뷰트 A에 대하여 새로운 릴레이션 R을 생성한다. 이 릴레이션 R은 A에 대응하는 한 애트리뷰트를 포함할 것이다. 또 엔티티 타입이나 A를 애트리뷰트로 갖는 관계 타입에 해당하는 릴레이션의 기본키 애트리뷰트 K를 R의 외래키로 포함시킬 것이다. R의 기본키는 A와 K의 조합이다. 만약 다치 애트리뷰트가 복합 애트리뷰트이면 이 복합 애트리뷰트의 단순 요소 애트리뷰트들을 포함시킨다.

N차 관계 타입의 사상
각각의 n차(n>2) 관계 타입 R에 대하여 R에 대응하는 새로운 릴레이션 S를 생성한다. 모든 참여 엔티티 타입에 대응되는 릴레이션들의 기본키를 S에 외래키 애트리뷰트로 포함시킨다. 또한 n차 관계 타입의 모든 단순 애트리뷰트를 S의 애트리뷰트로 포함시킨다. 일반적으로 S의 기본키는 참여 엔티티 타입에 해당하는 릴레이션들을 참조하는 모든 외래키의 조합이다. 그러나 만약 R에 참여하는 엔티티 타입 E들 중에서 한 엔티티 타입의 카디날리티 제약조건이 1이면 S의 기본키는 E에 해당하는 릴레이션 E'을 참조하는 외래키 애트리뷰트를 포함해서는 안 된다.

6.2 ER모델을 릴레이션으로 사상하기 위한 방법에 관하여 논하라.
1.외래키 접근 방식
한 릴레이션을 선택하여 T의 기본키를 S에 외래키로 포함시킨다. S역할을 하는 릴레이션을 선택함에 있어서 R에 완전히 참여하는 엔티티 타입을 선택하는 것이 좋다. 1:1 관계 타입 R의 모든 단순 애트리뷰트를 S의 애트리뷰트들로 포함시킨다.

2.합병된 릴레이션 접근 방식
1:1 관계 타입의 또 다른 사상으로는 두 엔티티 타입과 관계 타입을 하나의 릴레이션으로 합치는 방법이 있다. 이 방법은 두 엔티티 타입이 모두 완전하게 참여할 때 적절한 방법이다.

3.교차 참조 또는 관계 릴레이션 접근 방식
엔티티 타입을 나타내는 두 릴레이션 S와 T의 기본키를 교차 참조하기 위한 세 번째 릴레이션 R을 정의하는 것이다. 이 방법은 이진 M:N릴레이션에서 주로 사용된다. 릴레이션 R의 각 투플은 S의 한 투플과 T의 한 투플을 연관시키는 관계 인스턴스를 나타내기 때문에 R을 관계 릴레이션이라 부른다.
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:40


5.1 관계 대수의 연산들과 각각의 목적을 나열하라.
셀렉트 - 릴레이션으로부터 선택 조건을 만족하는 모든 투플들을 선택.
프로젝트 - 릴레이션의 애트리뷰트들 중에서 애트리뷰트들로 이루어지는 새로운 릴레이션을 생성하고 중복 투플들을 제거한다.
세타조인 - 릴레이션1과 릴레이션2로부터 조인 조건을 만족하는 투플들의 조합을 생성한다.
동등조인 - 릴레이션1과 릴레이션2로부터 동등(=) 비교로 명시된 조인 조건을 만족하는 투플들의 조합을 생성한다.
자연조인 - 릴레이션2의 조인 애트리뷰트들이 결과 릴레이션에 포함되지 않는다는 점을 제외하면 동등조인과 같다. 조인 애트리뷰트의 이름이 같으면 지정하지 않아도 된다.
합집합 - 릴레이션1 또는 릴레이션2 또는 릴레이션1과 릴레이션2 모두에 포함되는 모든 투플의 릴레이션을 생성한다. 릴레이션1과 릴레이션2는 합집합 호환성을 가져야 한다.
교집합 - 릴레이션1과 릴레이션2 모두에 포함되는 모든 투플의 릴레이션을 생성한다. 릴레이션1과 릴레이션2는 합집합 호환성을 가져야 한다.
차집합 - 릴레이션1에는 포함되나 릴레이션2에는 포함되지 않는 모든 투플의 릴레이션을 생성한다. 릴레이션1과 릴레이션2는 합집합 호환성을 가져야 한다.
카티션프로덕트 - 릴레이션1과 릴레이션2의 애트리뷰트로 이루어진 릴레이션을 생성하고 릴레이션1과 릴레이션2의 투플들의 모든 가능한 조합의 투플들을 포함시킨다.
디비전 - R2(Y)의 모든 투플과의 조합으로 R1에 나타나는 R1(Z)의 모든 t[X] 투플을 포함하는 릴레이션 R(X)를 생성한다. 여기서 Z=X∪Y이다.

5.2 합집합 호환성이 무엇인가? 합집합, 교집합, 차집합 연산이 적용될 릴레이션들이 합집합 호환성을 가져야 하는 이유는 무엇인가?
연산들이 관계데이터베이스에 적용될 때는 위의 세 연산을 적용하고자 하는 두 릴레이션이 같은 타입의 투플들을 가져야 한다. 두 릴레이션의 애트리뷰트 수가 같고 각각의 대응되는 애트리뷰트들 간의 도메인이 같아야 한다. 그렇지 않으면 연산을 할 수가 없다.

5.3 질의를 모호하지 않게 표현하기 위하여 애트리뷰트의 이름 변경이 필요한 질의 유형을 설명하라.
자연 조인의 표준적인 정의는 두 개의 조인 애트리뷰트의 이름이 양쪽 릴레이션에서 같을 것을 요구한다. 그렇지 않은 경우는 먼저 이름이 같도록 해야 한다. 자연 조인이 명시된 두 릴레이션의 애트리뷰트의 이름이 이미 같으면 이름을 바꿀 필요가 없다.

5.4 내부 조인 연산의 여러 가지 유형을 설명하라. 왜 세타 조인이 필요한가?
세타조인 - 일반적인 조인 조건을 가진 조인 연산. 조인 애트리뷰트의 값이 널이거나 조인 조건이 거짓인 투플들은 결과에 나타나지 않는다.
동등조인 - 동등 비교 연산자만 사용한 조인.
자연조인 - 두 개의 조인 애트리뷰트의 이름이 양쪽 릴레이션에서 같을 때 비교하는 조인.

5.5 가장 흔한 형태의 의미 있는 조인 연산을 표현할 때 외래키의 개념은 어떤 역할을 하는가?
참조되는 릴레이션에 대응되는 투플을 찾는 데 중요한 역할을 한다.

5.6 FUNCTION 연산이 무엇인가? 왜 필요한가?
수치 값들의 모임에 적용되는 일반적인 함수로 SUM, AVERAGE, MAXIMUM, MINIMUM 등이 있다.
기본적인 관계 대수로 표현하지 못하는 요구가 있을 때 사용한다.

5.7 외부 조인 연산이 (내부)조인 연산과 어떻게 다른가? 외부 합집합 연산은 합집합 연산과 어떻게 다른가?
다른 릴레이션에 적합한 투플이 존재하든 존재하지 않든 R의 모든 투플 또는 S의 모든 투플 또는 R과 S의 모든 투플들을 조인 결과에 포함시키는 연산이다. 이것은 두 릴레이션에서 대응되는 투플들을 결합하면서 대응되는 값을 갖지 않는 투플들도 결과에 포함시키고 싶은 질의에 사용된다. 대응되는 투플만을 결과에 포함시키는 조인 연산을 내부 조인이라고 부른다.
외부 합집합 연산은 합집합 호환성이 없는 두 릴레이션에 대한 합집합을 수행하기 위해 제안되었다.

5.8 관계 해석과 관계 대수의 차이점과 유사점을 논하라.
관계 대수가 관계 모델을 위한 연산의 집합을 정의하지만 관계 해석은 관계 질의를 나타내기 위한, 보다 상위 레벨의 선언적 표기법을 제공한다. 관계 대수는 검색 요청을 나타내는 연산을 순차적으로 명시하는 절차적 언어이고 관계 해석은 비절차적 언어이다.

5.9 투플 관계 해석과 도메인 관계 해석의 차이점과 유사점을 논하라.
도메인 해석과 투플 해석은 사용되는 변수들의 유형이 다르다. 즉, 도메인 해석에서 변수의 범위는 투플이 아니라 애트리뷰트의 도메인에 속한 값이다.

5.10 존재 정량자(∃)와 전체 정량자(∀)의 의미를 설명하라.
존재 정량자 - 모든 것에 대하여 for every
전체 정량자 - 일부분에 대하여 for some

5.11 투플 해석과 관련된 다음 용어들을 정의하라.
투플 변수 - 데이터베이스 릴레이션을 범위로 하는 값.
범위 릴레이션 - 투플 변수 t에 대한 릴레이션 범위.
원자 - 투플들의 특정한 조합에 대해서 참이나 거짓으로 계산된다.
식(formula) - COND, 투플 관계 해석의 조건.
표현식(expression) - {t1.Ai, t2.Ak, ..., tn.Am | COND(t1, t2, ..., tn, tn+1, ..., tn+m)}

5.12 도메인 해석과 관련된 다음 용어들을 정의하라.
도메인 변수 - 어떤 질의의 결과로 차수 n인 릴레이션을 생성하기 위해서 각 애트리뷰트마다 하나씩, 총 n개의 변수가 필요하다.
범위 릴레이션 - 애트리뷰트의 도메인에 속한 값.
원자 - 투플 해석과 마찬가지로 값들의 특정 집합에 대해서 참이거나 거짓으로 계산된다.
식 - COND, 도메인 관계 해석의 조건.
연산식 - {x1, x2, ..., xn | COND(x1, x2, ..., xn, xn+1, ..., xn+m)}

5.13 관계 해석에서 안전식의 의미는 무엇인가?
유한 개의 투플을 결과로 생성하는 것이 보장된 식.

5.14 질의어가 관계적으로 완전하다는 의미는 무엇인가?
어떤 관게 질의어 L이 있을 때 관계 해석으로 표현이 가능한 어떤 질의어 L로 표현이 가능하면 L을 관계적으로 완전한 언어라고 한다.
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:39


4.1 다음 용어들을 정리하여라.
도메인 - 더 이상 나누어질 수 없는 값들의 집합. 이름, 데이터 타입, 포맷을 가진다.
애트리뷰트 - 열의 제목
n-투플 - n 개의 값의 순서 리스트.
릴레이션 스키마 - 릴레이션 이름과 애트리뷰트로 구성, 릴레이션을 표현하기 위해 사용된다.
릴레이션 상태 - n-투플의 집합.
릴레이션의 차수 - 릴레이션 스키마의 애트리뷰트 수.
관계 데이터베이스 스키마 - 릴레이션 스키마의 집합과 무결성 제약조건들의 교집합이다.
관계 데이터베이스 상태 - 무결성 제약조건을 만족하는 릴레이션 상태들의 집합.

4.2 릴레이션의 투플들에 순서가 없는 이유는 무엇인가?
릴레이션은 투플들의 집합으로 정의된다. 수학적으로 집합의 원소들 사이에는 순서가 없다. 따라서 릴레이션에서도 투플들은 특정 순서를 갖지 않는다.

4.3 릴레이션에 중복 투플들이 허용되지 않는 이유는 무엇인가?
집합의 모든 원소는 중복되지 않으므로 이 정의에 의하면 릴레이션의 모든 투플도 중복되지 않아야 한다.

4.4 키와 슈퍼키의 차이점은 무엇인가?
슈퍼키는 같은 값을 가지는 서로 다른 투플이 존재하지 않는다는 유일성 제약 조건을 명시한다. 그러므로 모든 릴레이션은 적어도 하나의 슈퍼키를 갖는다. 그러나 슈퍼키는 중복되는 애트리뷰트들을 가질 수 있으므로 이런 중복성을 갖지 않는 개념이 필요한데 그것이 키이다. 키와 슈퍼키에 적용되는 조건은 서로 다른 두 투플은 동일한 키 애트리뷰트 값을 가질 수 없다는 것이다. 키는 최소의 슈퍼키이다. 그리고 일반적으로 단일 애트리뷰트의 슈퍼키는 키이다.

4.5 릴레이션의 후보키들 중의 하나를 기본키로 지정하는 이유는 무엇인가?
중복의 애트리뷰트 값을 가지는 것을 일차적으로 배제할 수 있기 때문에 후보키들 내에서 선택한다.

4.6 릴레이션이 보통의 테이블이나 파일과 다른 특성을 설명하라.
1.릴레이션은 투플들의 순서에 영향을 받지 않는다. 투플들에는 순서가 없다.
2. 릴레이션 스키마내의 애트리뷰트들의 순서와 그에 따른 투플 내의 값들의 순서는 같다.

4.7 릴레이션에 널값이 생기는 여러 가지 이유를 설명하라.
값이 정의되지 않은 경우
값을 알 수 없는 경우
값이 현재 가능하지 않은 경우

4.8 엔티티 무결성과 참조 무결성 제약조건을 설명하고, 그것들이 중요한 이유를 기술하라.
엔티티 무결성 - 어떠한 기본키 값도 널 값이 될 수 없다. 기본키 값은 한 릴레이션 내의 각 투플을 식별하는 데 사용하는데 기본키 값이 널값이면 투플들을 식별할 수 없기 때문이다.
참조 무결성 - 두 릴레이션 사이에 명시되는 제약조건으로 한 릴레이션에 있는 투플이 다른 릴레이션에 있는 투플을 참조하려면 반드시 참조되는 투플이 그 릴레이션 내에 존재해야 한다. 한 릴레이션의 외래키의 값이 참조하는 릴레이션의 기본키 값과 일치해야 한다는 것을 의미한다. 이렇게 함으로써 두 개체들 간의 관계를 나타내는 것이다.

4.9 외래키를 정의하라. 왜 이 개념이 필요한가? 이것이 조인 연산에서 어떤 역할을 하는가?
참조 무결성 제약조건이 만족된 두 릴레이션 스키마에서 다음과 같은 조건을 만족하면 외래키라고 한다.
1. 외래키의 애트리뷰트는 참조하는 릴레이션의 기본키의 애트리뷰트와 동일한 도메인을 가진다.(이때 '외래키는 그 릴레이션을 참조한다'고 한다.)
2. 한 릴레이션의 투플의 외래키 값은 참조하는 릴레이션의 투플의 기본키 값과 일치하거나 널값을 가져야 한다.
 
4.10 트랜잭션이란 무엇인가? 갱신과 무엇이 다른가?
데이터베이스에 존재하는 값들에 대한 읽기 연산. 추가, 삭제, 갱신 연산. 데이터베이스에 대해 모든 제약조건들을 만족하는 일관된 상태로 수행을 끝마쳐야 한다. 하나의 트랜젝션은 데이터베이스로부터 값을 읽는 검색 연산들과 갱신 연산들을 여러 개 포함할 수 있다.
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:39


3.1 데이터베이스 설계 과정에서 고수준 데이터 모델의 역할을 설명하라.
데이터베이스에 대한 개념 스키마를 만든다. 개념적 설계라고 부르는데 개념 스키마는 사용자들의 데이터 요구사항들을 간단히 기술한 것으로서 데이터 타입, 관계, 제약조건들을 자세하게 설명한 것이다. 이것들은 고수준의 데이터 모델이 제공하는 개념들을 사용하여 표현된다.

3.2 널값을 사용하는 것이 적합한 경우들을 나열하라.
한 애트리뷰트에 적용할 값이 없을 때.
한 엔티티의 특정 애트리뷰트 값을 모를 때.
- 애트리뷰트 값이 존재하지만 누락되었을 때.
- 애트리뷰트 값이 존재하는지의 여부를 알지 못할 때.

3.3 다음의 용어들을 정의하라.
엔티티 - ER 모델을 나타내는 기본 객체. 실세계에서 독립적으로 존재하는 실체.
애트리뷰트 - 엔티티를 기술하는 속성.
애트리뷰트 값 - 특정 엔티티를 설명.
관계 인스턴스 - 엔티티들의 연관.
복합 애트리뷰트 - 속성을 작은 구성요소로 나누어 계층을 형성한다. 복합 애트리뷰트의 값은 계층을 구성하는 단순 애트리뷰트들의 값을 연결한 것이다.
다치 애트리뷰트 - 한 엔티티에서 애트리뷰트가 여러 값을 가지는 경우, 이런 애트리뷰트를 다치 애트리뷰트라 한다. 다치 애트리뷰트는 각 엔티티가 가질 수 있는 값의 개수를 제한하기 위해 하한과 상한의 범위를 가질 수 있다.
유도된 애트리뷰트 - 두 개 이상의 애트리뷰트 값들이 서로 연관을 가지고 있는 경우, 관련 엔티티로부터 애트리뷰트의 값이 유도될 수 있다.
복잡한 애트리뷰트 - 복합 애트리뷰트와 다치 애트리뷰트가 임의의 방식으로 중첩되어 그것을 표현할 때 이를 복잡한 애트리뷰트라고 한다.
키 애트리뷰트 - 엔티티 집합 내에서 각 엔티티마다 서로 다른 값을 가지는 하나의 애트리뷰트.
값 집합(도메인) - 각 엔티티에서 해당 애트리뷰트가 가질 수 있는 값들의 집합.

3.4 엔티티 타입과 엔티티 집합이 무엇인가? 엔티티, 엔티티 타입, 엔티티 집합의 서로 다른 점을 설명하라.
엔티티 - 실세계에서 독립적으로 존재하는 실체, 개념적으로 존재하는 객체.
엔티티 타입 - 같은 애트리뷰트를 갖는 엔티티들의 집합, 이름과 애트리뷰트들의 리스트로 기술된다.
엔티티 집합 - 임의의 시점에 데이터베이스 내의 특정 엔티티 타입과 모든 엔티티의 모임, 엔티티 집합은 엔티티 타입과 같은 이름을 사용하여 부른다.

3.5 애트리뷰트와 값 집합의 차이점을 설명하라.
애트리뷰트는 각 엔티티가 갖는 속성을 말한다.
값 집합은 각 엔티티에서 해당 애트리뷰트가 가질 수 있는 값들의 집합을 말한다.

3.6 관계 타입이 무엇인가? 관계 인스턴스, 관계 타입, 관계 집합의 차이점을 설명하라.
엔티티 타입들에 속하는 엔티티 간의 연관들의 집합을 정의, 수학적으로 관계 타입은 관계 인스턴스들의 집합이다.
관계 타입은 각각의 엔티티를 연결하는 속성을 의미한다. 즉, 서로의 관계가 어떠한가에 대한 기술이다. 예를 들어 교수, 학생, 강의 라는 엔티티들이 있다. 교수 - 강의의 관계 타입은 강의를 한다는 타입이며 학생 - 강의는 강의를 듣는다는 타입을 갖게 되는 것이다. 관계 인스턴스는 관계가 있는 두 엔티티의 요소들을 연관시키는 역할을 하는데 학생 {A, B, C, D} 와 강의 {1, 2, 3} 을 A - r1 - 1(학생 A는 1번 강의를 듣는다.), B - r2 - 2(학생 B는 2번 강의를 듣는다.), ...식으로 표현할 수 있다. 관계 집합은 이러한 관계 인스턴스의 집합을 말한다.

3.7. 참여 역할이 무엇인가? 관계 타입을 기술하는데 언제 역할 이름이 필요한가?
관계 타입에 참여하는 각 엔티티 타입은 관계 내에서 특정 한 역할을 담당한다. 역할 이름은 엔티티 타입에 속한 한 엔티티가 각 관계 인스턴스에서 가지는 역할을 강조하고 관계가 무엇을 의미하는지 설명하는 데 도움이 된다. 같은 엔티티 타입이 어떤 관계 타입에 두 번 이상 참여하는 경우에는 각 참여의 의미를 구분하기 위해 역할 이름이 필수적이다.(이러한 관계 타입을 순환적 관계라고 한다.)

3.8 관계 타입에 대한 구조적 제약조건을 명시하는 두 가지 방법을 설명하라. 또한 각각의 장단점을 논의하라.
카디날리티 비율 - 엔티티가 참여할 수 있는 최대 관계 인스턴스들의 수를 명시한다.
참여 제약조건 -  한 엔티티의 존재가 관계 타입을 통해 연관되어 있는 다른 엔티티에 의존하는지의 여부를 명시한다. 이 제약 조건은 각 엔티티가 참여할 수 있는 관계 인스턴스의 최소 수를 명시하며 최소 카디널리티 제약조건이라고도 한다.

3.9 어떤 조건하에서, 이진 관계 타입의 애트리뷰트가 참여하는 엔티티 타입들 중 한 엔티티 타입의 애트리뷰트로 옮겨질 수 있는지 설명하라.
1:1 관계 타입의 애트리뷰트들은 참여하고 있는 엔티티 타입들 중의 하나로 이동될 수 있다.

3.10 관계를 애트리뷰트들로 표현하는 경우에 이런 애트리뷰트의 값 집합은 무엇인가? 어떤 데이터 모델이 이런 개념을 사용하는가?
애트리뷰트에 대한 값 집합은 모든 엔티티들의 집합이다. 이는 고수준의 개념적 데이터 모델에서 사용한다.

3.11 순환적 관계 타입이 무엇인가? 순환적 관계 타입의 예를 몇 개 보여라.
같은 엔티티 타입이 어떤 관계 타입에 두번 이상 참여하는 경우 그 관계 타입을 순환적 관계 타입이라고 한다. 예를 들어 사원 엔티티에서 그 원소들은 사원과 상사의 역할을 가지고 있다. 이럴 때 관계는 [사원 엔티티] - [상사관계] - [사원 엔티티] 로 나타낼 수 있다.

3.12 데이터 모델링에서 약한 엔티티 개념이 필요한 경우는? 또한 다음의 용어들을 설명하라.
한 엔티티 타입이 다른 엔티티 타입과 연관되어 있을 때 이 개념이 필요하다.
소유 엔티티 타입 - 약한 엔티티 타입의 어떤 속성으로 연계된 다른 엔티티 타입.
약한 엔티티 타입 - 자신의 키 애트리뷰트가 없는 엔티티 타입.
식별 관계 타입 - 약한 엔티티 타입과 강한 엔티티 타입을 연관시키는 타입.
부분키 - 동일한 소유엔티티에 연관되는 약한 엔티티들을 서로 구분할 수 있는 애트리뷰트들의 집합.

3.13 약한 엔티티 타입의 식별 관계가 삼진 이상일 수 있는지 설명하고, 있다면 그 예들을 보여라.
삼진 식별 관계 타입을 갖는 약한 엔티티 타입도 가능한다. 이 경우, 약한 엔티티 타입은 몇 개의 소유 엔티티 타입들을 가질 수 있다.

3.14 ER 스키마를 ER 다이어그램으로 도식화하기 위해 사용하는 표기법을 설명하라.
엔티티 타입은 사각 상자로 표기한다. 관계 타입들은 다이아몬드 상자로 표기하며 이 관계에 참여하는 엔티티 타입들과는 직선으로 연결한다. 애트리뷰트들은 타원으로 표기하며 각 애트리뷰트는 해당되는 엔티티 타입 또는 관계 타입에 직선으로 연결한다. 복합 애트리뷰트의 구성 요소 애트리뷰트들은 타원형의 복합 애트리뷰트에 연결한다. 다치 애트리뷰트는 이중 타원으로 나타낸다. 키 애트리뷰트는 애트리뷰트 이름에 밑줄을 그어 표현한다. 유도된 애트리뷰트들은 점선으로 된 타원으로 표기한다. 약한 엔티티 타입은 이중 상자로 엔티티 타입을 표시하고 식별 관계를 이중 다이아몬드로 표기한다. 약한 엔티티 타입의 부분키는 점선으로 밑줄을 그어 표기한다. 이진 관계 타입의 카디날리티 비율은 참여를 표시하는 선에 1, M 또는 N을 명시함으로써 표현한다. 참여 제약조건은 부분 참여에 대해서는 단일선으로, 전체 참여에 대해서는 이중선으로 나타낸다.

3.15 ER 스키마 다이어그램에서의 이름 지정 규칙을 설명하라.
엔티티 타입의 이름은 그 엔티티 타입에 속하는 각 엔티티에 적용되기 때문에 복수 이름보다는 단수 이름을 선택한다. ER 다이어그램에서는 엔티티 타입과 관계  타입의 이름은 대문자로, 애트리뷰트의 이름은 첫 글자만 대문자로, 역할 이름은 소문자로 표기한다. ER다이어그램을 왼쪽에서 오른쪽, 위에서 아래로 읽기 쉽게 관계 이름을 선택한다.
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:38


2.1 다음 용어들을 정의하라.
데이터 모델 - 데이터베이스의 구조를 명시하기 위해 사용할 수 있는 개념들의 집합으로서 이와 같은 추상화를 달성하기 위해 필요한 수단을 제공.
데이터베이스 스키마 - 데이터베이스의 기술.
데이터베이스 상태 - 어떤 특정 시점에 데이터베이스에 들어 있는 데이터.
내부 스키마 - 데이터베이스의 물리적 저장구조, 물리적 데이터 모델을 사용하여 데이터 저장구조의 세부사항과 데이터베이스에 대한 접근경로들을 기술.
개념 스키마 - 모든 사용자들을 위한 전체 데이터베이스의 구조를 기술. 물리적 저장구조의 세부 사항을 은폐시키고 엔티티, 데이터타입, 관계, 사용자 연산, 제약조건들을 나타내는 데 중점.
외부 스키마 - 특정 사용자 그룹이 관심들 갖는 데이터베이스의 부분을 기술하고 그 사용자 그룹에게 데이터베이스의 나머지 부분을 은폐.
데이터 독립성 - 고수준의 스키마를 변경할 필요없이 데이터베이스 시스템의 어떤 단계에서 스키마를 변경할 수 있는 능력.
데이터 정의어 - 데이터베이스에서 데이터와 데이터간의 관계를 정의하여 데이터베이스 구조를 설정하는 SQL문.
데이터 조작어 - 데이터베이스 내의 데이터를 검색, 수정, 삭제, 저장할 수 있는 SQL문.
저장구조 정의어 - 내부 스키마를 지정하는데 사용된다.
뷰 정의어 - 사용자 뷰를 명시하고 개념 스키마 사이의 사상을 나타낸다.
질의어 - 고수준 데이터 조작어가 그 자체로 대화식으로 사용될 때.
호스트 언어 - 고수준이든 저수준이든 범용 프로그래밍 언어 내에 데이터 조작어 명령이 삽입된 경우의 프로그래밍 언어.
데이터 부속어 - 범용 프로그래밍 언어 내에 데이터 조작어 명령이 삽입된 경우의 데이터 조작어.
데이터베이스 유틸리티 -  데이터베이스 관리자가 데이터베이스 시스템을 관리하는 것을 도와준다.
카탈로그 - DBMS 모듈들이 필요로 하는 파일의 이름과 크기, 데이터 항목의 이름과 데이터 타입, 각 파일의 자세한 저장 형태, 스키마 사이의 사상 정보, 제약조건들에 대한 정보 등을 포함한다.
클라이언트/서버 아키텍처 - 많은 수의 PC, 워크스테이션, 파일 서버, 프린터, 데이터베이스 서버, 웹 서버, 기타 구성 요소들이 네트워크를 통해서 서로 연결되어 있는 컴퓨팅 환경을 다루기 위해 개발. 각각의 서비스를 제공하는 서버들이 네트워크로 연결되어 이와 연결된 클라이언트 컴퓨터에 그 서비스를 제공한다.
3-층 아키텍처 - 클라이언트와 데이터베이스 서버 사이에 중간 단계-응용서버 혹은 웹서버-를 하나 더 추가한 것.
n-층 아키텍처 - 사용자와 저장된 데이터 사이를 좀 더 세밀하게 나누어 층을 추가한 것.

2.2 데이터 모델들을 분류하라.
물리적 데이터 모델(저수준)
개념적 데이터 모델(고수준)
표현 데이터 모델(구현)

2.3 데이터베이스 스키마와 데이터베이스 상태의 차이점은 무엇인가?
데이터베이스 스키마는 데이터베이스의 기술을 말하는데 데이터베이스 설계 과정에서 명시하며 자주 변경되지 않는다. 데이터베이스 설계시 각각의 사용자 집단들의 요구사항들을 도출하면서 변경된다.
데이터베이스는 실제로 변경이 자주 일어난다. 데이터의 변경이 일어나면 데이터베이스의 내용도 변경된다. 이 때 특정 시점에 데이터베이스에 들어 있는 데이터를 데이터베이스 상태(스냅샷)라고 한다. 

2.4 3단계-스키마 아키텍처를 설명하라. 왜 스키마 단계들 사이에 사상이 필요한가? 어떻게 상이한 스키마 정의어들이 이 아키텍처를 지원하는가?
사용자 응용들과 물리적 데이터베이스를 분리시키는 것을 목적으로 하며 내부 스키마, 개념 스키마, 외부 스키마 이렇게 세 단계로 정의된다. 3단계-스키마 아키텍처는 사용자가 데이터베이스 시스템 내에서 스키마 단계들을 시각화하는 데 편리한 수단으로 사용되나 스키마는 단지 데이터데 대한 기술임을 주의해야 한다.
3단계-스키마 아키텍처에 기반을 둔 DBMS는 각 사용자 그룹은 단지 각자의 외부 스키마만을 참조한다. 따라서 DBMS는 외부 스키마상에서 표현된 요구를 개념 스키마에 대한 요구로 변환시키고 다시 내부 스키마에 대한 요구로 변환 시켜서 저장된 데이터베이스를 접근한다.
이 때 단계들 간의 요구와 접근 결과를 변환하는 과정을 사상이라고 한다.

2.5 논리적 데이터 독립성과 물리적 데이터 독립성의 차이점은 무엇인가? 어느 독립성을 달성하는 것이 더 어려운가? 그 이유는 무엇인가?
논리적 데이터 독립성 - 외부 스키마나 응용 프로그램들을 변경하지 않으면서 개념 스키마를 변경하는 능력. 데이터베이스의 확장, 제약조건의 갱신, 데이터베이스의 축소 등. 변경시 남아있는 데이터만 참조하는 외부 스키마들이 영향을 받아서는 안 된다. 외부/개념 스키마간의 사상에 의해 제공된다.
물리적 데이터 독립성 - 개념 스키마를 변경하지 않으면서 내부 스키마를 변경할 수 있음을 말한다. 따라서 외부 스키마도 변경할 필요가 없다. 개념/내부 스키마간의 사상에 의해 제공된다.(데이터의 물리적 저장방법과 그 구성 변경의 투명성을 제공)
논리적 데이터 독립성이 달성하기 더 어려운데 왜냐하면 데이터의 물리적 저장방법이 변경되었을 경우 데이터 표현방식의 변화로 프로그램을 수정하면 되지만 프로그래머가 생각하는 논리적 구조가 변경되면 그에 따른 프로그램의 구조가 변경되기 때문에 전체적인 수정을 필요로 하기 때문이다.

2.6 절차적 데이터 조작어와 비절차적 데이터 조작어의 차이점은 무엇인가?
절차적 데이터 조작어 - 저수준 데이터 조작어, 반드시 범용 프로그래밍 언어 내에 삽입해서 사용한다. 이 유형은 데이터베이스로부터 각 레코드 또는 객체 단위로 검색하여 처리하기 때문에 프로그래밍 언어의 반복문 등을 이용한다. 한 번에 한 레코드 데이터 조작어라고도 부른다.
비절차적 데이터 조작어 - 고수준 데이터 조작어, 복잡한 데이터베이스 연산들을 간결하게 나타내는 데 사용한다. 한 데이터 조작어 명령으로 여러 개의 레코드들을 검색할 수 있기 때문에 한 번에 레코드 집합 조작어 또는 집합지향 데이터 조작어라고 부른다.

2.7 여러 가지 편리한 사용자 인터페이스 유형들과 각 유형을 주로 사용하는 사용자의 부류에 대해서 설명하라.
브라우징을 위한 메뉴 기반 인터페이스
폼 기반 인터페이스
그래식 사용자 인터페이스
자연어 인터페이스
음성 입력과 출력
초보자를 위한 인터페이스
데이터베이스 관리자를 위한 인터페이스

2.8 DBMS는 컴퓨터 시스템 소프트웨어들과 상호 작용하는가?
DBMS는 컴파일러와 인터페이스하면서 범용 호스트 프로그래밍 언어를 지원하고 시스템 네트워크 인터페이스를 통하여 별도의 컴퓨터에서 수행되는 클라이언트 및 응용 서버와 상호 작용한다.

2.9 2-층과 3-층 클라이언트/서버 아키텍처의 차이점이 무엇인가?
2-tier 아키텍처는 소프트웨어의 구성 요소들이 클라이언트와 서버에 분산되어 있다. 사용자 인터페이스 프로그램과 응용 프로그램들은 클라이언트 쪽에서 수행되며 SQL처리와 관련된 질의와 트랜잭션 기능은 서버(데이터 서버) 측에서 수행한다.
3-tier 아키텍처는 웹의 등장으로 개발되었는데 클라이언트와 데이터베이스 서버 사이에 미들 티어를 하나 더 추가한 것이다. 클라이언트는 정보를 사용자에게 보여주고 데이터를 입력받으며 미들 티어(웹서버 또는 응용서버)에서는 데이터를 사용자에 전달하거나 DBMS에게 보내기 전에 중간의 규칙과 제약조건들을 다룬다. 데이터베이스 서버에서는 데이터 관리의 모든 서비스를 수행한다.

2.10 데이터베이스 유틸리티의 유형과 기능들에 대해서 설명하라.
적재 - 텍스트 파일이나 순차 파일과 같은 기존의 데이터 파일들을 데이터베이스에 적재하기 위해 사용하는 유틸리티.
백업 - 전체 데이터베이스를 테이프에 복사해서 데이터베이스의 백업 사본을 만든다.
파일 재조직 - 성능을 향상시키기 위하여 데이터베이스 파일들의 구조를 다른 파일 구조로 재조직하는 유틸리티.
성능 모니터링 - 데이터베이스의 사용을 모니터링해서 사용 통계를 데이터베이스 관리자에게 제공.

2.11 어떤 기능이 n-층 아키텍처에 추가되었는가(n>3)?
n-층 아키텍처에서 비즈니스 논리 층은 다수의 층으로 나누어지는데 네트워크를 통해서 프로그램과 데이터를 분산시키는 것 외에 한 개의 층이 적절한 프로세서나 운영체제에서 동작할 수 있다는 장점이 있다. ERP나 CRM 패키지 업체들은 주로 미들웨어 층을 사용한다. 미들웨어 층은 뒷단의 데이터베이스들과 통진하는 앞단의 모듈을 맡는다.

*커드의 12규칙
http://ko.wikipedia.org/wiki/%EC%BB%A4%EB%93%9C%EC%9D%98_12_%EA%B7%9C%EC%B9%99
posted by 나는너의힘
:
DATABASE 2009. 5. 6. 11:38


1.1 다음 용어들을 정의하라.
데이터 - 알려진 사실, 의미를 가지고 기록될 수 있는 것들.
데이터베이스 - 어떤 특정한 의미를 가지는 데이터의 모임.
DBMS - 데이터베이스 관리 시스템, 다양한 응용들에서 필요로 하는 데이터베이스를 정의, 생성, 조작, 공유할 수 있도록 편리한 기능을 제공하는 범용 소프트웨어 시스템.
데이터베이스 시스템 - 데이터베이스와 DBMS.
데이터베이스 카탈로그 - 데이터베이스의 정의(데이터베이스에 속하는 각 파일들의 구조, 각 데이터 항목의 타입과 저장 형식, 데이터에 대한 다양한 제약조건 등)가 저장된 것.
프로그램-데이터 독립성 - 데이터 파일의 구조가 변경되어도 응용 프로그램은 거의 변하지 않는 성질.
사용자 뷰 - 데이터베이스의 일부이거나 데이터베이스로부터 유도되는 가상 데이터, 뷰의 데이터는 실제로 데이터베이스에 저장되지 않는다.
데이터베이스 관리자 - DBA, 데이터베이스나 DBMS, 관련 소프트웨어를 관리하고 감독. 데이터베이스에 대한 접근을 감독하며 자원의 사용을 모니터링하고 조정한다. 필요한 경우에 소프트웨어나 하드웨어 자원을 구입, 데이터베이스의 보안이나 시스템의 성능 문제를 책임진다.
최종 사용자 - 데이터베이스에 대하여 질의하고, 변경하고, 보고서를 작성하는 사람. 캐주얼 사용자, 초보 사용자, 전문 사용자, 독자적인 사용자로 분류.
미리 작성된 트랜잭션 - 초보 사용자가 데이터베이스에 제한적으로 접근하게 하기 위해 사용.
연역 데이터베이스 시스템 - 데이터베이스에 저장되어 있는 사실로부터 새로운 정보를 추론하는 연역적 규칙을 정의할 수 있는 기능을 가진 시스템.
지속성 객체 - 데이터베이스에 저장된 객체, 프로그램의 수행이 끝난 후에도 데이터베이스에 영구적으로 남아 필요하면 언제든지 다른 프로그램들에 접근이 가능.
메타데이터 - 카탈로그에 저장된 정보, 기본 데이터베이스의 구조를 기술.
트랜잭션 처리 응용 - 동시에 수행되는 트랜잭션들이 상호 방해를 받지 않고 효율적으로 수행되도록 보장.

1.2 데이터베이스를 사용하는 데 수반되는 중요한 세 가지 작업은 무엇인가? 각각을 간단하게 설명하라.
데이터베이스 정의 - 데이터베이스에 저장되는 데이터에 대한 데이터 타입, 구조, 제약조건들을 명세하는 과정.
데이터베이스 구축 - DBMS가 관리하는 기억 장치에 데이터를 저장하는 과정.
데이터베이스 조작 - 특정한 데이터를 검색하기 위한 질의, 데이터베이스의 갱신, 데이터로부터 리포트를 생성하는 기능.

1.3 데이터베이스의 방식의 중요한 특징을 설명하고, 기존의 파일처리 시스템을 사용하는 경우에 비하여 다른 점을 논의하라.
파일처리 방식에서는 소프트웨어 응용을 프로그래밍하는 작업의 일환으로 사용자가 특정한 소프트웨어 응용을 위하여 필요한 파일들을 별도로 정의하고 구현한다. 각각의 응용 프로그램들은 자유롭게 데이터 항목들을 독립적으로 명명할 수 있다.
데이터베이스 방식에서는, 데이터는 한 번만 저장되며 여러 사용자가 공유하게 된다. 데이터의 이름은 한 번만 정의되고, 정의와 트랜잭션 및 응용프로그램에서 반복해서 사용된다. 중요한 특징은 다음과 같다.
- 데이터베이스 시스템의 자기 기술성
- 프로그램과 데이터의 격리 및 데이터 추상화
- 데이터에 대한 다중 뷰의 제공
- 데이터의 공유와 다수 사용자 트랜잭션 처리

1.4 데이터베이스 관리자와 데이터베이스 설계자의 역할을 무엇인가?
데이터베이스 관리자는 데이터베이스나 DBMS, 관련 소프트웨어를 관리하고 감독한다. 즉, 데이터베이스에 대한 접근을 감독하며 자원의 사용을 모니터링하고 조정한다. 데이터베이스의 보안이나 시스템의 성능 문제를 책임지며 소프트웨어나 하드웨어 자원을 구입한다.
데이터베이스 설계자는 데이터베이스에 저장될 데이터를 선정하고 데이터를 나타내고 저장하는 구조를 정의하는 역할을 담당한다. 사용자 그룹들과 만나서 요구사항들을 도출하고 그것을 만족하는 데이터베이스 뷰를 개발한다.

1.5 데이터베이스의 최종 사용자들을 분류하고 각자의 주요 업무를 논하라.
캐주얼 사용자 - 데이터베이스에 가끔 접근하지만 매전 다른 정보를 찾는다. 정교한 데이터베이스 질의어를 사용하여 데이터를 요구한다. 중상급의 관리자.
초보 사용자 - 미리 잘 프로그램되고 테스트된 기작성 트랜잭션들을 사용하여 데이터베이스를 검색하고 변경하는 사용자.
전문 사용자 - 복잡한 요구사항을 가진 엔지니어, 과학자, 비즈니스 분석가 등.
독자적인 사용자 - 메뉴나 그래픽 사용자 인터페이스를 제공하는, 편리한 패키지를 사용하여 개인 데이터베이스를 유지하는 사용자.

1.6 DBMS가 제공해야 할 기능들을 설명하라.
중복성의 제어
권한이 없는 접근의 통제
프로그램 객체를 위한 지속성 기억 공간 제공
효율적인 질의처리를 위한 저장 구조 제공
백업과 회복 제공
다수의 사용자 인터페이스 제공
데이터 간의 복잡한 관계의 표현
무결성 제약조건의 시행
규칙을 사용한 추론과 수행
표준 강화
응용 개발 시간의 단축
융통성
최신 정보의 가용성
규모의 경제성

1.7 데이터베이스 시스템과 정보 검색 시스템 사이의 차이점을 논하라.
정보 검색 시스템 - 데이터베이스 시스템을 사용하는 한 분야. 키워드를 사용하여 데이터를 색인하고 카탈로그화 한다. 이러한 키워드에 기반하여 문서들을 찾는 것을 다루며 문서처리와 자유로운 비정형 텍스트 처리를 다룬다.
데이터베이스 시스템- 사용자의 질의를 처리, 수행하는 과정과 데이터베이스의 저장, 조작 등에 관한 모든 처리를 다룬다.
posted by 나는너의힘
:
DATABASE/MYSQL 2009. 5. 6. 11:35


10.4.3. The BLOB and TEXT Types

BLOB은 가변형 데이터를 저장하는 바이너리 대용량 객체이다. BLOB은 TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB이 있다. 이것은 저장 용량의 최대 길이에 따른 분류이다. TEXT는 TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT가 있다. TEXT 타입은 BLOB 타입과 일치하며 최대 길이와 용량도 같다.
 
BLOB 컬럼은 바이너리 스트링값(바이트형)을 가지며 TEXT 컬럼은 넌바이너리 스트링값(캐릭터형)을 가진다. BLOB 컬럼은 캐릭터셋이 없으며 컬럼값에서 바이트형의 숫자값으로 비교하고 정렬된다. TEXT 컬럼은 캐릭터셋을 가지며 캐릭터셋의 collation 에 따라 비교하여 정렬된 값을 갖는다.

strict SQL mode가 enable이 아니면 컬럼의 최대 길이를 초과하는 값을 BLOB이나 TEXT 컬럼에 대입할 것이고 그 값은 길이에 맞게 버림을 할 것이며 경고가 발생하게 된다. 공백이 없는 캐릭터를 자르면 (경고보다는)에러가 발생하게 되며 strict SQL mode를 사용하여 값의 삽입을 막을 수 있다.

MySQL 5.1.24의 시작에서, SQL mode와 상관없이, TEXT 컬럼에 삽입된 값에서 생성된 공백의, 초과를 자르면 항상 경고가 발생한다.

TEXT 컬럼이 인덱스되어있으면 인덱스 엔트리의 비교로 공백을 채운다. 즉, 인덱스에 유니크 값을 넣어야 하는데 동일한 키를 넣게 되면 앞서 넣은 값과는 다른 값을 넣으라고 에러가 발생한다. 예를 들자면, 테이블에 'a'를 넣고 다시 'a'를 저장하려고 하면 동일한 키로 인해 에러가 발생한다. 그러나 BOLB 컬럼에서는 그렇지 않다.

많은 값을 넣는데 대부분 BLOB 컬럼을 VARBINARY 컬럼으로 생각하기도 한다. 이와 유사하게 TEXT 컬럼을 VARCHAR 컬럼이라고 생각한다. 그러나 BLOB과 TEXT는 VARBINARY, VARCHAR와 여러 면에서 다르다.

- BLOB과 TEXT에서 인덱스의 prefix길이를 설정해야 하지만 CHAR와 VARCHAR에서는 선택이다.

- BLOB과 TEXT은 디폴트 값을 가질 수 없다.

LONG과 LONG VARCHAR는 MEDIUMTEXT 데이터 타입과 대응한다. 이것은 호환성을 말하는데, TEXT 데이터 타입의 BINARY 속성을 사용하면 컬럼은 캐릭터셋 컬럼의 binary collation으로 지정된다.

MySQL Connector/ODBC 는 BLOB 값을 LONGVARBINARY로 TEXT 값을 LONGVARCHAR로 정의한다.

BLOB과 TEXT 값은 매우 길기 때문에 두 타입을 사용할 때는 다음과 같은 제약사항이 존재한다.

- 정렬할 때는 컬럼의 최초 max_sort_length 바이트를 사용하며 디폴트 값은 1024바이트이다. 이 값은 MySQL서버를 시작할 때 설정하는 max_sort_length=N 옵션에 따라 다르다. 런타임시 max_sort_length 값의 증가를 그룹화하거나 정렬함으로서 더 큰 바이트를 나타낼 수 있다. 클라이언트는 각 세션의 max_sort_length 변수를 변경할 수 있다.

mysql> SET max_sort_length = 2000;mysql> SELECT id, comment FROM t -> ORDER BY comment;

max_sort_length 바이트 이상의 값을 나타내는데 GROUP BY나 ORDER BY를 사용하면 길이가 긴 값을 BLOB이나

TEXT 컬럼에 넣으면 컬럼 값을 고정된 길이의 객체로 변환할 수 있다. 이때 일반적으로 SUBSTRING() 함수를 사용한다. 그 예로, 다음 statement는 comment 컬럼의 2000바이트를 정렬을 뜻한다.

mysql> SELECT id, SUBSTRING(comment,1,2000) FROM t -> ORDER BY SUBSTRING(comment,1,2000);

- BLOB과 TEXT 객체의 최대 크기는 타입에 따라 결정된다. 서버와 클라이언트 간에 전송할 수 있는
최댓값은 가용메모리의 양과 communications 버퍼의 크기에 의해 결정된다. message 버퍼의 크기는 max_allowed_packet 변수로 변경할 수 있으며 서 버와 클라이언트 프로그램을 위해 변경해야 한다. MySQL과 MySQLdump에서는 클라이언트측의 max_allowed packet 변수를 변경할 수 있게 한다. 또한 패킷 사이즈와 저장된 데이터 객체의 사이즈를 비교할 수 있다.

각 BLOB이나 TEXT 값은 개별적으로 할당된 객체에 의해 내부적으로 대응된다. 테이블이 개방되었을 때 컬럼에 하나씩 공간이 할당되는 것은 다른 모든 데이터 타입과는 다르다.
 
BLOB이나 TEXT 컬럼에서 바이너리 데이터를 미디어 파일로 저장하는 것이 나은 경우도 있다. 그러한 데이터를 처리하기에 유용한 MySQL의 string 처리함수를 찾아보는 것이다. 보안이나 여러 가지 이유로 사용된다.
posted by 나는너의힘
:
DATABASE/MYSQL 2009. 5. 6. 11:35


데스크탑에 오라클10g를 설치했지만 테스트를 위해(과연!?) 랩탑에 MySQL5.1을 그냥 설치했다.

나의 설치 과정

1. MySQL 설치
http://dev.mysql.com/downloads/
MySQL Community Server → windows → Windows ZIP/Setup.EXE (x86) →Pick a mirror → 다운로드

1) mysql-5.1.30-win32.zip 파일의 압축을 풀어준다.
2) Setup.exe 파일이 생성된다.
3) 실행
Setup Type : custom
Custom Setup : Developer Components → install, Install path → change
Configuration Type : Detailed Configuration
Server Type : Developer Machine
Database Usage : Multifunctional Database
InnoDB Tablespace Settings : 알아서 경로 설정
Decision Support(DSS)/OLAP 체크
Enable TCP/IP Networking 체크, Add firewall exception for this port 체크, Enable Strict Mode 체크
Best Support For Multilingualism 체크 - 'UTF-8', euc-kr은 아래 메뉴에서 선택 가능
Install As Windows Service 체크(service name확인), Include Bin Directory in Windows PATH 체크
Modify Security Settings 비번 체크
Execute
4) MySQL 실행
도스 창에서 명령 실행, 설정할 때 체크한 server name으로 실행한다.
실행
>net start mysql
중지
>net stop mysql
5)MySQL 접속
관리자 접속 - 비번은 setting에 넣은 비번
>mysql -u root -p
접속 끊기
>quit

2. MySQL 드라이버 설치
http://dev.mysql.com/downloads/
Connectors → Connector/J → 5.1 Source and Binaries (zip) → 다운로드

1) mysql-connector-java-5.1.7.zip 파일의 압축을 풀어준다.
2) mysql-connector-java-5.1.7 폴더가 생성된다.

3. 이클립스에 MySQL 연동
1) Build Path로 드라이버(mysql-connector-java-5.1.7-bin.jar)를 잡아준다.

DB 플러그인(DBedit)은 설치했다가 삭제했다.
설치는 완벽했으나...
SQL문 작성을 위해 파일을 생성하려면 에러 발생이 무한으로 반복되어 이클립스가 날아가는 증상도 반복-_-
대체 무엇이 문제였을까?
posted by 나는너의힘
:
JAVA 2009. 5. 6. 11:34


jdbc 방식의 연결시에는 초기 지연시간 발생하기 때문에 서비스 시간이 지연 → 서비스 시간 개선 → connection을 DB에 미리 연동해두고 필요한 클라이언트에게 연결된 connection을 제공 → 메모리 부하

JNDI(Java Naming & Directory Interface) : JVM → CP
DBCP를 찾아 가기 위한 객체
Context ct = new InitialContext();
DataSource ds = (DataSorce)ct.lookup("java:comp/env/jdbc/등록한 이름");
Connection con = ds.getConnection();

이후는 JDBC와 동일하다.

* DBCP설정
http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html

0. Drivers for older Oracle versions may be distributed as *.zip files rather than *.jar files. Tomcat will only use *.jar files installed in $CATALINA_HOME/common/lib. Therefore classes111.zip or classes12.zip will need to be renamed with a .jar extension. Since jarfiles are zipfiles, there is no need to unzip and jar these files - a simple rename will suffice

1.context configuration
server.xml의 context부분에 추가해준다.

<Resource name="jdbc/myoracle" -- context의 lookup에서 찾아갈 이름, myoracle만 변경가능, 대소문자 주의
              auth="Container"
              type="javax.sql.DataSource"
              driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:mysid"
              username="scott" 
              password="tiger"
              maxActive="50" -- 확장 커넥션의 생성 갯수, 기본과 동일하거나 기본+10
              maxIdle="40" -- 기본 커넥션의 생성 갯수
              maxWait="-1" -- 대기시간
/>

2. web.xml configuration
일반 클래스(DAO)에서 connection pool을 쓰려면 servlet이나 JSP에서 클래스를 인스턴스화 해서 쓴다.
안되면 web.xml설정, DTD의 설정에 따라 파일에 넣는다.
webcontent → WEB-INF → lib → web.xml
위에서 설정한 resource name으로 변경해준다

<resource-ref>
<description>Oracle Datasource example</description>
<res-ref-name>jdbc/myoracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
posted by 나는너의힘
:
DATABASE/Modelling 2009. 5. 6. 11:33


1. JDBC드라이버 로딩
오라클 - oracle.jdbc.driver.OracleDriver

  try{
  Class.forName("oracle.jdbc.driver.OracleDriver");//대소문자 주의
  }catch(ClassNotFoundException cnfe){
   cnfe.printStackTrace();
  }

2. 데이터베이스 커넥션 구함

 public Connection getConnection(){
  Connection con=null;
  String dburl = "jdbc:oracle:thin:@localhost:1521:orcl";//127.0.0.1루프백, 도메인, 로컬호스트
  String dboid = "scott";
  String dbopass = "tiger";
    
  try{
  con = DriverManager.getConnection(dburl,dboid,dbopass);
  }
  catch(SQLException e){
   e.printStackTrace();
  }//end catch
  
  return con;
 }
//singletonpattern이용

3. 쿼리 실행을 위한 statement 객체 생성

Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

   con = SingletonConnection.getInstance().getConnection();
   StringBuffer selectQuery = new StringBuffer();
   selectQuery.append("select num, name, address, phone, age from classinfo");
   pstmt = con.prepareStatement(selectQuery.toString());
  
4. 쿼리 실행

 rs = pstmt.executeQuery();

5. 쿼리 실행 결과 사용

 while(rs.next()){
    //조회된 결과를 자바빈즈로 생성
    xmlDateDTO xdd = new xmlDateDTO(
            rs.getInt("num"),
            rs.getInt("age"),
            rs.getString("name"),
            rs.getString("address"),
            rs.getString("phone"));//빈즈를 list로 관리
    classList.add(xdd);
   }

6. statement 종료

if(rs!=null){rs.close();}
if(pstmt!=null){pstmt.close();}

7. 데이터베이스 커넥션 종료

if(con!=null){con.close();}
posted by 나는너의힘
:
DATABASE/Modelling 2009. 5. 6. 11:33


※데이터의 무결성
- 데이터의 정확성과 일관성이 보장된 상태
- 무결성 제약 조건은 데이터베이스에 저장된 데이터의 정확성을 보장하기 위해 정확하지 않은 데이터가 데이터베이스 내에 저장되는 것을 방지하기 위한 제약 조건

※무결성의 종류
1. 엔티티 무결성 : 한 엔티티는 중복과 누락이 있을 수가 없음. 동일한 PK를 가질 수 없으며 PK의 속성이 Null을 허용할 수 없음
2. 참조 무결성 : 외래키가 참조하는 다른 개체의 기본키에 해당하는 값이 기본키 값이나 Null이어야 함
3. 속성 무결성 : 속성의 값은 기본값, Null여뷰, 지정된 도메인(데이터타입, 길이)규칙을 준수하여 존재해야 함
4. 사용자 무결성 : 사용자의 의미적 요구사항을 준수해야 함

※제약조건의 종류
1. 엔티티 무결성 : Primary Key. Unique Index
2. 속성 무결성 : Check, Null/Not Null, Default
3. 참조 무결성 : Foreign Key
4. 사용자 정의 무결성 : Trigger, User Define Data Type

※각 요소의 내용

Primary Key

컬럼의 유일성 보장, PK Null이 될 수 없음

Unique Index

다중의 보조 키 개념을 지원, 컬럼의 유일성 보장, Null 허용

Foreign Key

테이블 간의 논리적 관계가 유지됨을 보장, FK는 참조하는 테이블의 PK, Null 허용

Cascaded Option : Master 삭제 시 레코드가 함께 삭제

Nullified Option : Master 삭제 시 해당 값을 Null로 세팅

Restricted Option : FK가 존재하면 Master 레코드를 삭제할 수 없음

Data Type

데이터의 형을 제한하여 데이터 무결성 유지

Check

데이터를 추가할 때마다 SQL서버가 해당 값이 해당 컬럼들에 지정된 Check제약을 위배하는지를 검사함으로써 데이터 무결성 유지

Default

특정 컬럼에 대해 명시적으로 값을 입력하지 않은 경우에 SQL서버가 자동적으로 지정된 값을 삽입할 수 있도록 함으로써 데이터 무결성 유지

INSERT 또는 UPDATE에서 DEFAULT 키워드를 사용할 수 있음

Trigger

테이블의 내용을 변경하려는 특정 사건(DB연산)에 대해서 DBMS가 미리 정의된 일련의 행동(DB연산)을 수행하는 메커니즘, DBMS서버에 의해 자동으로 호출

데이터에 대한 변경을 시도할 때마다 자동적으로 호출

트랜젝션의 철회(rollback)와 같은 동작을 수행가능

저장 프로시저의 특별할 형태로서 SQL의 모든 기능을 이용가능

참조 무결성을 위해 사용가능

posted by 나는너의힘
:
DATABASE/Modelling 2009. 5. 6. 11:32


※정규화(Normalization)
- 테이블의 속성들이 상호 종속적인 관계를 갖는 특성을 이용하여 테이블을 무손실 분해하는 과정
- 가능한 한 중복을 제거하여 삽입, 삭제, 갱신 이상의 발생 가능성을 줄이는 것

정규화

정규화 내용

1차 정규화

복수의 속성값을 갖는 속성을 분리

2차 정규화

주식별자에 종속적이지 않은 속성을 분리, 부분종속 속성을 분리

3차 정규화

속성에 종속적 속성을 분리, 이전(이행적)종속(Transitive Dependency) 속성을 분리

보이스-코드 정규화

다수의 주식별자를 분리

4차 정규화

다가 종속(Multi-Valued Dependency) 속성 분리

5차 정규화

결합 종속(Join Dependency)일 경우, 두 개 이상의 N개로 분리


※함수적 종속
- 어떤 테이블 R에서 X와 Y를 각각 R의 속성집합의 부분 집합이라고 하면, 속성 X의 값 각각에 대해 시간에 관계없이 항상 속성 Y의 값이 오직 하나만 연관되어 있을 때, Y는 X에 함수적 종속 또는 X가 Y를 함수적으로 결정한다고 하고, X→Y로 표기한다.
- X→Y의 관계를 갖는 속성 X와 Y에서 X를 결정자, Y를 종속자라고 한다.

위 표를 함수적 종속성으로 보자면 다음과 같다.

종속성

개념

함수적 종속성(1NF)

릴레이션의 한 속성 X가 다른 속성 Y를 결정지을 때 Y X에서 함수적으로 종속

부분함수적 종속성(2NF)

Y X의 부분 집합에 대해서도 함수적으로 종속되는 경우

이행함수적 종속성(3NF)

릴레이션 R에서, AX이고 XY이면 AY이다

결정자함수적종속성(BCNF)

함수적 종속이 되는 결정자가 후보키가 아닌 경우

다중값 종속성(4NF)

한 관계에 둘 이상의 독립적 다중값 속성이 존재하는 경우

조인 종속성(5NF)

둘로 나눌 때는 원래의 관계로 회복할 수 없으나 셋 또는 그 이상으로 분리시킬 때는 원래의 관계를 복원할 수 있는 특수한 경우


※완전 함수적 종속
- 어떤 테이블 R에서 속성 Y가 다른 속성 집합 X 전체에 대해 함수적 종속이면서 속성 집합X의 어떠한 진부분집합 Z(Z⊂X)에도 함수적 종속이 아닐 때
- 어떤 속성이 기본키에 대해 완전히 종속적일 때

※부분 함수적 종속
- 어떤 테이블 R에서 속성 Y가 다른 속성 집합 X 전체에 대해 함수적 종속이면서 속성 집합X의 임의의 진부분집합 Z(Z⊂X)에 대해 함수적 종속일 때
- 어떤 속성이 기본키의 일부에 대해 종속적일 때

※정규화와 정규형
- 정규화 : 무엇이 수행되어야 하는 과정
- 정규형 : 무엇이 수행된 결과
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:30


XML네임스페이스 영문 페이지
http://www.w3.org/TR/REC-xml-names/

spring에서...
의존 관계를 설정하는 방법 중의 하나로...
<property>태그를 사용하지 않고 property 값을 설정하려 할 때 XML네임스페이스를 이용한다.

[XML네임스페이스]

xml네임스페이스는 xml문서에 URI레퍼런스로 구별되는 네임스페이스를 사용하여 xml문서에 쓰인 요소와 속성의 이름을 한정시킬 수 있게 한다.
.....
확장된 이름은 네임스페이스의 이름과 로컬 이름으로 구성된다. URI레퍼런스에서 빈 문자열은 네임스페이스의 이름으로 사용할 수 없다. 동일한 문서의 레퍼런스를 포함하고 있는 상대URI레퍼런스는 네임스페이스 선언에서 사용할 수 없다.
.....
네임스페이스는(정확히 말하자면 네임스페이스 바인딩) 예약된 속성어를 사용하여 선언하며 속성의 이름은 xmlns이거나 xmlns로 시작되어야 한다. XML의 다른 속성과 마찬가지로 여기에서 쓰이는 속성도 직접 입력하거나 디폴트로 해서 생성된다.
속성의 표준값은 URI레퍼런스 - 네임스페이스에 구별되는 네임스페이스의 이름 - 이거나 디폴트이어야 하며 지정된 용도에 맞게 쓰려면 네임스페이스의 이름은 유일성과 영속성을 가지고 있어야 한다. (스키마가 있더라도)이것은 스키마 검색을 위한 직접적인 용도는 아니다.
.....
속성이름이 PrefixedAttName과 일치하면 NCname은, 선언에 나온 요소의 영역에 있는 속성값에서 네임스페이스 이름과 함께 쓰이는 요소와 속성 이름에 결합하여 쓸 수 있는 네임스페이스 접두어를 사용한다. 이 때, 네임스페이스 속성은 공백이 될 수 없다. 
속성이름이 DefaultAttName과 일치하면 속성값에서 네임스페이스 이름은 선언에 나온 요소의 영역에서 디폴트네임스페이스이다.

네임스페이스 이름 http://ecommerce.example.org/schema 에 네임스페이스 접두어 edi가 결합된 네임스페이스 선언의 예

<x xmlns:edi='http://ecommerce.example.org/schema'>
  <!-- the "edi" prefix is bound to http://ecommerce.example.org/schema
       for the "x" element and contents -->
</x>

.....
PrefixedAttName = xmlns : NCname
DefaultAttName = xmlns
prefix = NCname
.....
qualified name은 네임스페이스의 설명을 일컫는다.
접두어는 qualified name의 네임스페이스 접두어 부분을 제공하며 네임스페이스 선언에서 URI레퍼런스와 결합하여 쓰인다.

(...이상 발해석이었음)

즉, 네임스페이스에서 접두어로 사용하는 문자는 NCname이다...(나의 결론)
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:30


1. 클라이언트의 요청을 받을 DispatcherServlet을 web.xml 파일에 설정한다.
2. HandlerMapping을 이용하여 요청 URL과 컨트롤러의 매핑 방식을 설정한다.
3. 클라이언트의 요청을 처리(로직을 수행)할 컨트롤러를 작성한다.
4. 컨트롤러의 처리 결과 응답 화면을 생성할지를 결정하는 뷰 리졸버를 구성한다.
5. 사용자에게 보여주는 JSP를 작성한다.

최소한의 작업.

1. 클라이언트에서 DispatcherServlet에 전달
2. HandlerMapping을 사용하여 클라이언트의 요청을 처리할 컨트롤러 객체 매핑
3. handleRequest() 메서드를 호출하여 클라이언트의 요청 전달,
    컨트롤러의 handleRequest() 메서드는 처리 결과를 가진 ModelAndView객체 리턴
4. ViewResolver로부터 응답 결과를 생성할 뷰 객체 설정
5. 클라이언트에 전송할 응답 생성
posted by 나는너의힘
:
Ajax 2009. 5. 6. 11:19

Ajax란?

Asynchronous JavaScript and XML(비동기 방식의 자바스크립트와 XML)

Ajax를 구성하는 요소들

  • XMLHttpRequest : 웹 서버와 통신담당. 사용자의 요청을 웹에 전송, 웹서버로부터 받은 결과를 웹 브라우저에 전달
  • DOM : 문서의 구조를 나타낸다.
  • CSS : 글자 색, 배경색, 위치, 투명도 등등 UI관련 부분
  • 자바스크립트 : 사용자로 부터 이벤트(마우스 드래그나 버튼 클릭)를 받아 XMLHttpRequest객체을 통해서 웹서버에 요청 밑 응답을 받아 화면 조작

Ajax와 기존방식의 차이점

  • 웹 브라우저가 아닌 XMLHttpReqeust 객체가 웹 서버와 통신
  • 웹 서버의 응답 결과가 HTML이 아닌 XML 또는 단순 텍스트
  • 페이지의 이동없이 결과가 화면에 반영

XMLHttpRequest 객체


XMLHttpRequest 프로그래밍 순서

  1. XMLHttpReqeust 객체 구하기
  2. 웹 서버에 요청 전송하기
  3. 웹 서버서 응답이 도착하면 화면에 반영하기

1. XMLHttpRequest 객체 구하기

IE와 나머지 브라우저가 서로 다름. IE는 ActiveX 컴포넌트로 제공하며, 나머지 브라우저들은 XMLHttpRequest클래스를 기본적으로 제공하고 있다.
<script type="text/javascript">
  var httpRequest = null;

  function getXMLHttpRequest() {
    // IE
    if (window.ActiveXObject) {
      try {
        return new ActiveXObject("Msxml2.XMLHTTP");
      } catch(e) {
        try {
          return new ActiveXObject("Microsoft.XMLHTTP");
        } catch(e1) { return null; }
      }
    }
    // FF, Opera...
    else if (window.XMLHttpRequest) {
      return new XMLHttpRequest();
    } else {
      return null;
    }
  }
</script>

2. 웹 서버에 요청 전송하기


  • open() 함수 : 요청의 초기화, GET/POST 방식 선택, 접속할 URL
  • send() 함수 : 웹 서버에 요청전송

2.1 open()함수의 인자

httpReqeust.open("GET", url, true);
순서대로
  1. HTTP 메소드(GET, POST)
  2. 접속할 URL
  3. 동기/비동기 방식 지정

2.2 GET방식 전달의 예

httpRequest = getXMLHttpRequest();
httpReqeust.open("GET", "/test.jsp?id=2&passwd=1111", true);
httpReqeust.send(null);

2.3 POST방식 전달의 예

httpRequest = getXMLHttpRequest();
httpReqeust.open("POST", "/test.jsp", true);
httpReqeust.send("id=2&passwd=1111");

3. 서버응답 처리하기

3.1 onreadystatechange, 콜백함수

httpRequest = getXMLHttpRequest();
httpRequest.onreadystatechange = callbackFunction;
httpReqeust.open("POST", "/test.jsp", true);
httpReqeust.send("id=2&passwd=1111");

// 콜백 함수 function callbackFunction() {
    ....
}

3.2 readStatus

바로위의 httpRequest.onreadystatechange에서 명시한 콜백함수는 readyStatus라는 프로퍼티의 값이 변경 될때마다 호출된다.

의 미 설 명
0 UNINITIALIZED 객체만 생성되고 아직 초기화되지 않은 상태(open메소드가 호출되지 않음)
1 LOADING open메소드가 호출되고 아직 send메소드가 불리지 않은 상태
2 LOADED send메소드가 불렸지만 status와 헤더는 도착하지 않은 상태
3 INTERACTIVE 데이터의 일부를 받은 상태
4 COMPLETED 데이터를 전부 받은 상태. 완전한 데이터의 이용 가능

 function callbackFunction() {
  if(httpRequest.readyState == 1 || httpRequest.readyState == 2 ||
   httpRequest.readyState == 3) {
   // 작업중임
  } else if(httpRequest.readyState == 4) {
   // 서버에서 완전한 응답이 도착한 경우
   // 응답결과에 따라 알맞은 작업 처리
  }
 }

readyState 값이 2, 3 인 경우 웹 브라우저에 따라 다르게 처리된다. 따라서 readyState의 값을 사용할 때는 1과 4를 사용하는 것이 크로스브라우저를 지원할 수 있는 가장 알맞은 밥법이다.

3.3 status/statusText

웹 서버로부터 응답이 도착하면 웹 서버에서 처리가 올바르게 수행되었는지 확인해야한다. XMLHpptRequest객체는 웹 서버가 전달한 상태코드를 status 프로퍼티에 저장한다.
텍스트 설 명
200 OK 요청 성공
403 Forbidden 접근 거부
404 Not Found 페이지 없음
500 Internal Server Error 서버 오류 발생
XMLHttpReqeust는 statusText프로퍼티도 제공하는데, 위의 표의 텍스트 문장을 저장한다. (오페라 8.51버전까지는 제공하지 않는다고 함.)

지금까지의 소스~
 function callbackFunction() {
  if(httpRequest.readyState == 1 || httpRequest.readyState == 2 || {
    httpRequest.readyState == 3) {
    // 작업중임
  } else if(httpRequest.readyState == 4) {
   // 서버에서 완전한 응답이 도착한 경우
   // 응답결과에 따라 알맞은 작업 처리
   if(httpRequest.status == 200) {
    //정상적으로 수행
   } else {
    alert("문제 발생 : " + httpRequest.status);
   }
  }
 }

3.4 responseText

서버로부터 응답이 도착한 것을 확인, 서버가 요청을 바르게 수행했을 경우 (readyState == 4 && status == 200) 단순 텍스트로 참조
posted by 나는너의힘
:
DATABASE/Modelling 2009. 5. 6. 11:18

1. 1NF여야한다.

2. 부분적 함수 의존이 없다.
부분적 함수 종속 관계를 피하는 간단한 방법으로는 새로운 키(인덱스용)를 하나 만드는 것입니다.
테이블의 모든 열이 기본키의 일부이면 1NF의 테이블을 2NF이기도 합니다.

※함수적 종속관계(함수적 종속성  Functional Dependency)
열의 데이터가 변경될 때 다른 열의 데이터가 변경되어야하면, 변경되는 열에 함수적으로 종속한다고 합니다.

※부분적 함수 종속
키가 아닌 열이 합성키의 전부가 아닌 일부에 종속되는 경우.

※이행적 함수 종속(Transitive Functional Dependency)
키가 아닌 열이 키가 아닌 다른 열과 관련 되는 경우
키가 아닌열이 변경되었을 때 다른열의 변경을 야기시킨다면, 이행적 종속열을 보유하고 있는 것 입니다.

※함수 종속 관계를 명시하는 방법
T.x ->; T.y
(T라는 테이블에서 열y는 열x에 함수적으로 종속된다. x가 변경되면 y가 따라서 변경되야 한다.)

※합성키
여러개의 열들로 구성되어 유일무이한 키를 만드는 기본키.
posted by 나는너의힘
:
DATABASE/Modelling 2009. 5. 6. 11:17

테이블에 원자적 데이터가 있다고해서 정규테이블이 된 것은 아닙니다. 완전한 정규 테이블이 되려면 제1정규형(1NF)의 형태여야만 합니다.

1NF형태를 갖추려면 다음의 두 규칙을 만족시켜야 합니다.

1. 각행의 데이터들은 원자적 값을 가져야 한다.

2. 같은 데이터가 여러 열에 반복되지 말아야 한다.


※원자적인 데이터
원자는 쪼갤수 없는 작은 조각의 정보입니다. 데이터가 원자적이면 이는 쪼갤 수  없는 가장 작은 조각으로 쪼개졌다는 의미입니다. 데이터베이스에서 원자적인 데이터란 쓰는 사람의 입장해서 충분하게 원자적인 것이면 됩니다.
- 원자적 데이터 규칙1 : 원자적 데이터로 구성된 열은 그 열에 같은 타입의 데이터를 여러개 가질 수 없다.
- 원자적 데이터 규칙2 : 원자적 데이터로 구성된 테이블은 같은 타입의 데이터를 여러열에 가질 수 없다. 

※기본키
기본키는 각 레코드를 식별하는데 사용합니다. 이는 곧 기본키열의 데이터는 중복될수 없다는 의미입니다.
- 기본키는 NULL이 될수 없습니다.
- 기본키는 레코드가 삽입될 때 값이 있어야 합니다.
- 기본키는 간결해야 합니다.
- 기본키의 값은 변경불가입니다
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:15

AOP설정 엘리먼트 (스프링 인 액션 참고)
 AOP 설정 엘리먼트 목적 
 <aop:advisor>  AOP 어드바이저를 정의 한다 
 <aop:after>  After어드바이스를 정의한다.(이 어드바이스는 메서드의 예외발생 여부와 관계 없다.) 
 <aop:after-returning>  After-returning 어드바이스를 정의한다. 
 <aop:after-throwing>  After-throwing 어드바이스를 정의한다. 
 <aop:around>  Around 어드바이스를 정의한다. 
 <aop:aspect>  애스펙트를 정의한다. 
 <aop:before>  Before 어드바이스를 정의한다. 
 <aop:config>  최상위 AOP엘리번트. 대부분의 <aop:*> 엘리먼트는 이 <aop:config>안에 포함되야 한다. 
 <aop:pointcut>  포인트컷을 정의한다. 


스프링 AOP 설정 엘리먼트를 이용 예

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xmlns:aop="http://www.springframework.org/schema/aop"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 

    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

         http://www.springframework.org/schema/aop 

         http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">



    <bean id="audience" class="chapter4.springidol.Audience" />

    

    <aop:config>

    

      <aop:aspect ref="audience">

      

        <aop:before

          method="takeSeats"

          pointcut="execution(* *.perform(..))" />


        <aop:before

          method="turnOffCellPhones"

          pointcut="execution(* *.perform(..))" />

          

        <aop:after-returning

          method="applaud"

          pointcut="execution(* *.perform(..))" />

          

        <aop:after-throwing

          method="demandRefund"

          pointcut="execution(* *.perform(..))" />

          

      </aop:aspect>

      

    </aop:config>

</beans>


대부분의 스프링 AOP설정 엘리먼트는 <aop:config>엘리먼트 내에 사용됩니다. 이 안에는 하나 이상의 어드바이저, 애스펙트, 포인트컷을 선언할 수 있습니다. 

 헌데 여기서 중복된 코드를 많이 볼수있습니다. 각 어드바이스의 pointcut 애트리뷰트들이 같은 값을 가지고 있는데요. 이는 DRY(don't repeat yourself)의 원칙 위반입니다; 이래서~ 바꾸는 방법은 밑에 소스에서 처럼 <aop:aspect>안에 <aop:pointcut> 엘리먼트를 이용해서 포인트컷에 이름을 부여하고 이를 다른 어드바이스에서 참조하는 방법입니다.

       ...

    <aop:config>

    

      <aop:aspect ref="audience">

        <aop:pointcut 

          id="performance"

          expression="execution(* *.perform(..))" />

      

        <aop:before

          method="takeSeats"

          pointcut-ref="performance" />


        <aop:before

          method="turnOffCellPhones"

          pointcut-ref="performance" />

          

        <aop:after-returning

          method="applaud"

          pointcut-ref="performance" />

          

        <aop:after-throwing

          method="demandRefund"

          pointcut-ref="performance" />

      </aop:aspect>

      

    </aop:config>

    ...


<aop:pointcut>은 같은 <aop:aspect>내부의 모든 어드바이스가 참조할 수있는 포인트컷으로 정의를 하였는데, 
이 <aop:pointcut>을 <aop:config>의 바로 하위에 정의하게 되면 다른 애스펙트에서도 이 포인트 컷을 참조할 수가 있습니다.

posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:14

@Aspect 어노테이션은 AspectJ 5버전에 새롭게 추가된 어노테이션으로, @Aspect 어노테이션을 사용하면 설정파일에 Advice 및 Pointcut등의 설정을 하지 않고도 자동으로 Advice를 적용 할 수 있습니다. 스프링2부터 이 어노테이션을 지원하고 있으며 설정파일에 <aop:aspectj-autoproxy> 태그를 설정파일에 추가해주면 @Aspect 어노테이션이 적용된 빈을 Aspect로 사용할 수 있게 됩니다. aop네임스페이스도 설정파일에 포함시켜야 합니다.

스프링인 액션 참고 자료.
설정파일

<beans xmlns="http://www.springframework.org/schema/beans"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xmlns:aop="http://www.springframework.org/schema/aop"

     xsi:schemaLocation="http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

       http://www.springframework.org/schema/aop 

      http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">



  <aop:aspectj-autoproxy />

  <bean class="chapter4.springidol.Audience" />

  ....


</beans>



어노테이션이 적용된 자바소스파일

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;


@Aspect

public class Audience {

public Audience() {

}


@Pointcut("execution(* *.perform(..))")

public void performance() {

}


@Before("performance()")

public void takeSeats() {

System.out.println("The audience is taking their seats.");

}


@Before("performance()")

public void turnOffCellPhones() {

System.out.println("The audience is turning off their cellphones");

}


@AfterReturning("performance()")

public void applaud() {

System.out.println("CLAP CLAP CLAP CLAP CLAP");

}


@AfterThrowing("performance()")

public void demandRefund() {

System.out.println("Boo! We want our money back!");

}

}



@Around어노테이션 사용시 주의점

@Around어노테이션 사용시에는 반드시 proceed()를 호출하는 부분이 들어가야 합니다. proceed()가 호출이되어야 원래 호출되야 할 메서드로 실행이 넘어갑니다. 이를위해 Around어드바이스가 적용된 메소드에서 ProceedingJoinPoint객체를 인자로 받도록 선언을 해 주어야 합니다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:13

Advice 유형별 인터페이스
 어드바이스 유형 인터페이스 
 Before  org.springframework.aop.MethodBeforAdvice
 After-returning  org.springframework.aop.AfterReturningAdvice
 After-throwing  org.springframework.aop.ThrowAdvice
 Around  org.aopalliance.intercept.MethodInterceptor
 Introduction  org.springframework.aop.IntroductionInterceptor 

Before Advice
target의 특정 메소드를 실행하기 전에 어떠한 일을 추가하고 싶을 경우에 사용합니다.

After-retuning Advice
target객체의 특정 메소드의 실행을 무사히 완료한 뒤에 추가할 작업을 정의 할 때 사용합니다. (예외가 발생하지 않았을 경우)

After-throwing Advice
Advice 가 적용이 되는 메소드에서 예외(Exception)가 발생했을 경우 특정한 일을 추가하고자 할 때 사용합니다.

Around Advice
위에서 살펴본 Before, After-returning, After-throwing 어드바이스의 역할을 모두 다 할 수 있는  강력한 Advice입니다. 또 대상이 되는 메소드의 실행 여부도 결정할 수 있으며, target 메소드의 반환 값을 변경할 수 도 있습니다.

Introduction Advice
위의 어드바이스들과는 다른 매우 특이한 어드바이스로 target객체 자체에 별도의 메소드 또는 속성을 추가합니다.


Classic AOP
MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice 예제 (Spring In Action 참고)

/**

 * 세가지 어드바이스 유형을 구한다. MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice

 *

 */

public class AudienceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {

public AudienceAdvice() {

}


// 메소드 실행전에 호출된다.

public void before(Method method, Object[] args, Object target) throws Throwable {

audience.takeSeats();

audience.turnOffCellPhones();

}


// 성공적으로 메소드가 반환되면 실행된다

public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {

audience.applaud();

}


// 예외가 발생되면 실행된다.

public void afterThrowing(Throwable throwable) {

audience.demandRefund();

}


private Audience audience;


public void setAudience(Audience audience) {

this.audience = audience;

}

}



  <bean id="audience" class="chapter4.classicSpringAop.Audience" />


  <bean id="audienceAdvice"

class="chapter4.classicSpringAop.AudienceAdvice">

    <property name="audience" ref="audience" />

  </bean>

  

  <bean id="audienceAdvisor"

        class="org.springframework.aop.support.DefaultPointcutAdvisor">

    <property name="advice" ref="audienceAdvice" />

    <property name="pointcut" ref="performancePointcut" />

  </bean>


  <bean id="performancePointcut"

class="org.springframework.aop.aspectj.AspectJExpressionPointcut">

    <property name="expression" value="execution(* perform(..))" />

  </bean>


먼저 맨 밑의 포인트컷 정의 부분을 보면 AspectJExpressionPointcut을 사용하고 있는데 이는 AspectJ 스타일의 표현식을 이용한 것입니다. 

여기서 AspectJ의 표현식을 알아보면

JdkRegexpMethodPointcut(정규표현식)을 이용한다면

  <bean id="performancePointcut"

class="org.springframework.aop.aspectj.JdkRegexpMethodPointcut">

    <property name="pattern" value="*.perform" />

  </bean>

이렇게 쓸 수 있습니다. 

정규표현식을 알아본다면
 기호 의미 
 . 어떤 문자든 딱 한 글자
 *  * 앞에 있는 문자가 여러개 있을 수 있음
 +  + 앞에 있는 문자가 최소한 한 개에서 여러개 있을 수 있음 
 \  \ 뒤에 오는 문자가 있어야한다


DefaultPointcutAdvisor는 단순히 어드바이스(audienceAdvice 참조)와 포인트컷(performancePointcut)을 결합시키는 어드바이저 클래스입니다.

포인트컷과 어드바이스를 동시에 정의할수있는 어드바이저 클래스도 있는데 RegxpMethodPointcutAdvisior입니다.
RegxpMethodPointcutAdvisior를 이용한다면

   <bean id="audienceAdvisor"

        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

     <property name="advice" ref="audienceAdvice" />

     <property name="pattern" value=".*perform" />

   </bean>

이렇게 쓰고 기존의 포인트컷 부분은 없애 주시면 됩니다.


ProxyFactoryBean 활용

    <bean id="dukeTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>

    

    <bean id="duke" class="org.springframework.aop.framework.ProxyFactoryBean">

      <property name="target" ref="dukeTarget" />

      <property name="interceptorNames" value="audienceAdvisor" />

      <property name="proxyInterfaces" value="chapter2.springidol.Performer" />

    </bean>

    

    <bean id="stevieTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>

    

    <!-- 똑같은 코드의 중복 -->

    <bean id="stevie" class="org.springframework.aop.framework.ProxyFactoryBean">

      <property name="target" ref="stevieTarget" />

      <property name="interceptorNames" value="audienceAdvisor" />

      <property name="proxyInterfaces" value="chapter2.springidol.Performer" />

    </bean>


duke 프록시와 stevie 프록시가 같은 코드가 중복이 된다. 다른 빈들을 만들때도 이런식으로 하면 반복되는 정보가 너무 많아진다. 이럴 때는 추상 빈으로 ProxyFactoryBean을 하나 선언해 두고, 이를 부모삼아 각 프록시 빈에서 재사용 하면 된다.

변경후~~

    <bean id="dukeTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>


    <bean id="stevieTarget"

      class="chapter2.springidol.PoeticJuggler"

      autowire="constructor">

      <constructor-arg ref="sonnet29"/>  

    </bean>

    

    <bean id="audienceProxyBase" 

      class="org.springframework.aop.framework.ProxyFactoryBean"

      abstract="true">

      <property name="interceptorNames" value="audienceAdvisor" />

      <property name="proxyInterface" value="chapter2.springidol.Performer" />

    </bean>

    

    <bean id="stevie" parent="audienceProxyBase">

      <property name="target" ref="stevieTarget" />

    </bean>

    

    <bean id="duke" parent="audienceProxyBase">

      <property name="target" ref="dukeTarget" />

    </bean>



ProxyFactoryBean말고 autoproxing을 사용하자.

위에 작성했던 proxy가 들어가기 전의 코드로 돌아가서~ 프록시땜시 뒤에 붙혀주었던 xxxTarget 은 전부다 원래 빈의 이름으로 바꿔줍시다. 그리고 밑에 요거만 붙혀놓으면... 오토프록시가 설정이되어 할일이 없어집니다... 

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />


DefaultAdvisorAutoProxyCreator 클래스는 빈으로 등록만 되면, 자동으로 모든 어드바이저의 포인트컷이 특정 빈의 메서드에 일치하는지 확인하고, 일치하는 빈을 찾으면해당 어드바이스가 적용된 프록시로 대체해 놓습니다. 한마디로, 어드바이저가 일치하는 빈은 모두 자동으로 프록시화 됩니다.

이 방법들 말고 더욱 간단하게 설정하는 방법은 다음으로 미룹니다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:12

Aspect Oriented Programming의 약자로 여러 곳에 흩어져 존재할 수 밖에 없었던 코드를 모듈화 할 수있는 프로그래밍 기법입니다. Aspect라는 것을 사용하요 츠로그래밍을 할 때 특정한 관심사를 가진 코드 부분을 별도의 모듈로 분리함으로써, 기존 객체지향의 강력한 기능(상속, 위임)만으로는 처치가 곤란했던 중복을 제거 할 수 있게 되었습니다.
로깅, 트랜잭션 처리, 모니터링 관련 코드들을 AOP를 적용하여 하나의 Aspect로 모듈화각 가능하므로 서비스계층이나 도메인 계층에서 관련된 코드들의 제거 할수 있습니다. 또 특정 클래스에 종속성을 가지던 현상을 제거 할수 있게 되었습니다.

Spring AOP용어의 정리

Advice : 언제 무엇을 할지 나타냅니다. 즉 애스펙트가 해야하는 작업언제 그 작업을 수행해야 하는지를 정의한 것이 어드바이스 입니다. (실제로 Target 객체에 적용할 일을 나타냄.)

◎ Joinpoint : Advice를 적용할 시점을 말합니다. (생성자 호출, 필드에 접근, 필드의 값 변셩, 메소드 호출등의 시점.) Spring AOP는 메소드 호출 Joinpoint만 지원합니다.

Pointcut : Joinpoint의 부분집합으로 애스펙트가 어드바이스 할 조인포인트의 영역을 좁히는 일을합니다.

Advisor : 하나의 Advice와 하나의 Piontcut을 묶은 것. Aspect는 여러개의 Advice와 Pointcut을 가지고 있는 것을 말합니다. 즉 Advisor도 하나의 Advice와 Pointcut을 가지고 있는 Aspect라고 할 수 있습니다.

Aspect : Advice + Pointcut 
어드바이스와 포인트컷을 합친 것이 애스펙트 입니다. 두가지 정보가 합쳐지면 애스팩트가 무엇을 언제해야할지, 즉 애스펙트에 필요한 모든 정보가 정의됩니다.

Introduction : 기존 클래스의 코드 변경 없이도 새 메소드나 멤버변수를 추가하는 기능입니다.

Target : Advice의 대상이 되는 객체를 말합니다.

Proxy : 프록시 객체
Spring AOP는 Proxy객체를 사용합니다. 프록시는 어드바이스를 타깃 객체에 적용하면 생성되는 객체입니다.

Weaving : Target 객체에 Aspect를 적용하는 과정.
타깃 객체에 애스펙트를 적용해서 새로운 프록시 객체를 생성하는 절차를 위빙이라고 합니다. 애스펙트는 타깃 객체의 조인포인트로 위빙됩니다. 
위빙은 대상 객체의 생애중 컴파일 시점, 런타임 시점, 클래스 로딩 시점에 할 수 있는데, Spring AOP는 런타임시에 동시적으로 Proxy객체를 생성합니다.


Spring AOP의 특징

◎ 자바로 작성한다.

◎ 스프링 애스팩트는 실행시간에 만들어진다. (런타임시에 특정 Target객체의 Proxy객체를 만들어 Aspect로 사용한다.) 
스프링에서 Proxy를 만드는 방법은 두가지가 있는데 인터페이스 기반으로 Proxy를 만드는 방법과 클래스를 기반으로 Proxy를 만드는 방법이 있습니다. 인터페이스를 기반으로 Proxy를 만들때는 JDK의 Proxy클래스를 사용하기 때문에, 별도의 라이브러리를 클래스 패스에 추가할 필요가 없으며, 인터페이스 기반의 코딩으로 보다 유연한 코드 작성이 가능합니다. 반면 클래스 기반 Proxy를 만들 때는 CGLIB 라이브러리를 필요로 하며, 상속을 사용하여 만들 수 없기 때문에 final로 선언된 메소드를 가진 클래스의 Proxy객체를 생성할 수 없습니다.

method joinpoint만 지원한다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:12

이전 글에 이어서 의존관계자동설정에 대해서 알아 보겠습니다.
스프링은 의존하는 빈 객체의 타입이나 이름을 이용하여 의존 객체를 자동으로 설정할 수 있습니다. 여기(The Spring Framework - Reference Documentation)에 자세한 내용이 있네요 ^^;

일단 네가지 방식이 존재합니다. 방식으로는
1. byName : 프로퍼티의 이름과 같은 이름을 갖는 빈객체를 설정
2. byType : 프로퍼티의 타입과 같은 타입을 갖는 빈객체를 설정
3. constructor : 생성자 파라미터 타입과 같은 타입을 갖는 빈객체를 설정
4. autodetect : constructor방식을 먼저 적용, byType방식을 적용
네 가지 방식이 있습니다.

일단 설정파일에 포함된 모든 빈 객체에 대해서 특정방시의 자동 설정을 적용하고 싶다면
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:p="http://www.springframework.org/schema/p"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans      
  5.   http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
  6.   default-autowire="byName">  
  7. ...    
  8. ...   
  9. </beans>  
이렇게 해주시면 됩니다.

네가지의 설정 중에서 예를 하나만 들겠습니다.

  1. <bean name="userService" class="yoyojyv.service.UserServiceImpl" autowire="byName"/>  
autowire의 속성 값을 네가지 속성중에 하나만 주면 됩니다. 여기선 byName을 썼군요.
DI설정을 프로퍼티 방식(setter Injection)을 썼을경우에 autowire속성을 constructor로 하면 어떻게 될까요? 직접 해본 결과 오류가 납니다. ㅋㅋ 각 설정에 맞게 써 주어야 하고, 또 byType, constructor, autodetect의 경우 동일한 타입의 빈 객체를 2개 이상 정의를 하게되면 오류가 납니다. 지가 어떤빈을 써먹어야 할지 결정을 못하네요~

의존 관계를 자동으로 알맞게 설정해주는 기능은 설정파일의 크기를 줄여주고 유용한 기능이긴 하지만, 설정파일만으로 빈 객체간의 의존관계를 파악하기 힘들다는 단점이 있습니다. 규모가 커질수록~ 더 파악하기 힘들어지기때문에 상황에 맞게~ 되도록이면 설정파일에 의존관계를 명시하는 것이 좋은 방법이라고 합니다.
posted by 나는너의힘
:
JAVA/SPRING 2009. 5. 6. 11:10

스프링 프레임워크가 가지는 가장 핵심적인 기능은 IOC(Inversion Of Control)입니다. 그중에서 DI(Dependency Injection)는 스프링 프레임워크에서 지원하는 IOC의 한 형태입니다.
DI는 클래스 사이의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동적으로 연결해 주는 것을 말합니다. 컨테이너가 의존관계를 자동적으로 연결시켜 주기때문에 컨테이너 API에 종속되는 것을 줄일 수 있습니다.

의존관계를 설정하는 방식으로는 자주 쓰이는 것들에는 생성자 방식(Constructor Injection), 프로퍼티 설정 방식(Setter Injection) 등이 있습니다.

1. 생성자 방식
UserServiceImpl.java 

public class UserServiceImpl implements UserService {

  private UserDAO userDAO;

  public UserServiceImpl(UserDAO newUserDAO) {

    this.userDAO = newUserDAO;

  }


  ...


}



applicationContext.xml

  <bean id="userDAO" class="yoyojyv.dao.MySQLUserDAO"/>

  <bean id="userService" class="yoyojyv.service.UserServiceImpl">

    <constructor-arg>

      <ref bean="userDAO"/>   

    </constructor-arg>

  </bean>


UserServiceImpl.java 의 생성자와 applicationContext.xml 의 3~5번째줄의 <constructor-arg>태그를 이용하여  의존하는 객체를 전달 할 수 있습니다. 

    <constructor-arg ref="userDAO"/ >

바로위에 처럼
한줄로 표현도 가능하죠.


2. 프로퍼티 설정 방식
UserServiceImpl.java 

public class UserServiceImpl implements UserService { 

  private UserDAO userDAO;    

  public void setUseDAO(UserDAO newUserDAO) {   

    this.userDAO = newUserDAO;  

  } 

  ....

 }


applicationContext.xml

  <bean id="userDAO" class="yoyojyv.dao.MySQLUserDAO"/>

  <bean id="userService" class="yoyojyv.service.UserServiceImpl">

    <property name="userDAO">

      <ref bean="userDAO"/>

    </property>

  </bean>


UserServiceImpl.java 의 3~5번째줄의 setter메소드와 applicationContext.xml 의 3~5번째줄의 <property>태그를 이용하여  의존하는 객체를 전달 할 수 있습니다. 

나머지 방식들과 IoC container에관한 내용은 여기(The Spring Framework - Reference Documentation)<-- 에서 확인 하세요~
posted by 나는너의힘
:
JSP 2008. 9. 14. 11:53

출처: http://mkseo.pe.kr/blog/?p=65

많은 분들이 jsp에서 한글처리때문에 많은 고생을 하고 계신데 한글처리는

동작원리만 알면 쉽게 풀수 있는 문제입니다.

그럼. 동작원리를 잠깐 알아볼까요…. ^^

먼저 자바는 유니코드를 사용한다는 사실을 인지해야합니다.
(자바하시는 분들은 다 알고 있지만 한글처리를 하실때 많이 빼먹는 부분이기도합니다)

다시 말해서 jsp(java) 안에서는 문자열이 유니코드라는 것입니다.

그럼. 브라우저에서 request를 보낼 때 입니다.

HTTP 요청은 8859_1로 보냅니다. 즉 다시 말하면 한글완성형코드 그대로 변환없이

보냅니다. (byte그대로…)

일단 간략하게 그리면

브라우저 한글완성형코드 그대로 전송 –request(*)–> jsp 컨테이너에서 유니코드로 변환 –> 내부처리

–response(*)–> 결과물을 브라우저로 전송

(*)부분에서 유니코드<-->해당문자열코드로 변환이 일어납니다.

request(*)에서 문자셋이 지정되어 있지 않으면 (이 말은 브라우저가 request를 요청할 때 특별히
문자셋을 지정하지 않았을 때, 가장 일반적인 상황입니다) 8859_1로 처리됩니다.

즉. “한”이라는 문자열을 보냈다고 했을 때 완성형코드 2byte가 그대로 전송되죠.

8859_1 문자셋코드를 유니코드로 변환하면 상위바이트와 하위바이트가 각각 1자의

유니코드로 변환되므로 “한”이라는 글자는 유니코드 2자로 변환됩니다.

아시다시피 유니코드에서 한글은 1자입니다. 이 변환이 있더라도 한글byte가 깨지지는 않습니다.

왜냐하면 상위, 하위바이트가 각각 유니코드 안에 그대로 살아있기때문입니다.

이 경우 유니코드문자열.getBytes(”8859_1″)의 메소드 호출로 원래 byte열로 돌릴 수 있기 때문입니다.

request에서 기본 8859_1 문자셋을 다른 문자셋으로 바꾸는 메소드가 있죠.

request.setCharacterEncoding(”euc-kr”) 이라고 하면(반드시 파라미터를 읽기 이전에 해야합니다)

한글 1자(2byte)를 유니코드 1자로 변환해줍니다..

response(*) 부분은 브라우저에 보내기전에 유니코드를 해당 문자셋의 byte열로 변환하는 부분입니다.

page 태그나 response.setContentType() 메소드에서 “text/html; charset=euc-kr” 식으로 설정가능합니다.

지정하지 않으면 역시 8859_1로 처리되므로 request에서 8859_1이면 들어온 그대로 다시 보내므로

어떤 문자코드라도 깨지지 않습니다. 그러나 euc-kr로 되어 있으면 유니코드 –> 한글완성형

변환시 유니코드 1자를 한글 1자로 인식하기때문에 한글유니코드는 2byte의 완성형 코드로 변환됩니다.

여기서 한글유니코드를 8859_1으로 변환하면 유니코드의 상위byte가 없어지고 하위byte만 사용됩니다.

그러니 한글이 깨져서 브라우저로 전송됩니다.

이 경우 글자의 상위byte가 없어지므로 되돌릴 수 없습니다.

그래서 한글이 정상적으로 처리될려면

1, 브라우저 — 8859_1(default) –> jsp 컨테이너(jsp/java) — 8859_1(default) –> 브라우저
(* 비추전)

2. 브라우저 — euc-kr(요청시 브라우저에서 지정하던지, 아니면 setCharacterEncoding사용 –>
jsp 컨테이너(jsp/java) — euc-kr(response에서 contentType으로 지정) –> 브라우저
(* 추전)

3. jsp 내에서 (실행시간include)로 jsp가 아닌 한글화일(html등) 포함할 때는 jsp컨테이너가 실행될 때
시스템 문자셋에 따라서 변환이 됩니다.
그래서 1의 경우일 경우 시스템은 반드시 8859_1로 문자셋(로케일의 문자코드셋)으로 되어야하고
2의 경우는 한글코드(리눅스, 원도우즈에 따라 명칭이 다르지만 기본적으로 완성형표준코드입니다)로
지정되어 있어야 깨지지 않습니다.

4. 자바빈이나 db에서 한글처리 1의 경우를 비추천으로 하는 이유는 자바빈이나 db에서도
모두 8859_1로 맞추어 주어야한다는 것입니다. 즉 클래스를 컴파일할 때도 컴파일 옵션에 8859_1로
지정해주어야 클래스안의 한글이 깨지지 않습니다. (디폴트로 시스템 문자셋으로 컴파일, 원도는 당근 한글셋)
2의 경우는 euc-kr로 맞추어 주어야합니다. 대부분 개발시스템의 문자셋은 당근 한글이겠죠 ^^
2의 경우에서 mysql의 연결url에 unicode사용 옵션을 주고 문자셋을 주면 그냥 됩니다.
(상세한 옵션: jdbc:mysql://localhost/디비명?useUnicode=true&characterEncoding=euc-kr)

오라클도 시스템 문자셋에 따라 알아서 동작하는데
db가 asc7인가(갑자기 기억안남) 일때 문제가 있는 경우가 있는데 이경우 오라클 클라이언트를
같이 맞추어주고 getString(…)메소드를 읽을 때 new String(XXX.getBytes(8859_1), “euc-kr”)로
변환해주어야 합니다. 이건 오라클 jdbc드라이버가 db asc7 –> client euc-kr 변환을 못해주는 것 같습니다.
asc7 –> 8859_1 –> euc-kr 요렇게 두번 해주어야 하는데 asc7 –> euc-kr 요렇게 바로 해버리니까
한글이 깨지는 것 같습니다.(오라클 jdbc 스펙을 확인해보세요..)

posted by 나는너의힘
:
JAVA 2008. 8. 24. 21:59

[스윙] JEditorPane에서 html 을 표현하도록 해주는 방법

contentType 을 text/html 로 해준다.

제목: [스윙] JTable 에서 row 단위로 색깔을 다르게 주고 싶을때

JTable 생성시 prepareRenderer 메소드를 다음과 같이 재정의 해준다.

JTable table = new JTable() {
             public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                 Component c = super.prepareRenderer(renderer, row, column);
                 if (!isCellSelected(row, column)) {
                     if (row % 2 == 0) {
                        c.setBackground(Color.blue);
                     } else {
                        c.setBackground(Color.red);                        
                     }
                 }
                 
               return c;
             }
         };

제목: [스윙]SwingUtilities.invokeLater 와 SwingUtilities.invokeAndWait 의 차이점

SwingUtilities.invokeLater 와 SwingUtilities.invokeAndWait 메소드는 외부에서 다이얼로그와 같은 창을
띄울때 다이얼로그에 포커스가 가도록 해주는 함수들이다.

그런데 위의 두함수의 차이점은 invokeLater의 경우 호출한쪽에서 제어권을 가지지 않는경우이다 즉 비동기화를 의미하며 invokeAndWait 는 그 반대가 된다.



제목: [스윙] JLabel 에서 background 에 색깔을 주려면

opaque 를 true 로 해줘야 색깔이 바뀐다

제목: [스윙] JTable의 데이타가 변했는데도 화면에 변화가 생기지 않을때

JTable내의 데이타모델을 불러와서 다음과같이 2개를 메소드를 호출해준다.
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
dtm.fireTableStructureChanged();
dtm.fireTableDataChanged();

 

제목: [스윙] JOptionPane 이 스레드에 의해서 호출이 될때 제대로 동작하지 않을때

JOptionPane은 자신의 부모창이 아닌 외부 스레드에 의해서 호출이 될때 버튼이 활성화되지 않는 문제점이 있다. 이때 다음과 같이 해주면 된다
SwingUtilities.invokeAndWait(new Runnable()              {                
public void run() { JOptionPane.showXXXX...};              
});

 

 

제목: [스윙] DefaultTableModel 을 사용하면서 CheckBox모양이 나타나지 않을때

다음과 같이 재정의해주면 됩니다.
    public Class getColumnClass(int c) {
       return getValueAt(0, c).getClass();
    }

 

 

제목: [스윙] JComboBox 에서 아이템이 변할때 한번만 이벤트를 먹도록 하는 방법

if(e.getStateChange() == e.SELECTED){
}

public void itemStateChanged(java.awt.event.ItemEvent e) {      
   if(e.getStateChange() == e.SELECTED){
   }
}

posted by 나는너의힘
: