Spring3.0 DB

2012. 5. 14. 19:14

기본프로젝트
=================
완료프로젝트


=================================이론=====================================
p394

p412

p416

    //@Valid @InitBinder 와 연동해서 검증을 해줌
    @RequestMapping(value="/update.do", method=RequestMethod.POST)
    public String submit(@Valid MemberCommand memberCommand, BindingResult result){

        if(result.hasErrors()){
            return formViewName;
        }
        memberDao.updateMember(memberCommand);
        return "redirect:/list.do";
    }
    @InitBinder //initBinder 검증 등록
    protected void initBinder(WebDataBinder binder){
        binder.setValidator(new MemberValidator());
    }




===============================프로젝트===================================



=================================코드=====================================



===============================출력결과===================================


DB MEMBER1 테이블


멤버등록



리스트뿌리기

상세보기

수정하기

삭제하기






'스프링3.0' 카테고리의 다른 글

스프링 3.0 AOP 에러. 문제 해결  (1) 2012.05.15
Spring3.0 Tiles  (1) 2012.05.14
Spring3.0 View error filedown  (0) 2012.05.14
Spring3.0 MVC 웹요청 처리  (0) 2012.05.14
Spring 3.0 AOP  (0) 2012.05.14
Posted by 사라링

기본 세팅 프로젝트 파일


=================================이론=====================================
P309
뷰 영역 구현
P260
에러코드의 출력

P361
파일다운로드처리

p373~378
국제화처리

p362~367
엑셀,pdf 파일다운로드



===============================프로젝트===================================
chap07
src
    madvirus.spring.chap07.controller
           AuthenticationException *1 - 로그인 테스트 뷰영역 구현 에러코드출력
           Authenticator *1
           DownloadController *2 - 파일다운로드
           LocaleChangeController *3 - p376 Locale resolver
           LoginCommandValidator *1
           LoginCommnad *1
           LoginController *1
           MockAuthenticator *1
           PageRank *4 - 엑셀파일
           PageRanksController *4 - 엑셀파일 다운로드
           PageReportController *4 - pdf파일
    madvirus.spring.chap07.view
           DownloadView *2
           PageRanksView *4 - 엑셀파일
           PageReportView *4 - pdf파일

     messages
           label_en.properties *1
           label.properties *1
           validation_en.properties *1
           validation.properties *1

WebContent
      viewjsp
           loginForm.jsp *1
           loginSuccess.jsp *1

      dispatcherInternal-servlet.xml *1
      dispatcherNonHtml-servlet.xml *2
      web.xml

index.jsp
=================================코드=====================================
chap07
src
    madvirus.spring.chap07.controller
           AuthenticationException *1 - 로그인 테스트 뷰영역 구현 에러코드출력
package madvirus.spring.chap07.controller;

public class AuthenticationException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public AuthenticationException(String message) {
        super(message);
    }
}

           Authenticator *1
package madvirus.spring.chap07.controller;

public interface Authenticator {
    void authenticate(String id,String password);
}

           DownloadController *2 - 파일다운로드
package madvirus.spring.chap07.controller;

import java.io.File;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.ModelAndView;
    
@Controller
public class DownloadController implements ApplicationContextAware {

    private WebApplicationContext context = null;
   
    @RequestMapping("/file")
    public ModelAndView download() throws Exception {
        File downloadFile = getFile();
        return new ModelAndView("download","downloadFile",downloadFile);
    }
   
    private File getFile(){
        String path = context.getServletContext().getRealPath("/WEB-INF/설명.txt");
        return new File(path);
    }
   
    public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
        this.context = (WebApplicationContext)applicationContext;
    }
}

           LocaleChangeController *3 - p376 Locale resolver
package madvirus.spring.chap07.controller;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.LocaleResolver;

@Controller
public class LocaleChangeController {

    private LocaleResolver localeResolver;

    @RequestMapping("/changLanguage")
    public String change(@RequestParam("lang")String language,HttpServletRequest request, HttpServletResponse response){
        Locale locale = new Locale(language);
        localeResolver.setLocale(request, response, locale);
        return "redirect:/index.jsp";
    }           
    public void setLocaleResolver(LocaleResolver localeResolver){
        this.localeResolver = localeResolver;
    }
}

           LoginCommandValidator *1
package madvirus.spring.chap07.controller;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class LoginCommandValidator implements Validator {

    public void validate(Object target, Errors errors) {
        //비어있거나 공백이있으면 돌려보냄
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "id", "required");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "required");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "loginType", "required");
    }

    public boolean supports(Class<?> clazz) {
        return LoginCommnad.class.isAssignableFrom(clazz);
    }   
}

           LoginCommnad *1
package madvirus.spring.chap07.controller;

public class LoginCommnad {
   
    private String id;
    private String password;
    private String loginType;
   
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getLoginType() {
        return loginType;
    }
    public void setLoginType(String loginType) {
        this.loginType = loginType;
    }
}

           LoginController *1
package madvirus.spring.chap07.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

   /*//web.xml 에서 
  <servlet-mapping>
    <servlet-name>dispatcherInternal</servlet-name>
    <url-pattern>/jsp/*</url-pattern>
  </servlet-mapping>  => /jsp/login/login.do */
@Controller  
@RequestMapping("/login/login.do")
public class LoginController {

    private Authenticator authenticator;

    @ModelAttribute("login")
    public LoginCommnad formBacking(){
        return new LoginCommnad();
    }

    @RequestMapping(method = RequestMethod.GET)
    public String form(){
        return "loginForm";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String submit(@ModelAttribute("login") LoginCommnad loginCommand,BindingResult result){
        new LoginCommandValidator().validate(loginCommand, result);

        if(result.hasErrors()){
            return "loginForm";
        }
        try{
            authenticator.authenticate(loginCommand.getId(), loginCommand.getPassword());

            return "loginSuccess";
        }catch (AuthenticationException ex){                    //null : loginCommand.getId() 가 null이면 default 값
            result.reject("invalidIdOrPassword", new Object[] {loginCommand.getId()},null);
            return "loginForm";
        }
    }

    @ModelAttribute("loginTypes")
    protected List<String> referenceData() throws Exception {
        List<String> loginTypes = new ArrayList<String>();
        loginTypes.add("일반회원");
        loginTypes.add("기업회원");
        loginTypes.add("헤드헌터회원");
        return loginTypes;
    }
   
    public void setAuthenticator(Authenticator authenticator){
        this.authenticator = authenticator;
    }
}

           MockAuthenticator *1
package madvirus.spring.chap07.controller;

public class MockAuthenticator implements Authenticator{

    public void authenticate(String id, String password) {
        if(!id.equals("madvirus")){
            throw new AuthenticationException("invalid id"+ id);
        }       
    }
}

           PageRank *4 - 엑셀파일
package madvirus.spring.chap07.controller;

public class PageRank {
 
    private int rank;
    private String page;
   
    public PageRank() {
    }
   
    public PageRank(int rank, String page) {
        super();
        this.rank = rank;
        this.page = page;
    }
   
    public int getRank() {
        return rank;
    }
    public String getPage() {
        return page;
    }   
}

           PageRanksController *4 - 엑셀파일 다운로드
package madvirus.spring.chap07.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class PageRanksController {

    @RequestMapping("/pageRanks")
    public ModelAndView handleRequestInternal(){
       
        List<PageRank> pageRanks = new ArrayList<PageRank>();
       
        pageRanks.add(new PageRank(1, "/bbs/mir2/list"));
        pageRanks.add(new PageRank(2, "/bbs/mir3/list"));
        pageRanks.add(new PageRank(3, "/bbs/changchun2/list"));
       
        return new ModelAndView("pageRanks","pageRanks",pageRanks);
    }
}

           PageReportController *4 - pdf파일
package madvirus.spring.chap07.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class PageReportController {

    @RequestMapping("/pageReport")
    public ModelAndView pdfReport(){
        List<PageRank> pageRanks = new ArrayList<PageRank>();
        pageRanks.add(new PageRank(1, "/bbs/mir2/list"));
        pageRanks.add(new PageRank(2, "/bbs/mir3/list"));
        pageRanks.add(new PageRank(3, "/bbs/changchun2/list"));
        return new ModelAndView("pageReport","pageRanks",pageRanks);
    }
}

    madvirus.spring.chap07.view
           DownloadView *2
package madvirus.spring.chap07.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.view.AbstractView;

public class DownloadView extends AbstractView {

    public DownloadView() {
        setContentType("application/download; charset=utf-8");
    }
       
    @Override
    protected void renderMergedOutputModel(Map<String, Object> model,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        File file = (File) model.get("downloadFile");

        response.setContentType(getContentType());
        response.setContentLength((int) file.length());

        String userAgent = request.getHeader("User-Agent");
        boolean ie = userAgent.indexOf("MSIE") > -1;
        String fileName = null;
        if (ie) {
            fileName = URLEncoder.encode(file.getName(), "utf-8");
        } else {
            fileName = new String(file.getName().getBytes("utf-8"),
                    "iso-8859-1");
        }
        response.setHeader("Content-Disposition", "attachment; filename=\""
                + fileName + "\";");
        response.setHeader("Content-Transfer-Encoding", "binary");
        OutputStream out = response.getOutputStream();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            FileCopyUtils.copy(fis, out);
        } finally {
            if (fis != null)
                try {
                    fis.close();
                } catch (IOException ex) {
                }
        }
        out.flush();
    }
}

           PageRanksView *4 - 엑셀파일
package madvirus.spring.chap07.view;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import madvirus.spring.chap07.controller.PageRank;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.web.servlet.view.document.AbstractExcelView;

public class PageRanksView extends AbstractExcelView {

    //@SuppressWarnings("unchecked") : 문법에 문제가없는데 나오는 노란줄 경고 안나오게함
    @SuppressWarnings("unchecked")
    @Override
    protected void buildExcelDocument(Map<String, Object> model,
            HSSFWorkbook workbook, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        HSSFSheet sheet = createFirstSheet(workbook);
        createColumnLabel(sheet);

        List<PageRank> pageRanks = (List<PageRank>) model.get("pageRanks");
        int rowNum = 1;
        for (PageRank rank : pageRanks) {
            createPageRankRow(sheet, rank, rowNum++);
        }
    }

    private HSSFSheet createFirstSheet(HSSFWorkbook workbook) {
        HSSFSheet sheet = workbook.createSheet();
        workbook.setSheetName(0, "페이지 순위");
        sheet.setColumnWidth(1, 256 * 20);
        return sheet;
    }

    private void createColumnLabel(HSSFSheet sheet) {
        HSSFRow firstRow = sheet.createRow(0);
        HSSFCell cell = firstRow.createCell(0);
        cell.setCellValue("순위");

        cell = firstRow.createCell(1);
        cell.setCellValue("페이지");
    }

    private void createPageRankRow(HSSFSheet sheet, PageRank rank, int rowNum) {
        HSSFRow row = sheet.createRow(rowNum);
        HSSFCell cell = row.createCell(0);
        cell.setCellValue(rank.getRank());

        cell = row.createCell(1);
        cell.setCellValue(rank.getPage());

    }
}

           PageReportView *4 - pdf파일
package madvirus.spring.chap07.view;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import madvirus.spring.chap07.controller.PageRank;

import org.springframework.web.servlet.view.document.AbstractPdfView;

import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;

public class PageReportView extends AbstractPdfView {

    @SuppressWarnings("unchecked")
    @Override
    protected void buildPdfDocument(Map<String, Object> model,
            Document document, PdfWriter writer, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        List<PageRank> pageRanks = (List<PageRank>) model.get("pageRanks");
        Table table = new Table(2, pageRanks.size() + 1);
        table.setPadding(5);

        BaseFont bfKorean = BaseFont.createFont(
                "c:\\windows\\fonts\\batang.ttc,0", BaseFont.IDENTITY_H,
                BaseFont.EMBEDDED);

        Font font = new Font(bfKorean);
        Cell cell = new Cell(new Paragraph("순위", font));
        cell.setHeader(true);
        table.addCell(cell);
        cell = new Cell(new Paragraph("페이지", font));
        table.addCell(cell);
        table.endHeaders();

        for (PageRank rank : pageRanks) {
            table.addCell(Integer.toString(rank.getRank()));
            table.addCell(rank.getPage());
        }
        document.add(table);
    }
}

     messages
           label_en.properties *1
login.form.title=Login Form
login.form.type=Login Type
login.form.id=ID
login.form.password=Password
login.form.submit=Login

           label.properties *1
login.form.title=로그인
login.form.type=로그인 타입
login.form.id=회원Id
login.form.password=비밀번호
login.form.submit=전송

           validation_en.properties *1
required=required
required.login.id=login id is required
required.login.password=login password is requreid
required.login.loginType=You have to select login type
invalidIdOrPassword.login=Login id and password do not match. (You provided {0})

           validation.properties *1
required=필수입니다.
required.login.id=ID는 필수입니다.
required.login.password=비밀번호는 필수입니다.
required.login.loginType=로그인 타입을 선택하세요.
invalidIdOrPassword.login=당신이 입력한 id {0}. 로그인 아이디와 비밀번호가 일치하지 않습니다.

WebContent
      viewjsp
           loginForm.jsp *1
<%@ page contentType="text/html; charset=EUC-KR" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title><spring:message code="login.form.title"/></title>
</head>
<body>
<form:form commandName="login">
<form:errors />
<p>                       
    <label for="loginType"><spring:message code="login.form.type" /></label>
    <form:select path="loginType" items="${loginTypes}" />
</p>
<p>
    <label for="id"><spring:message code="login.form.id" /></label>
    <form:input id="id" path="id"/>
    <form:errors path="id" />
</p>
<p>
    <label for="password"><spring:message code="login.form.password" /></label>
    <form:password id="password" path="password"/>
    <form:errors path="password" />
</p>
<p>
    <input type="submit" value="<spring:message code="login.form.submit" />">
</p>
</form:form>
</body>
</html>

           loginSuccess.jsp *1
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>로그인 성공</title>
</head>
<body>
로그인에 성공했습니다.
</body>
</html>

      dispatcherInternal-servlet.xml *1
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    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-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 커스텀태그이용 -->
    <bean class="madvirus.spring.chap07.controller.LoginController">
        <property name="authenticator">
            <bean class="madvirus.spring.chap07.controller.MockAuthenticator"/>
        </property>
    </bean>   
   
    <!-- 국제화 -->
    <bean class="madvirus.spring.chap07.controller.LocaleChangeController">
        <property name="localeResolver" ref="localeResolver"/>
    </bean>
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
   
    <!-- 국제화2 -->
    <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="language"/>
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="localeChangeInterceptor"/>
            </list>
        </property>
    </bean>
   
    <!-- View 글로벌 설정 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/viewjsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
   
    <!-- 리소스 번들 지정 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>messages.validation</value>
                <value>messages.label</value>
            </list>
        </property>   
    </bean>
</beans>

      dispatcherNonHtml-servlet.xml *2
<?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-3.0.xsd">

    <!-- 파일 다운로드 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
    <bean id="downloadController" class="madvirus.spring.chap07.controller.DownloadController"/>
    <bean id="download" class="madvirus.spring.chap07.view.DownloadView"></bean>
   
   
    <!-- 엑셀 다운로드 -->
    <bean id="pageRanksController" class="madvirus.spring.chap07.controller.PageRanksController" />
    <bean id="pageRanks" class="madvirus.spring.chap07.view.PageRanksView" />

    <!-- PDF 다운로드 -->
    <bean id="pageReportController" class="madvirus.spring.chap07.controller.PageReportController" />
    <bean id="pageReport" class="madvirus.spring.chap07.view.PageReportView"/>
   
    </beans>      

      web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>false</param-value>
  </context-param>
  <servlet>
    <servlet-name>dispatcherInternal</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherInternal</servlet-name>
    <url-pattern>/jsp/*</url-pattern>
  </servlet-mapping>
   <servlet>
    <servlet-name>dispatcherNonHtml</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherNonHtml</servlet-name>
    <url-pattern>/download/*</url-pattern>
  </servlet-mapping>
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

설명.txt
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>View 연습</title>
</head>
<body>
<a href="http://localhost:8080/chap07/jsp/login/login.do">LoginController </a><br>
<a href="http://localhost:8080/chap07/download/file">DownloadController - 파일 다운로드</a><br>
<a href="http://localhost:8080/chap07/jsp/changLanguage?lang=ko">LocaleChangeController -1 한글</a><br>
<a href="http://localhost:8080/chap07/jsp/changLanguage?lang=en">LocaleChangeController -2 영어</a><br>
<a href="http://localhost:8080/chap07/jsp/login/login.do?language=ko">LocaleChangeInterceptor -1 한글</a><br>
<a href="http://localhost:8080/chap07/jsp/login/login.do?language=en">LocaleChangeInterceptor -2 영어</a><br>
<a href="http://localhost:8080/chap07/download/pageRanks">PageRanksController - 엑셀파일  다운로드</a><br>
<a href="http://localhost:8080/chap07/download/pageReport">PageReportController - PDF파일  다운로드</a><br>
</body> 
</html>

===============================결과값====================================

1.로그인 테스트


en_US


ko_KR


2.다운로드


3. 국제화 LocaleReslover를 이용한 Locale 변경


국제화 LocaleChangeInterceptor


4.엑셀파일 다운로드 , PDF 다운로드





'스프링3.0' 카테고리의 다른 글

Spring3.0 Tiles  (1) 2012.05.14
Spring3.0 DB  (0) 2012.05.14
Spring3.0 MVC 웹요청 처리  (0) 2012.05.14
Spring 3.0 AOP  (0) 2012.05.14
Spring3.0 DI 3  (0) 2012.05.14
Posted by 사라링

프로젝트 기본설정상태

완료파일

=====================


스프링 MVC를 이용한 웹 요청 처리


=================================이론=====================================

스프링의 MVC의 주요 구성요소
DispatcherServlet : Struts2의 컨트롤러 :
HandlerMapping :
컨트롤러(Controller) : Struts2의 액션 :
ModelAndView :
뷰(View) :


실행 흐름 정리 : http://javai.tistory.com/561

웹브라우저 hello.do -> Dispatcher : DispatcherServlet
컨트롤러 요청 DefaultAnnotationHandlerMapping
HelloController 빈 리턴 -> Dispatcher : DispatcherServlet
처리요청 HelloController -> 모델뷰 리턴 -> Dispatcher : DispatcherServlet
hello에 매칭되는 View 객체 요청 ViewResolver : InternalResourceViewResolver 뷰 리턴 -> Dispatcher : DispatcherServlet
응답 생성 요청 -> InternalResourceView -> JSP를 이용하여 응답생성 -> hello.jsp

Dispatcher : DispatcherServlet 가 모든것을 컨트롤 하는것을 알 수 있다(Struts2의 Controller와 같은 역할)


커맨드 객체로 List 받기
자바빈->ArrayList넣기

컨트롤러 메서드의 파라미터 타입


1.@RequestParam 이용한 파라미터 매핑
필수가 아닌 파라미터의 경우 required 속성값을 false로 지정(기본값이 true)

@Controller
public class SearchController {
   
    @RequestMapping("/search/internal.do")
    public ModelAndView searchInternal(@RequestParam("query") String query, @RequestParam(value = "p", defaultValue = "1")int pageNumber){               //메서드명은 마음대로
        System.out.println("query="+query+",pageNumber"+pageNumber);
       
        return new ModelAndView("search/internal");
    }

    @RequestMapping("/search/external.do")
    public ModelAndView searchExternal(@RequestParam(value="query", required=false)String query,@RequestParam(value="p",defaultValue = "1")int pageNumber){   //메서드명은 마음대로
        System.out.println("query="+query+",pageNumber"+pageNumber);
   
    return new ModelAndView("search/external");
    }
}

dispatcher-servlet.xml 설정
    <!-- 파라미터로 전송된 데이터 처리 -->
    <bean id="searchController" class="madvirus.spring.chap06.controller.SearchController"/>


2.@CookieValue 어노테이션을 이용한 쿠키 매핑

필수가 아닌 쿠키의 경우 required 속성값을 false로 지정(기본값이 true)

@Controller
public class CookieController {
    @RequestMapping("/cookie/make.do")
    public String make(HttpServletResponse response){
        response.addCookie(new Cookie("auth", "1"));
        return "cookie/made";
    }

    //@CookieValue 어노테이션은 클라이언트가 제공하는 쿠키정보를 읽어드림
    @RequestMapping("/cookie/view.do")
    public String view(@CookieValue(value ="auth", defaultValue="0") String auth){
        System.out.println("auth 쿠기 : " + auth);
        return "cookie/view";
    }
}

<!-- @CookieValue 어노테이션을 이용한 쿠키 매핑 -->
<bean id="cookieController" class="madvirus.spring.chap06.controller.CookieController"/>


@RequestMappign(요청URL)

public [return 타입 P231] process([파라미터 타입 P225]  )

return 타입 - 1. ModelAndView :  View,View 개체
                   2. String : View
                   3. Map,Model : 키와 값을 쌍으로 저장할때

5.예제 @RequestHeader
 


@ModelAttribute 검색



Validator인터페이스를 이용한 폼 값 검증



예제9
restful 서비스

http://localhost:8080/chap06/index.do?id=dragon => http://localhost:8080/chap06/index/id/dragon




===============================프로젝트===================================


=================================코드=====================================
chap06
      src
          madvirus.spring.chap06.controller
              ArithmeticOperatorController (11.예제 예외페이지)
package madvirus.spring.chap06.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class ArithmeticOperatorController {

    @RequestMapping("/math/divide.do")
    public String divide(@RequestParam("op1") int op1, @RequestParam("op2") int op2, Model model){
        model.addAttribute("result", op1 / op2);
       
        return "math/result";
    }
}

              CharacterInfoController (9.예제 restful서비스)
package madvirus.spring.chap06.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CharacterInfoController {
   
    @RequestMapping("/game/users/{userId}/characters/{characterId}")
    public String characterInfo(@PathVariable String userId, @PathVariable int characterId, ModelMap model){
        model.addAttribute("userId",userId);
        model.addAttribute("characterId", characterId);
        return "game/character/info";
       
    }   
}

              CookieController (4.예제 @CookieValue)
package madvirus.spring.chap06.controller;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CookieController {
    @RequestMapping("/cookie/make.do")
    public String make(HttpServletResponse response){
        response.addCookie(new Cookie("auth", "1"));
        return "cookie/made"; //View 경로
    }

    //@CookieValue 어노테이션은 클라이언트가 제공하는 쿠키정보를 읽어드림
    @RequestMapping("/cookie/view.do")
    public String view(@CookieValue(value ="auth", defaultValue="0") String auth){
        System.out.println("auth 쿠기 : " + auth);
        return "cookie/view";
    }
}

              CreateAccountController (7.예제)
package madvirus.spring.chap06.controller;

import javax.servlet.http.HttpServletRequest;

import madvirus.spring.chap06.model.Address;
import madvirus.spring.chap06.model.MemberInfo;
import madvirus.spring.chap06.validator.MemberInfoValidator;

import org.springframework.jmx.export.assembler.AutodetectCapableMBeanInfoAssembler;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/account/create.do")
public class CreateAccountController {

    //Command 객체 초기화
    @ModelAttribute("command")
    public MemberInfo formBacking(HttpServletRequest request){
        //equalsIgnoreCase : 대소문자 관계없이 비교해줌 단!영문만 가능
        if(request.getMethod().equalsIgnoreCase("GET")){
            MemberInfo mi = new MemberInfo();
            Address address= new Address();
            address.setZipcode(autoDetectZipcode(request.getRemoteAddr()));
            mi.setAddress(address);
            return mi;
        }else{
            return new MemberInfo();
        }
    }
   
    private String autoDetectZipcode(String remoteAddr){
        return "000000";
    }
   
    @RequestMapping(method = RequestMethod.GET)
    public String form(){
        return "account/creationForm";
    }
   
    @RequestMapping(method = RequestMethod.POST)
    public String submit(@ModelAttribute("command")MemberInfo memberInfo,BindingResult result){
       
        new MemberInfoValidator().validate(memberInfo, result);
       
        if(result.hasErrors()){
            return "account/creationForm";
        }
        return "account/created";
    }
}

              GameInfoController (8.예제)
package madvirus.spring.chap06.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class GameInfoController {
   
    //@RequestMapping("/game/info") /game/* 를 탈려면 /game을 하면안됨
    /*  /game/info 로 쓰기위해서는
    <!-- 요청 URI 매칭  -->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="alwaysUseFullPath" value="true"/>
    </bean>   
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="alwaysUseFullPath" value="true"/>
    </bean>
    */
    @RequestMapping("/game/info")
    public String gameInfo(){
        return "game/info";
    }
   
    @RequestMapping("/game/list")
    public String gameList(){
        return "game/list";
    }
}

             GameSearchController (6.예제)
package madvirus.spring.chap06.controller;

import java.util.ArrayList;
import java.util.List;

import madvirus.spring.chap06.service.SearchCommand;
import madvirus.spring.chap06.service.SearchResult;
import madvirus.spring.chap06.service.SearchService;
import madvirus.spring.chap06.service.SearchType;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class GameSearchController {

    @Autowired
    private SearchService searchService;
   
    @ModelAttribute("searchTypeList")
    public List<SearchType> referenceSearchTypeList(){
        List<SearchType> options = new ArrayList<SearchType>();
        options.add(new SearchType(1, "전체"));
        options.add(new SearchType(2, "아이템"));
        options.add(new SearchType(3, "캐릭터"));
        return options;       
    }
   
    @ModelAttribute("popularQueryList")
    public String[] getPopularQueryList(){
        return new String[]{"게임","창천2","위메이드"};
    }
   
    @RequestMapping("/search/main.do")
    public String main(){
        return "search/main";
    }
   
    @RequestMapping("/search/game.do")
    public ModelAndView search(@ModelAttribute("command") SearchCommand command){
        ModelAndView mav = new ModelAndView("search/game");
       
        System.out.println("검색어 : " + command.getQuery().toUpperCase());
       
        SearchResult result = searchService.search(command);
        mav.addObject("searchResult",result);
       
        return mav;
    }
   
    @ExceptionHandler(NullPointerException.class)
    public String handleNullPointerException(NullPointerException ex){
        return "error/nullException";
    }
   
    public void setSearchService(SearchService searchService){
        this.searchService = searchService;
    }
}

              HeaderController (5.예제 @RequestHeader)
package madvirus.spring.chap06.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HeaderController {

   
    //@RequestHeader 어노테이션은 클라이언트가 전송한 해더 정보 읽기
    @RequestMapping("/header/check.do")
    public String check(
            @RequestHeader("Accept-Language") String languageHeader){
        System.out.println(languageHeader);
       
        return "header/pass";
    }
}

              HelloController (1.예제) - 스프링의 컨트롤러는 Struts2의 액션
package madvirus.spring.chap06.controller;

import java.util.Calendar;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

//컨트롤러 (Struts2 의 Action과 동일)을 구현하기 위해 @Controller 명시
@Controller
public class HelloController {

    //클라이언트의 요청에 대해 호출되는 메소드 지정
    @RequestMapping("/hello.do")
    public ModelAndView hello(){ //메소드명은 마음대로
        //View에 정보를 전달하기 위해 ModelAndView 객체 생성
        ModelAndView mav = new ModelAndView();
        //View의 이름 지정
        mav.setViewName("hello");
        //View에 사용할 데이터 저장
        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 "안녕하세요";
    }   
}

              NewArticleController (2.예제)
package madvirus.spring.chap06.controller;

import madvirus.spring.chap06.service.ArticleService;
import madvirus.spring.chap06.service.NewArticleCommand;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/*스탠다드 포맷 */


//컨트롤러 설정
@Controller
//클라이언트의 요청에 대해서 호출하는 메서드 지정
@RequestMapping("/article/newArticle.do")
public class NewArticleController {
   
    @Autowired
    private ArticleService articleService;
   
    @RequestMapping(method = RequestMethod.GET)
    public String form(){ //메소드가 지정되어 있는것은 아니지만 일반적으로 사용하는 명칭
        //리턴값은 View설정
        //글로벌설정이 /WEB-INF/view/ 이라  맨앞에/없음
        return "article/newArticleForm";
    }

    @RequestMapping(method = RequestMethod.POST)
                        //Command(자바빈) 클래스 설정)
    public String submit(@ModelAttribute("command") NewArticleCommand command){
        articleService.writeArticle(command);
        //리턴값은 View설정
        return "article/newArticleSubmitted";
    }
   
    public void setArticleService(ArticleService articleService){
        this.articleService =articleService;
    }   
}

              SearchController (3.예제 @RequestParam)
package madvirus.spring.chap06.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class SearchController {
   
    @RequestMapping("/search/internal.do")
    public ModelAndView searchInternal(@RequestParam("query") String query, @RequestParam(value = "p", defaultValue = "1")int pageNumber){
        System.out.println("query="+query+",pageNumber"+pageNumber);
       
        return new ModelAndView("search/internal");
    }
   
    @RequestMapping("/search/external.do")
    public ModelAndView searchExternal(@RequestParam(value="query", required=false)String query,@RequestParam(value="p",defaultValue = "1")int pageNumber){
        System.out.println("query="+query+",pageNumber"+pageNumber);
   
    return new ModelAndView("search/external");
    }
}

          SubmitReportController (10.예제 파일업로드)
package madvirus.spring.chap06.model;

import org.springframework.web.multipart.MultipartFile;

//스프링의 Command = 자바빈
public class SubmitReportCommand {

    private String subject;
    private MultipartFile reportFile;
   
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public MultipartFile getReportFile() {
        return reportFile;
    }
    public void setReportFile(MultipartFile reportFile) {
        this.reportFile = reportFile;
    }   
}

          madvirus.spring.chap06.model
              Address (예제7. Command클래스)
package madvirus.spring.chap06.model;

public class Address {
    private String zipcode;
    private String address1;
    private String address2;
   
    public String getZipcode() {
        return zipcode;
    }
    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }
    public String getAddress1() {
        return address1;
    }
    public void setAddress1(String address1) {
        this.address1 = address1;
    }
    public String getAddress2() {
        return address2;
    }
    public void setAddress2(String address2) {
        this.address2 = address2;
    }
}

              MemberInfo (7.예제)
package madvirus.spring.chap06.model;

public class MemberInfo {

    private String id;
    private String name;
    private Address address;
   
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }   
}

             SubmitReportCommand (10.예제 파일업로드)
package madvirus.spring.chap06.model;

import org.springframework.web.multipart.MultipartFile;

//스프링의 Command = 자바빈
public class SubmitReportCommand {

    private String subject;
    private MultipartFile reportFile;
   
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public MultipartFile getReportFile() {
        return reportFile;
    }
    public void setReportFile(MultipartFile reportFile) {
        this.reportFile = reportFile;
    }   
}

          madvirus.spring.chap06.service
             ArticleService (2.예제)
package madvirus.spring.chap06.service;

public class ArticleService {

    public void writeArticle(NewArticleCommand command) {
        System.out.println("신규 게시글 등록: " + command);
    }
}

              NewArticleCommand (2.예제)
package madvirus.spring.chap06.service;

// *Command = 자바빈과 같은 기능  Command라 부른다.
public class NewArticleCommand {

    private String title;
    private String content;
    private int parentId;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getParentId() {
        return parentId;
    }

    public void setParentId(int parentId) {
        this.parentId = parentId;
    }

    @Override
    public String toString() {
        return "NewArticleCommand [content=" + content + ", parentId="
                + parentId + ", title=" + title + "]";
    }
}

             SearchCommand (6.예제)
package madvirus.spring.chap06.service;
//자바빈
public class SearchCommand {

    private String type;
    private String query;
    private int page;
   
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getQuery() {
        return query;
    }
    public void setQuery(String query) {
        this.query = query;
    }
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }   
}

             SearchResult (6.예제)
package madvirus.spring.chap06.service;

public class SearchResult {

}

             SearchService (6.예제)
package madvirus.spring.chap06.service;

public class SearchService {

    //SearchCommand 객체를 받는거
    public SearchResult search(SearchCommand command){
        return new SearchResult();
    }
}

             SearchType (6.예제)
package madvirus.spring.chap06.service;

public class SearchType {
   
    private int code;
    private String text;   
   
    public SearchType(int code, String text) {
        super();
        this.code = code;
        this.text = text;
    }
   
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }   
}

          madvirus.spring.chap06.validator
             MemberInfoValidator (7.예제 검증)
package madvirus.spring.chap06.validator;

import madvirus.spring.chap06.model.Address;
import madvirus.spring.chap06.model.MemberInfo;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class MemberInfoValidator implements Validator{

    //Validator가 해당 클래스에 대한 값 검증을 지원하는지 여부를 리턴
    @Override
    public boolean supports(Class<?> clazz) {
        return MemberInfo.class.isAssignableFrom(clazz);
    }

    //target객체에 대한 검증을 실행
    @Override
   
    public void validate(Object target, Errors errors) {
        MemberInfo memberInfo = (MemberInfo)target;
        if(memberInfo.getId()==null|| memberInfo.getId().trim().isEmpty()){
            errors.rejectValue("id","required");
        }
        if(memberInfo.getName()==null || memberInfo.getName().trim().isEmpty()){
            errors.rejectValue("name", "required");
        }
        Address address = memberInfo.getAddress();
        if(address == null){
            errors.rejectValue("address", "required");
        }
        if(address != null){
            errors.pushNestedPath("address");
            try{
                if(address.getZipcode() == null || address.getZipcode().trim().isEmpty()){
                    errors.rejectValue("zipcode", "required");
                }
                if(address.getAddress1()==null || address.getAddress1().trim().isEmpty()){
                    errors.rejectValue("address1", "required");
                }
            }finally{
                errors.popNestedPath();
            }
        }       
    }   
}

             SubmitReportValidator (10.예제 파일업로드)
package madvirus.spring.chap06.validator;

import madvirus.spring.chap06.model.MemberInfo;
import madvirus.spring.chap06.model.SubmitReportCommand;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class SubmitReportValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {

        return SubmitReportCommand.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
       
        //방식1.데이터가 없는경우 돌려보냄
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "subject", "required");
       
        SubmitReportCommand command = (SubmitReportCommand)target;
       
        //방식2. 일반적인방법
        if(command.getReportFile() ==null || command.getReportFile().isEmpty())
            errors.rejectValue("reportFile", "required");
    }
}

          message
             validation.properties (7예제. 설정파일)
required=필수 항목입니다.
invalidIdOrPassword.logincommand=아이디({0})와 암호가 일치하지 않습니다.
required.loginCommand.userId=사용자 아이디는 필수 항목입니다.
required.password=암호는 필수 항목입니다.
typeMismatch.from=시작일 값 형식은 yyyy-MM-dd 여야 합니다.
typeMismatch.to=종료일 값 형식은 yyyy-MM-dd 여야 합니다.

      WebContent
          WEB-INF
              lib (스프링 다이나믹웹 프로젝트 라이브러리)         
          upload
          view
              account
                  created.jsp (7.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>계정 생성</title>
</head>
<body>
계정 생성됨
<ul>
 <li>아이디: ${command.id}</li>
 <li>이름: ${command.name}</li>
 <li>우편번호: ${command.address.zipcode}</li>
 <li>주소: ${command.address.address1} ${command.address.address2}</li>
</ul>
</body>
</html> 

                  creationForm.jsp (7.예제)
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>계정 생성</title>
</head>
<body>
<!-- 에러메세지를 처리하귀해서 Spring 사용 -->
<spring:hasBindErrors name="command" />
<form:errors path="command" />
<form method="post">
    아이디: <input type="text" name="id" value="${command.id}" />
    <form:errors path="command.id" />
    <br/>
    이름: <input type="text" name="name" value="${command.name}" />
    <form:errors path="command.name" />
    <br/>
    우편번호: <input type="text" name="address.zipcode" value="${command.address.zipcode}" />
    <form:errors path="command.address.zipcode" />
    <br/>
    주소1: <input type="text" name="address.address1" value="${command.address.address1}" />
    <form:errors path="command.address.address1" />
    <br/>
    주소2: <input type="text" name="address.address2" value="${command.address.address2}" />
    <form:errors path="command.address.address2" />
    <br/>
    <input type="submit" />
</form>
</body>
</html>

              article
                  newArticleForm.jsp (2.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글 쓰기</title>
</head>
<body>
게시글 쓰기 입력 폼:
<form method="post">
    <input type="hidden" name="parentId" value="0" />
    제목: <input type="text" name="title" /><br/>
    내용: <textarea name="content"></textarea><br/>
    <input type="submit" />
</form>
</body>
</html>

                  newArticleSubmitted.jsp (2.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글 쓰기</title>
</head>
<body>
게시글 등록됨:
<br/>
제목: ${command.title}
</body>
</html>

              cookie
                  made.jsp (4.예제 @CookieValue)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>쿠키</title>
</head>
<body>
쿠키 생성함
</body>
</html>

                  view.jsp (4.예제 @CookieValue)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>쿠키</title>
</head>
<body>
쿠키 확인
</body>
</html>

              error (에러체크)
                  exception.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>예외 발생</title>
</head>
<body>
요청을 처리하는 도중에 예외가 발생하였습니다:
${exception.message}
<%
    Throwable e = (Throwable) request.getAttribute("exception");
    e.printStackTrace();
%>
</body>
</html>

                  mathException.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>예외 발생</title>
</head>
<body>
연산 과정에서 예외가 발생하였습니다.
</body>
</html>

                  nullException.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>예외 발생</title>
</head>
<body>
요청을 처리하는 과정에서 예외(null)가 발생하였습니다.
</body>
</html>

              game
                  character
                           info.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>호출 테스트</title>
</head>
<body>
[info] 호출 가능
</body>
</html>

                  info.jsp (8.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>호출 테스트</title>
</head>
<body>
[info] 호출 가능
</body>
</html>

                   ist.jsp (8.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>호출 테스트</title>
</head>
<body>
[list]호출 가능
</body>
</html>

              header
                  pass.jsp (5.예제 @RequestHeader)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>헤더 검사 통과</title>
</head>
<body>
헤더 검사 통과
</body>
</html>
           
              math
                  result.jsp (11.예제 예외페이지)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>연산 성공</title>
</head>
<body>
연산 성공
</body>
</html>

              report
                  submitReportForm.jsp (10.예제 파일업로드)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>리포트 등록 폼</title>
</head>
<body>
<spring:hasBindErrors name="report"/>
<form action="submitReport.do" method="post" enctype="multipart/form-data">
<p>
    <label for="subject">제목</label>
    <input type="text" id="subject" name="subject" value="${report.subject}">
    <form:errors path="report.subject"/>
</p>
<p>
    <label for="reportFile">리포트파일</label>
    <input type="file" id="reportFile" name="reportFile">
    <form:errors path="report.reportFile"/>
</p>
<p>
    <input type="submit" vlaue="리포트전송">
<p>
</body>
</html>

                  submittedReport.jsp (10.예제 파일업로드)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>리포트 등록 완료</title>
</head>
<body>
리포트 '${report.subject}'를 동록했습니다.
</body>
</html>      

              search
                  external.jsp (3.예제 @RequestParam)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>외부 검색</title>
</head>
<body>
외부 검색
</body>
</html>

                  game.jsp (6.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게임 검색결과</title>
</head>
<body>
인기 키워드 : <c:forEach var="popualrQuery" items="${popularQueryList}">${popularQuery}></c:forEach>
<form action="game.do">
<select name="type">
    <c:forEach var="searchType" items="${searchTypeList}">
        <option value="${serchType.code}"<c:if test="${command.type == searchType.code}">selected</c:if>>${searchType.text}</option>
    </c:forEach>
</select>
<input type="text" name="query" value="${command.query}"/>
<input type="submit" value="검색"/>
</form>
검색결과 : ${searchResult}
</body>
</html>

                  internal.jsp (3.예제 @RequestParam)  
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>내부 검색</title>
</head>
<body>
내부 검색
</body>
</html>

                  main.jsp (6.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게임 검색 메인</title>
</head>
<body>
인기 키워드 : <c:forEach var="popualrQuery" items="${popularQueryList}">${popualrQuery}></c:forEach>
<form action="game.do">
<select name="type">
    <c:forEach var="searchType" items="${searchTypeList}">
        <option value="${serchType.code}">${searchType.text}</option>
    </c:forEach>
</select>
<input type="text" name="query" value=""/>
<input type="submit" value="검색"/>
</form>
</body>  
</html>

              hello.jsp (1.예제)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>인사</title>
</head>
<body>
인사말 :<strong>${greeting}</strong>
</body>
</html>

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

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    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-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config/>
   
    <!-- 기본설정 -->
    <bean id="helloController" class="madvirus.spring.chap06.controller.HelloController"/>
   
    <!-- 데이터를 전송하여 자바빈에 담기 -->
    <!-- <bean id="newArticleController" class="madvirus.spring.chap06.controller.NewArticleController" p:articleService-ref="articleService" /> -->
    <bean id="newArticleController" class="madvirus.spring.chap06.controller.NewArticleController"/>
   
    <bean id="articleService" class="madvirus.spring.chap06.service.ArticleService" />
   
    <!-- 파라미터로 전송된 데이터 처리 -->
    <bean id="searchController" class="madvirus.spring.chap06.controller.SearchController"/>
   
    <!-- @CookieValue 어노테이션을 이용한 쿠키 매핑 -->
    <bean id="cookieController" class="madvirus.spring.chap06.controller.CookieController"/>
   
    <!-- @RequestHeader 어노테이션을 이용한 쿠키 매핑 -->
    <bean class="madvirus.spring.chap06.controller.HeaderController"/>
       
    <!-- 뷰에 모델 데이터 전달하기 -->
    <bean class="madvirus.spring.chap06.controller.GameSearchController"/>
    <bean id="searchService" class="madvirus.spring.chap06.service.SearchService"/>
   
    <!-- 커멘드 객체 초기화 -->
    <bean class="madvirus.spring.chap06.controller.CreateAccountController"/>
   
    <!-- 요청 URI 매칭  -->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="alwaysUseFullPath" value="true"/>
    </bean>   
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="alwaysUseFullPath" value="true"/>
    </bean>
    <bean class="madvirus.spring.chap06.controller.GameInfoController"/>
   
    <!-- @PathVariable 어노테이션을 이용한 URI 템플릿 -->
    <bean class="madvirus.spring.chap06.controller.CharacterInfoController"></bean>
   
    <!-- 파일 업로드 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="104857600"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>
    <bean class="madvirus.spring.chap06.controller.SubmitReportController"/>
   
    <!-- 예외처리 -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArithmeticException">
                    error/mathException
                </prop>
                <prop key="java.lang.Exception">
                    error/exception
                </prop>
            </props>
        </property>
    </bean>   
    <bean class="madvirus.spring.chap06.controller.ArithmeticOperatorController"/>
   
    <!-- View 글로벌 설정  -->
    <bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
   
    <!-- 리소스 번들 지정 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>messages.validation</value>
            </list>
        </property>
    </bean>
   
</beans>

          web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
 
 <!-- 기본 설정 --> <!-- DispatcherServlet -->
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
    <url-pattern>/game/*</url-pattern>
  </servlet-mapping>
  <!-- 캐릭터 인코딩 -->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

index.jsp (메인 링크페이지)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>예제 요청 URL</title>
</head>
<body>
<a href="http://localhost:8080/chap06/hello.do">HelloController</a><br/>
<a href="http://localhost:8080/chap06/article/newArticle.do">NewArticleController</a><br/>
<a href="http://localhost:8080/chap06/search/internal.do?query=spring">SearchController - 1</a><br/>
<a href="http://localhost:8080/chap06/search/external.do">SearchController - 2</a><br/>
<a href="http://localhost:8080/chap06/cookie/make.do">쿠키 생성</a><br/>
<a href="http://localhost:8080/chap06/cookie/view.do">쿠키값 읽기</a><br/>
<a href="http://localhost:8080/chap06/header/check.do">헤더정보 읽기</a><br/>
<a href="http://localhost:8080/chap06/search/main.do">GameSearchController</a><br/>
<a href="http://localhost:8080/chap06/account/create.do">CreateAccountController</a><br/>
<a href="http://localhost:8080/chap06/game/info.do">GameInfoController -1</a><br/>
<a href="http://localhost:8080/chap06/game/list.do">GameInfoController -2</a><br/>
<a href="http://localhost:8080/chap06/game/users/dragon/characters/1">CharacterInfoController</a><br/>
<a href="http://localhost:8080/chap06/report/submitReport.do">파일업로드 SubmitReportController</a><br/>
<a href="http://localhost:8080/chap06/math/divide.do?op1=3&op2=0">예외발생</a><br/>
<a href="http://localhost:8080/chap06/math/divide.do?op1=4&op2=2">연산성공</a><br/>
</body>      
</html>                                                                

=================================결과값====================================

1.예제

2.예제


3.예제 @RequestParam



4.예제 @CookieValue

5.예제 @RequestHeader

6.예제 @ModelAttribute 검색


7.예제 : Validator인터페이스를 이용한 폼 값 검증


8.예제 :



9.예제 restful서비스

10.예제 파일업로드
파일없이 쿼리전송시

11예제. 예외페이지


'스프링3.0' 카테고리의 다른 글

Spring3.0 DB  (0) 2012.05.14
Spring3.0 View error filedown  (0) 2012.05.14
Spring 3.0 AOP  (0) 2012.05.14
Spring3.0 DI 3  (0) 2012.05.14
스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Posted by 사라링

Spring 3.0 AOP

2012. 5. 14. 19:10


05. 스프링 AOP




AOP(Aspect Oriented Programming)
 - 문제를 바라보는 관점을 기준으로 프로그래밍하는 기법
 - 문제를 해결하기 위한 핵심 관심 사항과 전체에 적용되는 공통 관심 사항을 기준으로 프로그래밍 함으로써 공통 모듈을 여러 코드에 쉽게 적용

공통관심사항 (cross-cutting concern)
어플리케이션에서 로깅과 같은 기본적인 기능에서부터 트랙잭션이나 보안과 같은 기능에 이르기까지 어플리케이션 전반에걸쳐 적용되는 공통기능이

핵심로직을 핵심 관심 사항(core concern) 이라고 표현.




* AOP용어 *



Advice    : 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의
Joinpoint : Advice를 적용 가능한 지점을 의미 (메서드호출, 필드값 변경 등)
Pointcut  :  Joinpoint의 부분집합(그룹화)  실제로 Advice가 Joinpoint  적용된 스프링 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의 할 수있다.
Weaving  : Advice를 핵심 로직 코드에 적용하는것
Aspect   :  공통관심사항


세가지 Weaving 방식

 - 컴파일 시에  Weaving 하기
 - 클래스 로딩시에 Weaving 하기
 - 런타임 시에 Weaving 하기


스프링에서의 AOP
스프링은 자체적으로 프록시 기반의 AOP를 지원한다 따라서 스프링 AOP는 메서드호출 Joinpoint만을 지원하고 필드값변경같은 Joinpoint를 사용하기 위해서는 AspectJ와 같이 풍부한 기능을 지원하느 AOP 도구를 사용

스프링은 세가지 방식으로 AOP구현
 - XML 스키마 기반의 POJO클래스를 이용한 AOP 구현
 - AspectJ 5/6에서 정의한 @Aspect 어노테이션 기반의 AOP구현
 - 스프링 API를 이용한 AOP 구현 (많이사용하지는 않음)


Advice    : 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의

Advice 정의 관련태그
<aop:before>            : 메서드 실행전에 적용되는 Advice를 정의
<aop:after-returning> : 메서드가 정상적으로 실행된 후에 적용되는 Advice를 정의
<aop:throwing>         : 예외를 발생시킬 때 적용되는 Advice를 정의 (catch와 비슷)
<aop:after>              : 예외 여부와 상관없는 Advice를 정의한다 (finally 블록봐 비슷)
<aop:around>           : 메서드 호출 이전, 이후, 예외 발생 등 모든 시점에서 적용 가능한 Advice를 정의한다.

public class ProfilingAdvice {
    public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{

전처리
        String signatureString = joinPoint.getSignature().toShortString();
        System.out.println(signatureString + "시작");
        long start = System.currentTimeMillis();

       
        try{
            Object result = joinPoint.proceed();
            return result;
        }finally{

후처리
            long finish = System.currentTimeMillis();
            System.out.println(signatureString + "종료");
            System.out.println(signatureString + "실행 시간 : " + (finish - start) + "ms");

        }
    }
}

XML스키마를 이용한 AOP 설정

<aop:config> : AOP 설정 정보임을 나타낸다.
<aop:aspect> : Aspect를 설정한다.
<aop:pointcut> : Pointcut을 설정 한다.
<aop:around> : Around Advice를 설정한다. 이외에도 다양한 Advice를 설정




Aspect   :  공통관심사항
@Aspect 어노테이션을 이용해서 Aspect 클래스를 구현한다 .이때 Aspect 클래스는 Advice를 구현한 메서드와 Pointcut을 포함한다.








Pointcut  :  Joinpoint의 부분집합(그룹화)  실제로 Advice가 Joinpoint  적용된 스프링 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의 할 수있다.



Joinpoint : Advice를 적용 가능한 지점을 의미 (메서드호출, 필드값 변경 등)
Weaving  : Advice를 핵심 로직 코드에 적용하는것


AspectJ의 Pointcut 표현식 P181




===============================프로젝트===================================
예제.
src/
madvirus.spring.chap05.aop.annot
      ProfilingAspect (어노테이션)

madvirus.spring.chap05.aop.pojo
      Main (POJO)
      ProfilingAdvice (POJO)

madvirus.spring.chap05.board
      Article ()

madvirus.spring.chap05.board.dao
      ArticleDao (interface)
      MySQLArticleDao ()

madvirus.spring.chap05.board.service
      WriteArticleService (interface)
      WriteArticleServiceImpl ()

madvirus.spring.chap05.member
      Member ()

madvirus.spring.chap05.member.service
      MemberService (interface)
      MemberServiceImpl ()
      UpdateInfo ()

applicationContext.xml (POJO)
applicationContext02.xml (어노테이션)


==================================코드======================================
예제.
src/
madvirus.spring.chap05.aop.annot
      Main02(어노테이션)
package madvirus.spring.chap05.aop.annot;

import madvirus.spring.chap05.board.Article;
import madvirus.spring.chap05.board.service.WriteArticleService;
import madvirus.spring.chap05.member.Member;
import madvirus.spring.chap05.member.service.MemberService;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main02 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext02.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        WriteArticleService articaleService = (WriteArticleService)context.getBean("writeArticleService");
       
        articaleService.write(new Article());
    }
}

      ProfilingAspect (어노테이션)
package madvirus.spring.chap05.aop.annot;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class ProfilingAspect {

    @Pointcut("execution(public * madvirus.spring.chap05.board..*(..))")
    private void profileTarget(){}

    @Around("profileTarget()")
    public Object trace(ProceedingJoinPoint joinPoint)throws Throwable{
       
        String signatureString = joinPoint.getSignature().toShortString();
        System.out.println(signatureString + "시작");
        long start = System.currentTimeMillis();
       
        try{
            Object result =joinPoint.proceed();
            return result;
        }finally{
           
            long finish = System.currentTimeMillis();
            System.out.println(signatureString + "종료");
            System.out.println(signatureString + "실행시간 : "+(finish-start)+"ms");               
        }
    }
}


madvirus.spring.chap05.aop.pojo
      Main (POJO)
package madvirus.spring.chap05.aop.pojo;

import madvirus.spring.chap05.board.Article;
import madvirus.spring.chap05.board.service.WriteArticleService;
import madvirus.spring.chap05.member.Member;
import madvirus.spring.chap05.member.service.MemberService;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        WriteArticleService articaleService = (WriteArticleService)context.getBean("writeArticleService");
       
        articaleService.write(new Article());
       
        MemberService memberService = (MemberService)context.getBean("memberService");
        memberService.regist(new Member());
    }
}

      ProfilingAdvice (POJO)
package madvirus.spring.chap05.aop.pojo;

import org.aspectj.lang.ProceedingJoinPoint;

public class ProfilingAdvice {
    public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
        String signatureString = joinPoint.getSignature().toShortString();
        System.out.println(signatureString + "시작");
        long start = System.currentTimeMillis();
       
        try{
            Object result = joinPoint.proceed();
            return result;
        }finally{
            long finish = System.currentTimeMillis();
            System.out.println(signatureString + "종료");
            System.out.println(signatureString + "실행 시간 : " + (finish - start) + "ms");
        }
    }
}


madvirus.spring.chap05.board
      Article ()
package madvirus.spring.chap05.board;

import madvirus.spring.chap05.board.dao.ArticleDao;

import org.springframework.beans.factory.annotation.Configurable;

public class Article {

    private int id;
    private ArticleDao articleDao;

    public Article() {
    }

    public Article(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void increaseReadCount() {
        articleDao.updateReadCount(id, 1);
    }

    public void setArticleDao(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }
}


madvirus.spring.chap05.board.dao
      ArticleDao (interface)
package madvirus.spring.chap05.board.dao;

import madvirus.spring.chap05.board.Article;

public interface ArticleDao {

    void insert(Article article);

    void updateReadCount(int id, int i);
}

      MySQLArticleDao ()
package madvirus.spring.chap05.board.dao;

import madvirus.spring.chap05.board.Article;

public class MySQLArticleDao implements ArticleDao {

    @Override
    public void insert(Article article) {
        System.out.println("MySQLArticleDao.insert() 실행");
    }

    @Override
    public void updateReadCount(int articleId, int inc) {
        System.out.println("MySQLArticleDao.updateReadCount() 실행");
    }
}


madvirus.spring.chap05.board.service
      WriteArticleService (interface)
package madvirus.spring.chap05.board.service;

import madvirus.spring.chap05.board.Article;

public interface WriteArticleService {

    void write(Article article);
}

      WriteArticleServiceImpl ()
package madvirus.spring.chap05.board.service;

import madvirus.spring.chap05.board.Article;
import madvirus.spring.chap05.board.dao.ArticleDao;

public class WriteArticleServiceImpl implements WriteArticleService {

    private ArticleDao articleDao;

    public WriteArticleServiceImpl() {
    }
   
    public WriteArticleServiceImpl(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }

    //실제적으로 출력될 메서드
    @Override
    public void write(Article article) {
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }
}


madvirus.spring.chap05.member
      Member ()
package madvirus.spring.chap05.member;

public class Member {

}


madvirus.spring.chap05.member.service
      MemberService (interface)
package madvirus.spring.chap05.member.service;

import madvirus.spring.chap05.member.Member;

public interface MemberService {
   
    void regist(Member member);
   
    boolean update(String memberId,UpdateInfo info);
}

      MemberServiceImpl ()
package madvirus.spring.chap05.member.service;

import madvirus.spring.chap05.member.Member;

public class MemberServiceImpl implements MemberService {

    @Override
    public void regist(Member member) {
        System.out.println("MemberServiceImpl.regist() 메서드 실행");
    }

    @Override
    public boolean update(String memberId, UpdateInfo info) {
        System.out.println("MemberServiceImpl.update() 메서드 실행");
        return true;
    }
}

      UpdateInfo ()
package madvirus.spring.chap05.member.service;

public class UpdateInfo {

}


applicationContext.xml (POJO)
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <!-- Advice 클래스를 빈으로 등록 -->
    <bean id="preformanceTraceAdvice" class="madvirus.spring.chap05.aop.pojo.ProfilingAdvice"/>
   
    <!-- Aspect 설정 : Advice를 어떤 Pointcut에 적용할 지 설정 -->
    <aop:config>
        <aop:aspect id="traceAspect1" ref="preformanceTraceAdvice">
            <!-- 광범위하게 적용 : madvirus.spring.chap05.board 안에있는  모든 메소드에 적용 -->
            <aop:pointcut id="publicMethod" expression="execution(public * madvirus.spring.chap05.board..*(..))" />
            <aop:around pointcut-ref="publicMethod" method="trace"/>       
        </aop:aspect>   
       
        <aop:aspect id="traceAspect2" ref="preformanceTraceAdvice">
            <!-- 광범위하게 적용 : madvirus.spring.chap05.board 안에있는  모든 메소드에 적용 -->
            <aop:around pointcut="execution(public * madvirus.spring.chap05.member..*(..))" method="trace"/>       
        </aop:aspect>   
    </aop:config>
   
    <bean id="writeArticleService" class="madvirus.spring.chap05.board.service.WriteArticleServiceImpl">
        <constructor-arg>
            <ref bean="articleDao"/>
        </constructor-arg>
    </bean>   
   
    <bean id="articleDao" class="madvirus.spring.chap05.board.dao.MySQLArticleDao" />
   
    <bean id="memberService" class="madvirus.spring.chap05.member.service.MemberServiceImpl"/>
   
</beans>

applicationContext02.xml (어노테이션)
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <aop:aspectj-autoproxy/>

    <!-- Advice 클래스를 빈으로 등록 -->
    <bean id="preformanceTraceAspect" class="madvirus.spring.chap05.aop.annot.ProfilingAspect"/>
   
    <bean id="writeArticleService" class="madvirus.spring.chap05.board.service.WriteArticleServiceImpl">
        <constructor-arg>
            <ref bean="articleDao"/>
        </constructor-arg>
    </bean>   
   
    <bean id="articleDao" class="madvirus.spring.chap05.board.dao.MySQLArticleDao" />
   
</beans>


==================================결과값=====================================

1. (POJO)

2. (POJO)

3 (어노테이션)


'스프링3.0' 카테고리의 다른 글

Spring3.0 View error filedown  (0) 2012.05.14
Spring3.0 MVC 웹요청 처리  (0) 2012.05.14
Spring3.0 DI 3  (0) 2012.05.14
스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Posted by 사라링

Spring3.0 DI 3

2012. 5. 14. 19:10


==================================이론======================================

*의존관계 자동 설정

private Board board
          (Type) (Name)

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

<beans default-autowire="byName"> : 하위 태그 모두영향
   <bean autowire="byName"/> : 태그에 autowire 속성값지정
</beans>



*프로퍼티 타입을 이용한 의존관계 자동설정

1. 프로퍼티 이름을 이용한 의존 관계 자동 설정    

    <!-- 프로 퍼티  이름을 이용한 의존 관계 자동 설정-->
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="byName"/>
    <bean name="articleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>  

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


2. 프로퍼티 타입을 이용한 의존관계 자동설정

    동일한 타입의 빈 객체가 두 개 이상 존재하게 되면 스프링은 어떤 빈 객체를 사용해야 할 지 알 수 없기 때문에 예외를 발생 시기키게 된다.
    이는 byType 방식을 이용할 경우, 프로퍼티 타입과 동일한 타입의 빈 객체를 오직 한개만 설정할 수 있다는 것을 의미며, 동일한 타입의 빈객체를 다수
    설정해야하는 경우 byType을 사용할수 없다.

    <!-- 프로퍼티 타입을 이용한 의존 관계 자동 설정  -->
    <bean name="writeArticleService2" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="byType"/>
    <bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>
    //<bean name="orcleArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/> 동일타입 빈객체가 존재하면 예외발생  


3. 생성자 파라미터 타입을 이용한 의존 관계 자동설정

    <!-- 생성자 파라미터 타입을 이용한 의존 관계 자동설정  -->
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="constructor"/>
    <bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>

    이 경우  WriteArticleServiceImpl(ArticleDao articleDao) 생성자의 첫 번째 파라미터에 ArticleDao타입인 mysqlArticleDao 빈 객체가 전달된다.


4. 생성자 프로퍼티 타입을 이용한 자동설정

    <!-- 생성자 및 프로퍼티 타입을 이용한 자동설정  -->
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="autodetect"/>
    <bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>

autodetect 방식은 constructor 방식을 먼저 적용하거, constructor 방식을 적용할 수 없는 경우 byType 방식을 적용하여 의존 객체를 설정해 준다.
autodetect 방식은 constructor 방식과 byType 방식을 사용하므로, 동일한 타입의 빈 객체를 2개 이상 정의할 수 없다는 단점을 그대로 갖는다.


5. 자동설정과 직접 설정의 혼합

경우에 따라서는 프로퍼티 중 일부는 자동 설정을 하지 않고 직접적으로 명시하고 싶을 때가 있을 것이다. 이런경우에는 자동 설정과 함께 <property>태그를 이용하여 해당 프로퍼티의 값을 직접 설정해 주면 된다.
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="byName">
        <property name="eventListener" ref="emailAdaptor" />
    </bean> 

특정 프로퍼티의 값이 자동 설정에 의해 초기화 되지 않도록 하려면, <null>태그를 이용하여 프로퍼티의 값을 null로 설정할 수도 있다.

    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="byName">
        <property name="eventListener"><null/><</property>
    </bean> 

* 의존 관계를 자동으로 알맞게 설정해 주는 기능은 스프링 설정 파일의 크기를 줄여 주므로, 분명 유요한 기능임에 틀림없다.
  하지만 설정파일만으로 빈객체 간의 의존 관계를 파악하기 힘들다는 단점이있다. - 규모가 커지면 디버깅이 어렵게된다.
  가급적 빈객체 사이의 의존 관계를 모두 명시해준다.


* 부모 빈을 통한 설정 재사용 P88

빈 정보를 설정하다 보면 여러 빈태그의 설정 정보가 중복되는 경우가 있다.
중복되는 빈은 이름만 다를 뿐 나머지 설정은 대부분 동일한 것.
중복되는 설정을 갖는 빈이 다수 존재할 경우, 중복되는 설정 정보를 담고있는 부모 빈을 정의 한뒤 , 부모 빈 정보를 재사용 하도록 설정할 수 있다.

    <!-- 부모빈을 통한 설정 재사용 -->
    <bean id="commonMonitor" class="madvirus.spring.chap02.SystemMonitor" abstract="true">
        <property name="periodTime" value="10"></property>
        <property name="sender" ref="smsSender"></property>
    </bean>
    <bean id="doorMonitor" parent="commonMonitor" />
    <bean id="lobbyMonitor" parent="commonMonitor" />
    <bean id="roomMonitor" parent="commonMonitor">
        <property name="periodTime" value="20"></property>
    </bean>
    <bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>

<bean abstract="true">   abstract 속성값을 true로 지정하게 되면 스프링 컨테이너는 해당 빈 객체를 생성하지 않는다. 

자식 빈에서는 parent속성을 사용하여 클래스 및 프로퍼티 설정 정보를 물려 받을 부모 빈을 설정하면 된다.
위 코드의 경우 doorMonitor, lobbyMonitor, roomMonitor 빈이 모두 commonMonitor 빈의 설정 정보를 사용하도록 설정하고 있다.
따라서, 이 세 빈은 모두 class 속성의 값으로 madvirus.spring.chap02.SystemMonitor를 사용한다.

parent 속성을 이용하여 물려 받은 설정 정보 중에서 변경하고 싶은 값이 있다면 추가로 입력해주면 된다.
예를 들어, commonMonitor의 periodTime 프로퍼티의 값은 10인데, 다른 값을 사용하고 싶다면
위 코드에서 roomMonitor 빈 객체처럼 사용할 프로퍼티 값을 입력해주면 된다.
프로퍼티 뿐만 아니라 클래스도 새롭게 지정할 수 있다.


*빈객체범위 총 5개

singleton : 스프링 컨테이너에 한개의 빈 객체만 존재한다(기본값)
prototype : 빈을 사요할 때 마다 객체를 생성한다.

request : HTTP 요청 마다 빈 객체를 생성한다. WebApplicationContext에서만 적용 가능하다.
session : HTTP  세션 마다 빈 객체를 생성한다. WebApplicationContext에서만  적용 가능하다.
global-session : 글로벌 HTTP 세션에 대해빈 객체를 생성한다. 포틀릿을 지원하는 컨텍스트에 대해서만 적용 가능하다.

<bean id="workerBean" class="madvirus.spring.chap02.Worker" scope="singleton">
   .......................
</bean>


*서로 다른 범위 빈에 대한 의존 처리 P91

<bean id="workerBean" class="madvirus.spring.chap02.Worker" scope="prototype">
    <!-- <aop:scoped-proxy /> : id="workerBean"이 싱글턴을 사용할경우 싱글턴으로 인정하기때문에  프로토탑입으로 인정시키기위해 사용 -->
    <aop:scoped-proxy />
</bean>


*외부 설정 프로퍼티

방법1:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
           <list>
            <value>classpath:config/jdbc.properties</value>
            <value>classpath:config/jdbc2.properties</value> // 한개이상의 프로퍼티 파일을 지정하려면 <list> 태그를 이용  교제P102
           </list>
        </property>
    </bean>

방법2:

    xmlns:context="http://www.springframework.org/schema/context"
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd"
    beans에 등록후

    <context:property-placeholder location="classpath:config/jdbc.properties, classpath:config/jdbc2.properties"/>
                                                                                                       // 한개이상의 프로퍼티 파일을 지정하려면 , 로 구분

PropertyPlaceholderConfigurer 사용시 주의사항

PropertyPlaceholderConfigurer를 두번 설정하면안된다!!!! 위와같이 하나의 PropertyPlaceholderConfigurer에서 여러파일을 등록해서 사용
PropertyPlaceholderConfigurer를 나누면 예외발생



* 컨테이너 간 계층

BeanFactory 나 ApplicationContext는 컨테이너 간 자식- 부모의 계층 구조를 가질 수 있다.
컨테이너 간 계층 구조를 구성하면, 자식 컨테이너부모 컨테이너정의된 빈 객체에 접근할 수 있다.
반면에 부모 컨테이너에서자식 컨테이너정의된 빈객체에 접근할 수 없다.


 <!-- parent.xml -->
<bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>

<!-- child.xml -->
<bean id="monitor" class="madvirus.spring.chap02.SystemMonitor" p:periodTime="10" p:sender-ref="smsSender"/>
<bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>   



==================================프로젝트======================================
예제.
config
      jdbc.properties (외부 설정 프로퍼티)

madvirus.spring.chap02
     Article (객체형식을 지정할 용도)
     ArticleDao (인터페이스 insert메소드)
     Command (인터페이스 execute메소드)
     CommandFactory (인터페이스 createCommand 메소드)
     CommandFactoryImpl (CommandFactory를 구현 createCommand메소드 구현)
     DataSourceFactory (외부 설정 프로퍼티)
     Executor(서로 다른 범위 빈에 대한 의존 처리)
     Main05 (프로퍼티 이름을 이용한 의존 관계 자동 설정)
     Main06 (프로퍼티 타입을 이용한 의존관계 자동설정)
     Main07 (부모빈을 통한 설정 재사용)
     Main08 (서로 다른 범위 빈에 대한 의존 처리)
     Main09 (외부 설정 프로퍼티)
     MySQLArticleDao (ArticleDao 구현 insert메소드 구현)
     PerformanceMonitor (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
     Processor (getCommandFactory메서드를 통해 CommandFactory를 객체생성 createCommand(commandName)
                      로 Command객체를 생성 execute메서드실행)
     SmsSender (객체형식을 지정할 용도)
     SomeCommand (Command 를 구현  execute메서드 구현)
     SystemMonitor (XML네임스페이스 출력부분)
     Worker (서로 다른 범위 빈에 대한 의존 처리)
     WorkUnit (서로 다른 범위 빈에 대한 의존 처리)
     WriteArticleService (인터페이스 write메소드)
     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
applicationContext03.xml (외부 설정 프로퍼티)
applicationContext2.xml (DI(Dependency Injection 처리): 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)


==================================코드======================================

예제.
config
      jdbc.properties (외부 설정 프로퍼티)
jdbc.driver=oracle.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.username=hr
jdbc.password=hr

madvirus.spring.chap02
     Article (객체형식을 지정할 용도)
package madvirus.spring.chap02;

public class Article {

}

     ArticleDao (인터페이스 insert메소드)
package madvirus.spring.chap02;

public interface ArticleDao {
    void insert(Article article);
}

     Command (인터페이스 execute메소드)
package madvirus.spring.chap02;

public interface Command {   
    void execute();
}

     CommandFactory (인터페이스 createCommand 메소드)
package madvirus.spring.chap02;

public interface CommandFactory {

    Command createCommand(String commandName);
}

     CommandFactoryImpl (CommandFactory를 구현 createCommand메소드 구현)
package madvirus.spring.chap02;

public class CommandFactoryImpl implements CommandFactory{

    @Override
    public Command createCommand(String commandName) {
        if(commandName.equals("some")){
            return new SomeCommand();
        }
        return null;
    }
}

     DataSourceFactory (외부 설정 프로퍼티)
package madvirus.spring.chap02;

public class DataSourceFactory {

    private String jdbcDriver;
    private String jdbcUrl;
    private String username;
    private String password;
   
    public void setJdbcDriver(String jdbcDriver) {
        this.jdbcDriver = jdbcDriver;
    }
    public void setJdbcUrl(String jdbcUrl) {
        this.jdbcUrl = jdbcUrl;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
   
    @Override
    public String toString() {
        return "DataSourceFactory [jdbcDriver=" + jdbcDriver + ", jdbcUrl="
                + jdbcUrl + ", username=" + username + ", password=" + password
                + "]";
    }   
}


     Executor(서로 다른 범위 빈에 대한 의존 처리)
package madvirus.spring.chap02;

public class Executor {

    private Worker worker;
   
    public void addUnit(WorkUnit work){
        worker.work(work);
    }
   
    public void setWorker(Worker worker){
        this.worker = worker;
    }
}

     Main05 (프로퍼티 이름을 이용한 의존 관계 자동 설정)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main05 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext2.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //프로퍼티 이름을 이용한 의존 관계 자동 설정
        WriteArticleService articleService = (WriteArticleService)context.getBean("writeArticleService");
       
        articleService.write(new Article());
    }
}

     Main06 (프로퍼티 타입을 이용한 의존관계 자동설정)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main06 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext2.xml"};
        ApplicationContext context =new ClassPathXmlApplicationContext(configLocations);
       
        //프로퍼티 타입을 이용한 의존관계 자동설정
        WriteArticleService articleService= (WriteArticleService)context.getBean("writeArticleService2");
       
        articleService.write(new Article());
    }
}   

     Main07 (부모빈을 통한 설정 재사용)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main07 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext2.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //부모 빈을 통한 설정 재사용
        SystemMonitor articleService = (SystemMonitor)context.getBean("doorMonitor");
        System.out.println(articleService);
        SystemMonitor articleService02 = (SystemMonitor)context.getBean("lobbyMonitor");
        System.out.println(articleService02);
        SystemMonitor articleService03 = (SystemMonitor)context.getBean("roomMonitor");
        System.out.println(articleService03);
       
    }
}

     Main08 (서로 다른 범위 빈에 대한 의존 처리)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main08 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext2.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //서로 다른 범위 빈에 대한 의존 처리
        Executor executor = context.getBean("executor",Executor.class);
        executor.addUnit(new WorkUnit());
        executor.addUnit(new WorkUnit());
        executor.addUnit(new WorkUnit());
       
        Worker worker = context.getBean("workerBean", Worker.class);
        worker.work(new WorkUnit());
        worker.work(new WorkUnit());
    }   
}

     Main9 (외부 설정 프로퍼티)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main09 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext03.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        DataSourceFactory dataSourceFactory = context.getBean("dataSourceFactory",DataSourceFactory.class);
       
        System.out.println(dataSourceFactory.toString());
    }
}


     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
package madvirus.spring.chap02;

public class MySQLArticleDao implements ArticleDao{
   
    @Override
    public void insert(Article article){
        System.out.println("MySQLArticleDao.insert()실행");
    }
}


     PerformanceMonitor (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
package madvirus.spring.chap02;

import java.util.List;

public class PerformanceMonitor {
   
    private List<Double> deviations;
   
    public void setDeviations(List<Double> deviations){
        this.deviations = deviations;
    }

    @Override
    public String toString() {
        return "PerformanceMonitor [deviations=" + deviations + "]";
    }
}

     Processor (getCommandFactory메서드를 통해 CommandFactory를 객체생성 createCommand(commandName)
                      로 Command객체를 생성 execute메서드실행)
package madvirus.spring.chap02;

public class Processor {

    public void process(String commandName){
        CommandFactory factory = getCommandFactory();
        Command command = factory.createCommand(commandName);
        command.execute();
    }
   
    protected CommandFactory getCommandFactory(){
        return null;
    }
}

     SmsSender (객체형식을 지정할 용도)
package madvirus.spring.chap02;

public class SmsSender {
}

     SomeCommand (Command 를 구현  execute메서드 구현)
package madvirus.spring.chap02;

public class SomeCommand implements Command{

    @Override
    public void execute() {
        System.out.println("SomeCommand executed.");
    }   
}

     SystemMonitor (XML네임스페이스 출력부분)
package madvirus.spring.chap02;

public class SystemMonitor {
   
    private long periodTime;
    private SmsSender sender;
   
   
    public void setPeriodTime(long periodTime) {
        this.periodTime = periodTime;
    }
    public void setSender(SmsSender sender) {
        this.sender = sender;
    }
   
    @Override
    public String toString() {
        return "SystemMonitor [periodTime=" + periodTime + ", sender=" + sender
                + "]";
    }
}

     Worker (서로 다른 범위 빈에 대한 의존 처리)
package madvirus.spring.chap02;

public class Worker {
   
    public void work(WorkUnit unit){
        System.out.println(toString()+" work " + unit);
    }
}

     WorkUnit (서로 다른 범위 빈에 대한 의존 처리)
package madvirus.spring.chap02;

public class WorkUnit {

}

     WriteArticleService (인터페이스 write메소드)
package madvirus.spring.chap02;

public interface WriteArticleService {
    void write(Article article);
}

     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
package madvirus.spring.chap02;

public class WriteArticleServiceImpl implements WriteArticleService{

    private ArticleDao articleDao;
   
    //의존 관계 설정 방식: 프로퍼티
    public void setArticleDao(ArticleDao articleDao){
        this.articleDao = articleDao;
    }   
   
    @Override
    public void write(Article article) {       
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }   
}

applicationContext03.xml (외부 설정 프로퍼티)
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!--    
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>classpath:config/jdbc.properties</value>
        </property>
    </bean>
-->
   
    <context:property-placeholder location="classpath:config/jdbc.properties"/>
   
    <bean id="dataSourceFactory" class="madvirus.spring.chap02.DataSourceFactory">
        <property name="jdbcDriver" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>       
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>       
    </bean>   
</beans>

applicationContext2.xml (DI(Dependency Injection 처리): 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 프로 퍼티  이름을 이용한 의존 관계 자동 설정-->
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="byName"/>

    <bean name="articleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>
   
    <!-- 프로퍼티 타입을 이용한 의존 관계 자동 설정  -->
    <bean name="writeArticleService2" class="madvirus.spring.chap02.WriteArticleServiceImpl" autowire="byType"/>
   
    <bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>
   
    <!-- 부모빈을 통한 설정 재사용 -->
    <bean id="commonMonitor" class="madvirus.spring.chap02.SystemMonitor" abstract="true">
        <property name="periodTime" value="10"></property>
        <property name="sender" ref="smsSender"></property>
    </bean>
    <bean id="doorMonitor" parent="commonMonitor" />
    <bean id="lobbyMonitor" parent="commonMonitor" />
    <bean id="roomMonitor" parent="commonMonitor">
        <property name="periodTime" value="20"></property>
    </bean>
    <bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>
   
    <!-- 서로 다른 범위 빈에 대한 의존 처리  -->
    <bean id="workerBean" class="madvirus.spring.chap02.Worker" scope="prototype">
    <!-- <aop:scoped-proxy /> :id="workerBean"이 싱글턴을 사용할경우 싱글턴으로 인정하기때문에  프로토탑입으로 인정시키기위해 사용 -->
        <aop:scoped-proxy />
    </bean>
   
    <bean id="executor" class="madvirus.spring.chap02.Executor">
        <property name="worker" ref="workerBean"/>
    </bean>       
   
</beans>

==================================결과값=====================================

1.프로퍼티 이름을 이용한 의존 관계 자동 설정

   



2.프로퍼티 타입을 이용한 의존관계 자동설정

   



3. 부모빈을 통한 설정 재사용

   



4. 서로 다른 범위 빈에 대한 의존 처리


    <aop:scoped-proxy /> 처리

    

     <aop:scoped-proxy /> 빼면 같아짐 Worker가 싱글턴이기 때문

   

5. 외부 설정 프로퍼티

    


'스프링3.0' 카테고리의 다른 글

Spring3.0 MVC 웹요청 처리  (0) 2012.05.14
Spring 3.0 AOP  (0) 2012.05.14
스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
Posted by 사라링


04장. 어노테이션 기반 설정



어노테이션 쉽게 명시하기

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd

<!--RequiredAnnotationBeanPostProcessor @Required 사용시
         AutowiredAnnotationBeanPostProcessor @Autowired 사용시
         CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
         ConfigurationClassPostProcessor @Configuration 사용시     
         context를 명시하면 context태그 하나로 사용가능     
        <context:annotation-config/> -->



==================================이론======================================

1.1 @Required 어노테이션을 이용한 필수 프로퍼티 검사

@Required : 필수 프로퍼티를 명시하여 값을 넘겨오는것을 강요 안넘겨오면 에러                    
                     number 프로퍼티를 설정하지 않을 경우 예외 발생


Camera
   import org.springframework.beans.factory.annotation.Required;

 //@Required : 필수요소를 체크해줌 : 스프링에서만 사용할수있다.
    @Required
    public void setNumber(int number){
        this.number = number;
    }

applicationContext.xml
    <!-- @Required 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
     <!-- RequiredAnnotationBeanPostProcessor 대신 context를 명시하면 context태그를 사용가능
            <context:annotation-config/> -->
   
    <bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera">
        <!--
            number 프로퍼티에 @Required 어노테이션 적용
            number 프로퍼티를 설정하지 않을 경우 예외 발생
         -->
         <property name="number" value="1" />
    </bean>

1.2 @Autowired 어노테이션을 이용한 자동 설정

@Autowired : 타입을 이용하여 의존하는 객체를 삽입해준다. 생성자, 필드,메서드 세곳에 적용이 가능하다.
  프로퍼티 설정 메서드에 @Autowired 적용하면  어노테이션 타입을 이용한 프로퍼티 자동 설정 기능을 제공한다.
   
@Required 와 마찬가지로 @Autowired기본적으로  값을 강요하는데 필수여부를 조정해줄수있다.
@Autowired(required=false) 기본값은 true이다

    <!-- @Autowired 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    <bean id="monitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor"/>
    <bean id="sender" class="madvirus.spring.chap04.homecontrol.SmsSender"/>

@Autowired 어노테이션은 타입을 기반으로하기 때문에 자동 설정할 타입이 두개 이상 존재할 경우 예외를 발생 시킨다.
그래서 @Qualifier 어노테이션을 이용한 자동 설정 제한 을 이용한다.

@Qualifier
로 레코드를 지정   
    <!-- @Qualifier 어노테이션을 이용한 자동 설정 제한 -->
    <bean id="systemMonitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor2"/>
    <bean id="recorder" class="madvirus.spring.chap04.homecontrol.Recorder">
        <qualifier value="main"/>
    </bean>   


1.3 @Resource 어노테이션을 프로퍼티 설정

어플리케이션에서 필요로 하는 자원을 자동 연결할때 사용된다.
의존하는 빈 객체를 전달할 때 사용한다.
@Resource 어노테이션을 사용 하려면 name 속성에 자동으로 연결할 빈 객체의 이름을 입력 하면된다.

동일한 객체타입인데 객체주소가 다른 여러객체가 들어올때 사용하면 GOOD!!


<!-- @Resource 어노테이션 사용시 필수적으로 설정 -->
<!-- 스프링에서의 singleton id 하나당 객체한개 -->
<bean id="homeController" class="madvirus.spring.chap04.homecontrol.HomeController"/>
<bean id="camera2" class="madvirus.spring.chap04.homecontrol.Camera" p:number="2"/>
<bean id="camera3" class="madvirus.spring.chap04.homecontrol.Camera" p:number="3"/>
<bean id="camera4" class="madvirus.spring.chap04.homecontrol.Camera" p:number="4"/>


1.4 @PostConstruct 어노테이션및 @PreDestory어노테이션과 라이플 사이클

라이프 사이클(생명주기) 초기화 및 제거 과정을 제공한다.
@PostConstruct는 의존하는 객체를 설정한 이후에 초기화 작업을 수행할 메서드에 적용된다.
@PreDestroy는 컨테이너에서 객체를 제거하기 전에 호출될 메서드에 적용된다.
스프링 설정 파일에서 init-method 속성과  destroy-method 속성성을 이용하여 명시한 메서드와 동일한 시점에 실행된다.

*사용후 재사용가능하게 메모리정리를안함
ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
* 작업이끝나고 메모리정리까지함
AbstractApplicationContext context = new ClassPathXmlApplicationContext(configLocations);

        @PostConstruct
        public void init(){
            System.out.println("init 메소드 동작");
        }
       
        @PreDestroy
        public void close(){
            System.out.println("close 메소드 동작");
        }



2.1 어노테이션을 이용한 자동스캔

@Component, @Service, @Controller 는 클래스 선언부분에 붙게된다.

@Component 어노테이션은 클래스에 적용했다면

//스프링이 클래스를 검색할 패키지를 지정.
<context:component-scan base-package="madvirus.spring.chap04.homecontrol"/>
*@Component  어노테이션 적용된 클래스를 검색하여 빈으로 등록하게된다.

<context:annotation-config/>와같이<context:component-scan/>  태그를 쓰면
RequiredAnnotationBeanPostProcessor @Required 사용시
AutowiredAnnotationBeanPostProcessor @Autowired 사용시
CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
ConfigurationClassPostProcessor @Configuration 사용시    
같은 어노테이션이 함께 적용된다.

* 명시적으로 설정해야하는부분이 많아서 오토스캔만 사용하는경우는 극히적다. 적당히 썩어서 사용

3.1 @Configuration 어노테이션과 @Bean 어노테이션을 이용한 코드 기반 설정
스프링3.0에 새로생김

@Configuration 과 @Bean 을 이용해서 스프링 컨텐이너에 새로운 빈 객체를 제공할 수 있다.

@Configuration
public class SpringConfig{

     @Bean // XML 빈정의 설정시 해당 메소드 이름을 사용한다.
     //@Bean(name="smsAlarmDevice") //메서드 이름이 아닌 다른이름을 사용하고 싶다면 name 속성을 사용
     //@Bean(autowire = Autowire.BY_NAME) 
     //Autowire.BY_NAME:이름을 이용해서 자동연관처리, Autowire.BY_TYPE:타입을 이용하여 자동연관처리, Autowire.NO:자동연관처리 안함
     public AlarmDevice alarmDevice(){
            return new SmsAlarmDevice();
     }
}

@Configuration 적용된 클래스를 설정정보로 이용하는 방법.

@Configuration
public class MainConfig{

     public static void main(String[] args){

            ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

            //한개이상의 @Configuration 적용 클래스로부터 ApplicationContext 를 생성하고 싶다면 @Configuration 목록을 지정
            //ApplicationContext context = new AnnotationConfigApplicationContext
         //                                                   (
ArticleServiceConfig.class,ArticleRepositoryConfig.class);

            HomeController homeController = context.getBean("homeController",HomeController .class);
            ....
     }
}

XML 설정파일에서도 @Configuration 적용된 클래스를 사용할수있다.

<bean class="org.springframework.beans.factory.annotation.ConfigurationClassPostProcessor"/>// @Configuration 사용시 
<bean class="madvirus.spring.chap04.config.SpringConfig"/> 

//<context:component-scan base-package="madvirus.spring.chap04.config.SpringConfig">

반대로 @Configuration 적용된 클래스 XML 설정파일 정보를 사용하기

@Configuration
@ImportResource("classpath:/article-repository.xml")
//두개이상사용시 배열형태로
@ImportResource({"classpath:/article-repository.xml", "
classpath:/article-datasource.xml"})
public class SpringConfig{

     @Bean
   
public AlarmDevice alarmDevice(){
            return new SmsAlarmDevice();
     }
}

@Configuration 클래스 간의 의존 설정

@Configuration
public class ArticleServiceConfig{

     @Autowired
     private ArticleRespositoryConfig respositoryConfig;

     @Bean
   
public ArticleService articleService(){
            return new ArticleServiceImpl(respositoryConfig.articleRepository());
     }
}

@Import를 이용한 @Configuration 클래스의 조합

@Configuration
@Import({"ArticleServiceConfig.class, ArticleRepositoryConfig.class"})
public class SpringConfig{

     @Bean
   
public AlarmDevice alarmDevice(){
            return new SmsAlarmDevice();
     }
}



===============================프로젝트===================================
예제.
madvirus.spring.chap04.homecontrol
      AlarmDevice (@Resource)
      Camera (@Required)
      Homecontrolloer (@Resource)
      Homecontrolloer2 (@PostConstruct,@PreDestroy)
      Main (@Required)
      Main02 (@Autowired)
      Main03 (@Autowired - @Qualifier)
      Main04 (@Resource)
      Main05 (@PostConstruct,@PreDestroy)
      Main06 (@Component )
      MessageSender (@Autowired)
      Recorder (@Autowired - @Qualifier)
      SmsSender (@Autowired)
      SystemMonitor (@Autowired)
      SystemMonitor2 (@Autowired - @Qualifier)
      Viewer (@Resource)

applicationContext.xml
applicationContext02.xml

==================================코드======================================
예제.
madvirus.spring.chap04.homecontrol
      AlarmDevice (@Resource)
package madvirus.spring.chap04.homecontrol;

public interface AlarmDevice {
   
    void alarm(String name);
}

       Camera (@Required)
package madvirus.spring.chap04.homecontrol;

import org.springframework.beans.factory.annotation.Required;

public class Camera {
   
    private int number;
   
    public Camera() {
    }

    //@Required : 필수요소를 체크해줌 : 스프링에서만 사용할수있다.
    @Required
    public void setNumber(int number){
        this.number = number;
    }

    @Override
    public String toString() {
        return "Camera [number=" + number + "]";
    }   
}

      Homecontrolloer (@Resource)
package madvirus.spring.chap04.homecontrol;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

@Component("homeController")
public class HomeController {

   
        private AlarmDevice alarmDevice;
        private Viewer viewer;

        //@Resource 프로퍼티 설정
        //결과적으론 private Camera camera1 에보관.
        @Resource(name = "camera1")
        private Camera camera1;

        @Resource(name = "camera2")
        private Camera camera2;

        @Resource(name = "camera3")
        private Camera camera3;       

        private Camera camera4;

        public void setCamera1(Camera camera1) {
            this.camera1 = camera1;
        }

        public void setCamera2(Camera camera2) {
            this.camera2 = camera2;
        }

        public void setCamera3(Camera camera3) {
            this.camera3 = camera3;
        }

        //메소드에도 명시할수있음
        @Resource(name = "camera4")
        public void setCamera4(Camera camera4) {
            this.camera4 = camera4;
        }

        @Override
        public String toString() {
            return "Homecontrolloer [camera1=" + camera1 + ", camera2="
                    + camera2 + ", camera3=" + camera3 + ", camera4=" + camera4
                    + "]";
        }       
}

      Homecontrolloer2 (@PostConstruct,@PreDestroy)
package madvirus.spring.chap04.homecontrol;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

public class HomeController2 {

   
        private AlarmDevice alarmDevice;
        private Viewer viewer;

        //@Resource 프로퍼티 설정
        //결과적으론 private Camera camera1 에보관.
        @Resource(name = "camera1")
        private Camera camera1;

        @Resource(name = "camera2")
        private Camera camera2;

        @Resource(name = "camera3")
        private Camera camera3;       

        private Camera camera4;

        public void setCamera1(Camera camera1) {
            this.camera1 = camera1;
        }

        public void setCamera2(Camera camera2) {
            this.camera2 = camera2;
        }

        public void setCamera3(Camera camera3) {
            this.camera3 = camera3;
        }

        //메소드에도 명시할수있음
        @Resource(name = "camera4")
        public void setCamera4(Camera camera4) {
            this.camera4 = camera4;
        }

        @PostConstruct
        public void init(){
            System.out.println("init 메소드 동작");
        }
       
        @PreDestroy
        public void close(){
            System.out.println("close 메소드 동작");
        }
}

      Main (@Required)
package madvirus.spring.chap04.homecontrol;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
   
    public static void main (String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        Camera camera = context.getBean("cameara1", Camera.class);
        System.out.println(camera);
    }
}

      Main02 (@Autowired)
package madvirus.spring.chap04.homecontrol;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main02 {
   
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        SystemMonitor monitor = context.getBean("monitor",SystemMonitor.class);
       
        System.out.println(monitor.getSender());
    }
}

      Main03 (@Autowired - @Qualifier)
package madvirus.spring.chap04.homecontrol;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main03 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        SystemMonitor2 monitor = context.getBean("systemMonitor",SystemMonitor2.class);

        System.out.println(monitor.getSender());
        System.out.println(monitor.getRecorder());
    }
}

      Main04 (@Resource)
package madvirus.spring.chap04.homecontrol;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main04 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        HomeController home = context.getBean("homeController" , HomeController.class);
       
        System.out.println(home);
    }   
}

      Main05 (@PostConstruct,@PreDestroy)
package madvirus.spring.chap04.homecontrol;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main05 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        //사용후 재사용가능하게 메모리정리를안함
        //ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //작업이끝나고 메모리정리까지함
        AbstractApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        context.registerShutdownHook();
       
        HomeController2 home = context.getBean("homeController2" , HomeController2.class);       
    }   
}

      Main06 (@Component )
package madvirus.spring.chap04.homecontrol;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main06 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext02.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        HomeController home = context.getBean("homeController" , HomeController.class);
       
        System.out.println(home);
    }   
}

      MessageSender (@Autowired)
package madvirus.spring.chap04.homecontrol;

public interface MessageSender {

}

      Recorder (@Autowired - @Qualifier)
package madvirus.spring.chap04.homecontrol;

public class Recorder {

}

      SmsSender (@Autowired)
package madvirus.spring.chap04.homecontrol;

public class SmsSender implements MessageSender {
    public SmsSender (){}
   
    public SmsSender(boolean value){}
}

      SystemMonitor (@Autowired)
package madvirus.spring.chap04.homecontrol;

import org.springframework.beans.factory.annotation.Autowired;

public class SystemMonitor {

    private int periodTime;
    private MessageSender sender;
   
   
    public SystemMonitor() {}
   
    public SystemMonitor(int period) {
        this(period, null);
    }
   
    public SystemMonitor(int period, MessageSender sender) {
        this.periodTime = period;
        this.sender = sender;
    }

    public int getPeriodTime() {
        return periodTime;
    }

    public void setPeriodTime(int periodTime) {
        this.periodTime = periodTime;
    }

    public MessageSender getSender() {
        return sender;
    }
   
    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }   
}

      SystemMonitor2 (@Autowired - @Qualifier)
package madvirus.spring.chap04.homecontrol;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class SystemMonitor2 {

    private MessageSender sender;

    @Autowired
    @Qualifier("main")
    private Recorder recorder;
   

    public SystemMonitor2(MessageSender sender){
        this.sender = sender;
    }
   
    public SystemMonitor2() {}

    public MessageSender getSender() {
        return sender;
    }
   
    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }

    public Recorder getRecorder() {
        return recorder;
    }
   
    public void setRecorder(Recorder recorder) {
        this.recorder = recorder;
    }
}

      Viewer (@Resource)
package madvirus.spring.chap04.homecontrol;

public interface Viewer {

        void add (Camera camera1);
       
        void draw();
}

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

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!--RequiredAnnotationBeanPostProcessor @Required 사용시
         AutowiredAnnotationBeanPostProcessor @Autowired 사용시
         CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
         ConfigurationClassPostProcessor @Configuration 사용시    
        context를 명시하면 context태그 하나로 사용가능    
        <context:annotation-config/> -->
     
    <!-- @Required 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
    <bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera">
        <!--
            number 프로퍼티에 @Required 어노테이션 적용
            number 프로퍼티를 설정하지 않을 경우 예외 발생
         -->
         <property name="number" value="1" />
    </bean>
   
    <!-- @Autowired 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    <bean id="monitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor"/>
    <bean id="sender" class="madvirus.spring.chap04.homecontrol.SmsSender"/>
   
    <!-- @Qualifier 어노테이션을 이용한 자동 설정 제한 -->
    <bean id="systemMonitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor2"/>
    <bean id="recorder" class="madvirus.spring.chap04.homecontrol.Recorder">
        <qualifier value="main"/>       
    </bean>   
   
    <!-- @Resource 어노테이션 사용시 필수적으로 설정 -->
    <!-- 스프링에서의 singleton id 하나당 객체한개 -->
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
    <bean id="homeController" class="madvirus.spring.chap04.homecontrol.HomeController"/>
    <bean id="camera2" class="madvirus.spring.chap04.homecontrol.Camera" p:number="2"/>
    <bean id="camera3" class="madvirus.spring.chap04.homecontrol.Camera" p:number="3"/>
    <bean id="camera4" class="madvirus.spring.chap04.homecontrol.Camera" p:number="4"/>
   
    <!-- @PostConstruct 어노테이션 및    @PreDestroy 어노테이션 사용 -->
    <bean id="homeController2" class="madvirus.spring.chap04.homecontrol.HomeController2"/>    
   
   
</beans>

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

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <context:component-scan base-package="madvirus.spring.chap04.homecontrol"/>
   
    <bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera" p:number="1"/>
    <bean id="camera2" class="madvirus.spring.chap04.homecontrol.Camera" p:number="2"/>
    <bean id="camera3" class="madvirus.spring.chap04.homecontrol.Camera" p:number="3"/>
    <bean id="camera4" class="madvirus.spring.chap04.homecontrol.Camera" p:number="4"/>
   
</beans>

==================================결과값=====================================

1.@Required

  @Required에 값을 안넣어주는경우.


2.@Autowired

3.@Autowired - @Qualifier


4.@Resource

5.@PostConstruct,@PreDestroy

6.@Component


'스프링3.0' 카테고리의 다른 글

Spring 3.0 AOP  (0) 2012.05.14
Spring3.0 DI 3  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
Spring3.0 DI AOP  (0) 2012.05.14
Posted by 사라링

Spring3.0 message&event

2012. 5. 14. 19:07

메시지 및 이벤트 처리 - 국제화


==================================이론======================================

*메시지 소스를 이용한 메시지 국제화 처리

* 프로퍼티 파일은 유니코드를 이용하여 값을 표시해 주어야 한다. (JDK에서 제공하는 native2ascii를 이용하여 유니코드 값으로 변환)

<!-- 국제화 처리를 위한 리소스 번들지정  -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>message.greeting</value>
            <value>message.error</value>
        </list>       
    </property>
</bean>

* 빈 객체에서 메시지 이용하기

 - ApplicationContextAware 인터페이스를 구현한 뒤, setApplicationContext()메서드를 통해 전달받은 ApplicationContext의 getMessage()메서드를 이용하여 메시지 사용
 - MessageSourceAware 인터페이스 구현한 뒤, setMessageSource() 메서드를 통해 전달받은 MessageSource의 getMessage()메서드를  이용하여 메시지 사용


public interface MessageSourceAware{
    void setMessageSource(MessageSource messageSource)
}

public class LogingProcessor implements MessageSourceAware{

   private MessageSource messageSource;

   public void setMessageSource(MessageSource messageSource){
       this.messageSource = messageSource;
   }

   public void login(String username, String password){
        ...
        Object[] arg = new String[] {username};
        String failMessage = messageSource.getMessage("login.fail",args,locale);
        ...
   }
}


*스프링 컨텍스트 이벤트

ApplicationContext는 이벤트를 발생시킬수 있는 publishEvent() 메서드를 제공한다.

void publishEvent(ApplicationEvent event)

publishEvent() 메서드는 org.springframework.context.ApplicationEvent 타입의 객를 전달 받는다.

ApplicationEvent 는 추상 클래스로서 다음과 같이 생성자를 통해서 이벤트를 발생시킨 객체를 전달받는다.

public abstract class ApplicationEvent extends EventObject{
      ...
      public ApplicationEvent(Object source){
            super(source);
            this.timestamp = System.currentTimeMillis();
      }
   
      public final long getTimestamp(){
            return this.timestamp;
      }
}

ApplicationContext를 통해서 이벤트를 발생시키고 싶은 빈은 ApplicationContextAware 인터페이스를 구현한뒤 ApplicationContext가 제공하는 publishEvent()메서드를 이용해서 이벤트를 발생시키면된다.

public classs MemberService implements ApplicationContextAware{

         private ApplicationContext context;
         public void setApplicationContext(ApplicationContext context){
              this.context = context;
         }

         public void regist(Member member){
               ...
              context.publishEvent(new MemberRegistrationEvent(this, member));
          }
}

이벤트 클래스는 ApplicationEvent클래스를 상속받아 구현하면된다.

public classs MemberRegistrationEvent extends ApplicationEvent{

         private Member member;

         public void MemberRegistrationEvent (Object source, Member member){
              super(source);
              this.member= member;
         }

         public Member getMember(){
               return member;
          }
}

ApplicationContext가 발생시킨 이벤트를 처리할 클래스는 ApplicationListenner 인터페이스를 알맞게 구현해 주면 된다. ApplicationListener인터페이스는 다음과 같이 정의 되어있다.

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener{
        void onApplicationEvent(E event);
}

ApplicationContext는 이벤트 발생시 ApplicationListenner 인터페이스를 구현한빈 객체의 onApplicationEvent() 메서드를 호출함으로서 이벤트를 전달한다. 아래 코드는 ApplicationListenner인터페이스를 구현한 클래스의 전형적인 구현 방식을 보여주고있다.

public classs CustomEventListener implements ApplicationListener<MemberRegistationEvent>{
     
         @Override
         public void onApplicationEvent(MemberRegistationEvent event){
              //원하는 이벤트 처리 코드 삽입
          }
}

ApplicationListenner 인터페이스를 구현한 클래스를 스프링 빈으로 등록해 주기만하면 ApplicationContext가 발생한 이벤트를 전달받아 처리할 수 있게 된다.

<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-3.0.xsd">
  
    <!-- 스프링 컨텍스트 이벤트 객체만들기 -->
    <bean id="customEventListener" class="madvirus.spring.chap03.CustomEventListener"/>
   
</beans>


스프링은 기본적으로 ApplicationContext와 관련된 이벤트를 발생시키고 있는데, 이들 이벤트는 다음과 같다.

org.springframework.context.event.ContextRefreshedEvent : ApplicationContext가 초기화 되거나 설정을 재로딩해서 초기화를재수행할 때 발생한다.
org.springframework.context.event.ContextClosedEvent : ApplicationContext가 종료될 때 발생한다.
org.springframework.context.event.ContextStartEvent : ApplicationContext가 시작될 때 발생한다.
org.springframework.context.event.ContextStoppedEvent : ApplicationContext가 중지될 때 발생한다.

스프링 3.0  부터는 ApplicationListenner에 제네릭이 적용되었기 때문에, 지정한 타입만 처리하는 리스너를 작성할수 있게 되었다.

스프링 2.5 버전는 instanceof 연산자로 객체를 비교했어야했다 P114에 예제있음


==================================프로젝트======================================
예제.
madvirus.spring.chap03
      CustomeventListener (스프링 컨텍스트 이벤트 객체만들기)
      LoginProcessor (클래스내의 메시지 소스를 사용)
      Main (메시지 소스를 이용한 메시지 국제화 처리)
      Main02 (메시지 소스를 이용한 메시지 국제화 처리:강제 영어설정)
      Main03 (클래스내에서 메시지 소스를 사용)
      Main04 (스프링 컨텍스트 이벤트 객체만들기)
      Member (스프링 컨텍스트 이벤트 객체만들기)
      MemberRegistartionEvent (스프링 컨텍스트 이벤트 객체만들기)
      MemberService (스프링 컨텍스트 이벤트 객체만들기)

message
      error.properties
      greeting_en.properties
      greeting_ko.properties

applicationContext.xml


==================================코드======================================

madvirus.spring.chap03
      CustomeventListener (스프링 컨텍스트 이벤트 객체만들기)
package madvirus.spring.chap03;

import org.springframework.context.ApplicationListener;

public class CustomeventListener implements ApplicationListener<MemberRegistartionEvent> {

    @Override
    //MemberRegistartionEvent 객체를 받는다.
    public void onApplicationEvent(MemberRegistartionEvent event) {
        System.out.println("회원 가입 이벤트 발생: " + event.getMember());
    }
}

      LoginProcessor (클래스내의 메시지 소스를 사용)
package madvirus.spring.chap03;

import java.util.Locale;

import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;

public class LoginProcessor  implements MessageSourceAware{

    private MessageSource messageSource;
       
    @Override
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }
   
    public void login(String username,String password){
        if(!username.equals("medvirus")){
            Object[] args = new String[] { username};
            String failMessage = messageSource.getMessage("login.fail", args, Locale.getDefault());
            throw new IllegalArgumentException(failMessage);
        }
    }
}

      Main (메시지 소스를 이용한 메시지 국제화 처리)
package madvirus.spring.chap03;

import java.util.Locale;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        Locale locale = Locale.getDefault();
        String greeting = context.getMessage("greeting",new Object[0], locale);
       
        System.out.println("Default Locale Greeting: "+greeting);
    }
}

      Main02 (메시지 소스를 이용한 메시지 국제화 처리:강제 영어설정)
package madvirus.spring.chap03;

import java.util.Locale;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main02 {

    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        Locale locale = Locale.ENGLISH;
        String greeting = context.getMessage("greeting",new Object[0], locale);
       
        System.out.println("English Locale Greeting: "+greeting);
    }
}

      Main03 (클래스내에서 메시지 소스를 사용)
package madvirus.spring.chap03;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main03 {

    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        LoginProcessor loginProcessor = context.getBean("loginProcessor",LoginProcessor.class);
       
        try{
            loginProcessor.login("madvirus2", "1234");
        }catch(Throwable e){
            System.out.println("예외 발생 : "+e.getMessage());
        }       
    }
}

      Main04 (스프링 컨텍스트 이벤트 객체만들기)
package madvirus.spring.chap03;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main04 {
   
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        MemberService memberService = context.getBean("memberService",MemberService.class);
       
        memberService.regist(new Member("madvirus", "최범균"));
    }
}

      Member (스프링 컨텍스트 이벤트 객체만들기)
package madvirus.spring.chap03;

public class Member {
 
    private String id;
    private String name;
   
    public Member(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Member [id=" + id + ", name=" + name + "]";
    }   
}

      MemberRegistartionEvent (스프링 컨텍스트 이벤트 객체만들기)
package madvirus.spring.chap03;

import org.springframework.context.ApplicationEvent;

public class MemberRegistartionEvent extends ApplicationEvent {

    private Member member;   

    public MemberRegistartionEvent(Object source, Member member) {
        super(source);
        this.member = member;
    }
    public Member getMember() {
        return member;
    }
}

      MemberService (스프링 컨텍스트 이벤트 객체만들기)
package madvirus.spring.chap03;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class MemberService implements ApplicationContextAware {

    private ApplicationContext applicationContext;
   
    //객체를 받을수있도록 setter를 만듬
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void regist(Member member){
        //publishEvent 를 불러 이벤트 처리
        applicationContext.publishEvent(new MemberRegistartionEvent(this, member));
    }
}

message
      error.properties
login.fail=Member ID {0} is not matching password

      greeting_en.properties
greeting=Hello!

      greeting_ko.properties
greeting=안녕하세요!


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

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 국제화 처리를 위한 리소스 번들지정  -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>message.greeting</value>
                <value>message.error</value>
            </list>       
        </property>
    </bean>
   
    <!-- 빈 객체에서 메시지 이용하기 -->
    <bean id="loginProcessor" class="madvirus.spring.chap03.LoginProcessor"/>
   
    <!-- 스프링 컨텍스트 이벤트 객체만들기 -->
    <bean id="memberService" class="madvirus.spring.chap03.MemberService"/>
    <bean class="madvirus.spring.chap03.CustomeventListener"/>
   
</beans>

==================================결과값=====================================

1. Main (메시지 소스를 이용한 메시지 국제화 처리)

2. Main02 (메시지 소스를 이용한 메시지 국제화 처리) - locale 처리

3.클래스내에서 메시지 소스를 사용

4.스프링 컨텍스트 이벤트 객체만들기


'스프링3.0' 카테고리의 다른 글

Spring3.0 DI 3  (0) 2012.05.14
스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
Spring3.0 DI AOP  (0) 2012.05.14
스프링 3.0 강좌  (0) 2012.05.11
Posted by 사라링

Spring3.0 Di 2

2012. 5. 14. 19:06

chap01.zip chap02.zip
컨트롤+ 스페이스바 = 이클립스 단축키

==================================이론======================================

스프링 컨테이너


BeanFactory 인터페이스

  FileSystemResource        : 파일 시스템의 특정 파일로부터 정보를 읽어 온다.
  InputStreamResource       : InputStream 으로 부터 정보를 읽어온다.
  ClassPathResource          : 클래스패스(src) 에있는 자원으로부터 정보를 읽어온다.
  UrlResource                   : 특정 URL로부터 정보를 읽어온다.
  ServletContextResource    : 웹 어플리케이션의 루트 디렉터리를 기준으로 지정한 경로에 위치한 자원으로 부터 정보를 읽어온다.


ApplicationContext 인터페이스
WebApplicationContext 인터페이스
  ClassPathXmlApplicationContext    : 클래스에 위치한 XML 파일로부터 설정 정보를 로딩한다.
  FileSystemXmlApplicationContext   : 파일 시스템에 위치한 XML 파일로부터 설정 정보를 로딩한다.
  XmlWebApplicationContext            : 웹 어플리케이션에 위치한 XML 파일로 부터 설정 정보를 로딩한다.

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

의존관계설정

(1)생성자 방식
 



(2)프로퍼티 설정 방식

<!-- 프로퍼티 설정 방식 -->
<bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl">
     <property name="articleDao">
            <ref bean="mysqlArticleDao"/>           
        </property>
    </bean>
<bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>


(3)XML 네임스페이스를 이용한 프로퍼티 설정

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

<bean id="monitor" class="madvirus.spring.chap02.SystemMonitor" p:periodTime="10" p:sender-ref="smsSender"/>
<bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>   

주의!!
p:프로퍼티이름 형식을 사용할 경우 이름이 Ref로 끝나는 프로퍼티에 대해서는 설정할 수가 없다. 따라서, 이런 경우에는 <property> 태그를 이용해서 값을 설정해주어야한다.


(4)룩업 메서드 인젝션 방식

룩업 메서드는 다음과 같은 규칙을 따라야 한다.

* 접근 수식어가 public 이나 protected 여야 한다.
* 리턴 타입이 void가 아니다.
* 인자를 갖지않는다.
* 추상 메서드여도(abstract) 된다. = 추상메서드 추상클래스여야한다.
*  final이 아니다.


(5)임의 빈 객체 전달

한번밖에 호출못한 ID가없기때문.
별로 좋은방법은 아니다.



콜렉션 타입 프로퍼티 설정

<list> : java.util.List                    : List 타입이나 배열에 값 목록을 전달할 때 사용된다.
<map>: java.util.Map                 : Map 타입에 <키,값> 목록을 전달 할 때 사용된다.
<set>: java.util.Set                     : Set 타입에 값 목록을 전달할 때 사용된다.
<properties>: java.util.Properties : Properties 타입에 <프로퍼티이름, 프로퍼티값> 목록을 전달할 때 사용된다.


(1) List 타입과 배열

<!-- List 타입 프로퍼티 설정 -->
<bean name="performanceMonitor" class="madvirus.spring.chap02.PerformanceMonitor">
   <property name="deviations">
       <list//<list value-type="java.lang.Double"> 로 리스트에 타입을 명시해도 된다.
            //제네릭표현 Double시
           <value type="java.lang.Double">0.2</value>
           <value type="java.lang.Double">0.3</value>
       </list>
   </property></bean> 


<!-- List 타입 프로퍼티 설정 -->
<bean name="performanceMonitor" class="madvirus.spring.chap02.PerformanceMonitor">
   <property name="deviations">
       <list>
            //ref 태그로 객체목록을 전달받는다.
           <ref bean="monitor"/>
         <ref bean="smsSender"/>
         <bean class="madvirus.spring.chap02.HeaderFiter"/> //임의 객체를 List에 전달할수도있다.
       </list>
   </property>

 </bean>  

<bean id="monitor" class="madvirus.spring.chap02.SystemMonitor" />
<bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>  



(2) Map 타입

Object형이기때문에 제네릭 표현이가능
key - Object
Value - Object

<bean name="handlerFactory" class="madvirus.spring.chap02.ProtocolHandlerFactory">
   <property name="handlers">
      <map>
            <entry>
               <ket><value>soap</value></key> //키값
               <ref bean="soapHandler"/>  //값
            </entry>
            <entry>
                <key><value>rest</value></key>
                <ref bean="restHandler"/>
            </entry>
            <entry>
                <key><키태그>...</키태그></key>            
                         <값태그>...</값태그>
            </entry>
      </map>
   </property>
</bean>

<ref> - 다른 스프링 빈 객체를 키로사용
<bean> - 임의 빈 객체를 생성해서 키로 사용
<value> - 래퍼타입이나 String 을 키로 사용
<list>,<map>,<props>,<set> - 콜렉션 객체를 키로 사용
<null> - null값을 키로 사용

//키와 값의 속성을 지정
<map key-type="jana.lang.Integer" value-type="java.lang.Double">



(3) Properties 타입 : 특별한 타입의 Map 으로 키와 값 모두 String 인 맵으로 보통 Properties 클래스는 환경변수나 설정정보와 같이 상황에 따라 변경되는 값을 저장하기 위한 용도로 주로 사용된다.

String으로만 처리하기때문에 제네릭안함
key - String
Value - String

<bean name="client" class="madvirus.spring.chap02.BookClient">
   <property name="config">
      <props>
            <prop key="server">192.168.1.100</prop>
            <prop key="connectionTimeout">5000</prop>
      </props>
   </property>
</bean>


(4) Set 타입

중복값을 허용하지 않는다.
중복값을 허용하지 않는 경우외에는 보통 리스트 사용을 많이함.

<property name="subset">
    <set value-type="java.lang.Integer">
         <value>10</value>
         <value>20</value>
         <value>30</value>
    </set>
</property>

<ref> - 다른 스프링 빈 객체를 키로사용
<bean> - 임의 빈 객체를 생성해서 키로 사용
<value> - 래퍼타입이나 String 을 키로 사용
<list>,<map>,<props>,<set> - 콜렉션 객체를 키로 사용
<null> - null레퍼런스를 값으로 사용

==================================프로젝트======================================
예제.
madvirus.spring.chap02
     Article (객체형식을 지정할 용도)
     ArticleDao (인터페이스 insert메소드)
     Command (인터페이스 execute메소드)
     CommandFactory (인터페이스 createCommand 메소드)
     CommandFactoryImpl (CommandFactory를 구현 createCommand메소드 구현)
     Main (기본 프로퍼티 설정)
     Main02 (XML네임스페이스를 이용한 프로퍼티 설정)
     Main03 (룩업 메서드 인젝션 방식)
     Main04 (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
     PerformanceMonitor (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
     Processor (getCommandFactory메서드를 통해 CommandFactory를 객체생성 createCommand(commandName)
                      로 Command객체를 생성 execute메서드실행)
     SmsSender (객체형식을 지정할 용도)
     SomeCommand (Command 를 구현  execute메서드 구현)
     SystemMonitor (XML네임스페이스 출력부분)
     WriteArticleService (인터페이스 write메소드)
     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
applicationContext.xml (DI(Dependency Injection 처리): 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)

==================================코드======================================
예제.
madvirus.spring.chap02
     Article (객체형식을 지정할 용도)
package madvirus.spring.chap02;

public class Article {
}

     ArticleDao (인터페이스 insert메소드)
package madvirus.spring.chap02;

public interface ArticleDao {
    void insert(Article article);
}

     Command (인터페이스 execute메소드)
package madvirus.spring.chap02;

public interface Command {   
    void execute();
}

     CommandFactory (인터페이스 createCommand 메소드)
package madvirus.spring.chap02;

public interface CommandFactory {

    Command createCommand(String commandName);
}

     CommandFactoryImpl (CommandFactory를 구현 createCommand메소드 구현)
package madvirus.spring.chap02;

public class CommandFactoryImpl implements CommandFactory{

    @Override
    public Command createCommand(String commandName) {
        if(commandName.equals("some")){
            return new SomeCommand();
        }
        return null;
    }
}

     Main (기본 프로퍼티 설정)
package madvirus.spring.chap02;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Main {
    public static void main(String[] args){
        Resource resource = new ClassPathResource("applicationContext.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        //WriteArticleService articleService = (WriteArticleService)beanFactory.getBean("writeArticleService");
       
        //제네릭표현
        WriteArticleService articleService = beanFactory.getBean("writeArticleService",WriteArticleService.class);
       
        articleService.write(new Article());
    }
}

     Main02 (XML네임스페이스를 이용한 프로퍼티 설정)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main02 {
    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //XML 네임 스페이스를 이용한 프로퍼티 설정
        SystemMonitor articleService = (SystemMonitor)context.getBean("monitor");
        System.out.println(articleService);
    }
}

     Main03 (룩업 메서드 인젝션 방식)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main03 {
    public static void main (String[] args){
        String[] configLocations = new String[] {"applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //룩업 메서드 인젝션 방식
        Processor processor = context.getBean("processor",Processor.class);
        processor.process("some");
    }
}

     Main04 (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
package madvirus.spring.chap02;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main04 {
    public static void main(String[] args){
        String[] configLocations = new String[]{"applicationContext.xml"};   
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //List 타입 프로퍼티 설정
        PerformanceMonitor monitor= (PerformanceMonitor)context.getBean("performanceMonitor");
        System.out.println(monitor);
    }
}

     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
package madvirus.spring.chap02;

public class MySQLArticleDao implements ArticleDao{
   
    @Override
    public void insert(Article article){
        System.out.println("MySQLArticleDao.insert()실행");
    }   
}

     PerformanceMonitor (콜렉션 타입 프로퍼티 설정 - List타입과 배열)
package madvirus.spring.chap02;

import java.util.List;

public class PerformanceMonitor {
   
    private List<Double> deviations;
   
    public void setDeviations(List<Double> deviations){
        this.deviations = deviations;
    }

    @Override
    public String toString() {
        return "PerformanceMonitor [deviations=" + deviations + "]";
    }
}

     Processor (getCommandFactory메서드를 통해 CommandFactory를 객체생성 createCommand(commandName) 로 Command객체를 생성 execute메서드실행
package madvirus.spring.chap02;

public class Processor {

    public void process(String commandName){
        CommandFactory factory = getCommandFactory();
        Command command = factory.createCommand(commandName);
        command.execute();
    }
   
    protected CommandFactory getCommandFactory(){
        return null;
    }
}

     SmsSender (객체형식을 지정할 용도)
package madvirus.spring.chap02;

public class SmsSender {
}

     SomeCommand (Command 를 구현  execute메서드 구현)
package madvirus.spring.chap02;

public class SomeCommand implements Command{

    @Override
    public void execute() {
        System.out.println("SomeCommand executed.");
    }   
}

     SystemMonitor (XML네임스페이스 출력부분)
package madvirus.spring.chap02;

public class SystemMonitor {
   
    private long periodTime;
    private SmsSender sender;
   
   
    public void setPeriodTime(long periodTime) {
        this.periodTime = periodTime;
    }
    public void setSender(SmsSender sender) {
        this.sender = sender;
    }
   
    @Override
    public String toString() {
        return "SystemMonitor [periodTime=" + periodTime + ", sender=" + sender
                + "]";
    }
}

     WriteArticleService (인터페이스 write메소드)
package madvirus.spring.chap02;

public interface WriteArticleService {
    void write(Article article);
}

     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
package madvirus.spring.chap02;

public class WriteArticleServiceImpl implements WriteArticleService{

    private ArticleDao articleDao;
   
    //의존 관계 설정 방식: 프로퍼티
    public void setArticleDao(ArticleDao articleDao){
        this.articleDao = articleDao;
    }   
   
    @Override
    public void write(Article article) {       
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }   
}

applicationContext.xml (DI(Dependency Injection) 처리 : 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 프로퍼티 설정 방식 -->
    <bean name="writeArticleService" class="madvirus.spring.chap02.WriteArticleServiceImpl">
        <property name="articleDao">
            <ref bean="mysqlArticleDao"/>           
        </property>
    </bean>
    <bean name="mysqlArticleDao" class="madvirus.spring.chap02.MySQLArticleDao"/>
   
    <!-- XML 네임스페이스를 이용한 프로퍼티 설정 -->
    <!-- p:periodTime p:sender  프로퍼티명  -->
    <!-- ref="smsSender" 빈객체 전달 -->
    <bean id="monitor" class="madvirus.spring.chap02.SystemMonitor" p:periodTime="10" p:sender-ref="smsSender"/>
    <bean id="smsSender" class="madvirus.spring.chap02.SmsSender"/>   
   
    <!-- 룩업 메서드 인젝션 방식 -->
    <bean id="processor" class="madvirus.spring.chap02.Processor">
        <!-- 메서드인젝션 -->
        <lookup-method name="getCommandFactory" bean="commandFactory"/>       
    </bean>
    <bean id="commandFactory" class="madvirus.spring.chap02.CommandFactoryImpl"/>   
   
    <!-- List 타입 프로퍼티 설정 -->
    <bean name="performanceMonitor" class="madvirus.spring.chap02.PerformanceMonitor">
        <property name="deviations">
            <list>
                <value type="java.lang.Double">0.2</value>
                <value type="java.lang.Double">0.3</value>
            </list>
        </property>
    </bean>
</beans>

==================================결과값=====================================
1. 프로퍼티 설정 방식



2. XML네임스페이스를 이용한 프로퍼티 설정


3. 룩업 메서드 인젝션 방식


4. 콜렉션 타입 프로퍼티 설정 - List타입과 배열


'스프링3.0' 카테고리의 다른 글

스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 DI AOP  (0) 2012.05.14
스프링 3.0 강좌  (0) 2012.05.11
스프링 3.0 동영상 강좌.  (0) 2012.05.09
Posted by 사라링

Spring3.0 DI AOP

2012. 5. 14. 19:05
Spring 스프링을 간단히 말하면 엔터프라이즈 어플리케이션에서 필요로 하는 기능을 제공하느 프레임워크

* 경량 컨테이너 (EJB보다는 경량 하지만 struts같은것보단 무거움 대신기능은많음)
* DI (!중요 : 객체를 주입,넣어주는 역할, struts에서는 인터셉터설정해서 하던것을 설정만해주면 자동으로 넣어줌)
* AOP : 인터셉터보다 범위확장  (Struts2 인터셉터 => 액션의 동작의 전처리 후처리)
* POJO
* 스프링은 트랜잭션 처리를 위한 일관된 방법을 제공한다.
* 스프링은 영속성과 관련된 다양한 API를 지원한다.
* 스프링은 다양한 API에 대한 연동을 지원한다.

단점
* EJB 보단 가볍고 쉽지만 다른것들에 비해서는 어렵고 무겁다.

자바프로젝트만들기




Dependency Injection (DI) : 면접볼때 물어볼수있을정도로 중요함.

설정만으로 객체를 주입시켜줌







==================================프로젝트======================================
예제.
madvirus.spring.chap01
     Article (자바빈같은용도)
     ArticleDao (인터페이스 insert메소드)
     Main (applicationContext.xml)
     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
     WriteArticleService (인터페이스 write메소드)
     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
applicationContext.xml (DI(Dependency Injection) 처리 : 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)


==================================코드======================================
예제.
madvirus.spring.chap01
     Article (자바빈같은용도)
package madvirus.spring.chap01;

public class Article {
}

     ArticleDao (인터페이스 insert메소드)
package madvirus.spring.chap01;

public interface ArticleDao {
    void insert(Article article);
}

     Main (applicationContext.xml)
package madvirus.spring.chap01;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

 public class Main {
    public static void main(String[] args){
        Resource resource =new ClassPathResource("applicationContext.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        WriteArticleService articleService =  (WriteArticleService)beanFactory.getBean("writeArticleService");
       
         articleService.write(new Article());
    }       
}

     MySQLArticleDao (ArticleDao 를 구현 insert메소드 구현)
package madvirus.spring.chap01;

public class MySQLArticleDao implements ArticleDao{
   
    @Override
    public void insert(Article article){
        System.out.println("MySQLArticleDao.insert()실행");
    }   
}

     WriteArticleService (인터페이스 write메소드)
package madvirus.spring.chap01;

public interface WriteArticleService {
    void write(Article article);
}

     WriteArticleServiceImpl (WriteArticleService를 구현한 write메소드 구현)
package madvirus.spring.chap01;

public class WriteArticleServiceImpl implements WriteArticleService{
   
    private ArticleDao articleDao;
   
    //생성자
    public WriteArticleServiceImpl(ArticleDao articleDao){
        this.articleDao = articleDao;
    }
   
    @Override
    public void write(Article article) {
        System.out.println("WriteArticleServiceImpl.write() 메서드 실행");
        articleDao.insert(article);
    }
}

applicationContext.xml (DI(Dependency Injection) 처리 : 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성)
<?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-3.0.xsd">

    <!-- DI(Dependency Injection) 처리 -->
    <!-- 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성  -->
    <bean name="writeArticleService" class="madvirus.spring.chap01.WriteArticleServiceImpl">
        <!-- 생성자에 객체 전달 -->
        <constructor-arg>
            <!-- 생성자가  class="madvirus.spring.chap01.MySQLArticleDao" 를 받을수 있도록 등록 -->
            <ref bean="articleDao"/>
        </constructor-arg>
    </bean>
   
    <bean name="articleDao" class="madvirus.spring.chap01.MySQLArticleDao"/>
</beans>

==================================결과값======================================





AOP : struts의 인터셉터보다 규모가 커졌다. 적용범위가 넓다.

        여러부분에 걸쳐서 공통으로 사용되는 기능이 필요한 경우가 있다. 

        예를들어 로깅, 트랙잭션처리, 보안과 같은 기능을 처리






proxy : 대리객체  LogginAspect를 호출해줌



================================프로젝트====================================
예제.

madvirus.spring.chap01

     LoggingAspect (공통관심사항 실제처리할부분)

     MainForAop (실행할부분)

commonConcern.xml (공통관시사항 설정,적용)


==================================코드======================================

예제.

madvirus.spring.chap01

     LoggingAspect (공통관심사항 실제처리할부분)

package madvirus.spring.chap01;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;

public class LoggingAspect {

    private Log log = LogFactory.getLog(getClass());
   
    public Object logging (ProceedingJoinPoint joinPoint) throws Throwable{

        log.info("기록시작");

        StopWatch stopWatch = new StopWatch();
        try{

            stopWatch.start();
        Object retValue = joinPoint.proceed();
            return retValue;

        }catch(Throwable e) {
            throw e;
        }finally{

            stopWatch.stop();
            log.info("기록종료");
            log.info(joinPoint.getSignature().getName() + "매서드 실행시간 : " + stopWatch.getTotalTimeMillis());

        }
    }
}

     MainForAop (실행할부분)

package madvirus.spring.chap01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainForAop {

    public static void main(String[] args){
        String[] configLocations = new String[] {"applicationContext.xml","commonConcern.xml"};
       
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
        WriteArticleService articleService = (WriteArticleService) context.getBean("writeArticleService");
       
        articleService.write(new Article());
    }   
}

applicationContext.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-3.0.xsd">

    <!-- DI(Dependency Injection) 처리 -->
    <!-- 객체의 외부에서 두개의 의존성있는 객체의 관계를 형성  -->
    <bean name="writeArticleService" class="
madvirus.spring.chap01.WriteArticleServiceImpl">
        <!-- 생성자에 객체 전달 -->
        <constructor-arg>
            <!-- 생성자가  class="madvirus.spring.chap01.MySQLArticleDao" 를 받을수 있도록 등록 -->
            <ref bean="articleDao"/>
        </constructor-arg>
    </bean>
   
    <bean name="articleDao" class="madvirus.spring.chap01.MySQLArticleDao"/>
</beans>


commonConcern.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
      
    <bean id="logging" class="madvirus.spring.chap01.LoggingAspect"/>       
    <aop:config>
        <!-- 공통관시사항 설정  -->
        <aop:pointcut id="servicePointcut" expression="execution(* *..*Service.*(..))"/>
        <!-- 공통관심사항 실제적용 -->
        <aop:aspect id="loggingAspect" ref="logging">
            <aop:around pointcut-ref="servicePointcut" method="logging" />
        </aop:aspect>
    </aop:config>
</beans>


==================================결과값======================================


'스프링3.0' 카테고리의 다른 글

스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
스프링 3.0 강좌  (0) 2012.05.11
스프링 3.0 동영상 강좌.  (0) 2012.05.09
Posted by 사라링

HTML 이란.

2012. 5. 14. 10:28

03

HTML5의 모든 것

, , 2010-02-3

애플 iPad 논란과 유튜브 HTML5 지원 이슈와 Flash vs. HTML 5 이슈를 거치면서 HTML 5에 대한 반응이 국내에서 커지고 있군요.

지난 주에 했던 블로터 포럼 인터뷰가 어제 올라간 후 저에게 이런 저런 문의를 해 주신 분들이 많습니다. 제가 가지고 있는 지식이나 경험은 짧지만 최대한 가지고 있는 것을 하나의 글에 제공해 드려 보도록 하겠습니다. 아래 글은 개인적으로 관리하던 HTML 자료 모음집을 합친 것입니다.

트위터를 검색하면 맨 위에 있는 Twitter의 모든 것 처럼 HTML5에 궁금증이 있으신 분들을 위해 모아서 공유 합니다. 앞으로 좋은 자료를 찾는 대로 계속 업데이트 해 보겠습니다. 업데이트 부분만 보시려면 여기를 누르세요.

I. HTML 5 소개

HTML 5는 W3C에서 만들고 있는 차세대 웹 표준으로서 마이크로소프트, 모질라, 애플, 구글, 오페라 등 모든 웹 브라우저 벤더가 참여하고 있는 산업 표준이기도 합니다. 2004년 WHATWG의 초안으로 부터 시작된 이 표준안은 시맨틱 마크업, 편리한 웹폼 기능, 리치 웹 애플리케이션 API 들을 담고 있으며 2007년 부터 W3C HTML W/G에서 표준안이 만들어 지고 있습니다.

HTML5의 주요 목적은 과거 HTML의 호환성을 유지하면서 웹 개발자들이 실질적으로 부딫히는 문제를 해결 하고 HTML 문서가 좀더 의미 있으면서도 리치 웹 애플리케이션 기능을 수행할 수 있는 범용 표준을 만드는 데 있습니다. 즉, 웹 문서 기반을 그대로 유지하면서 웹 브라우저 간의 상호 운용성을 위한 세부적인 지침을 담고 있으며 필요에 따라 각 이해 관계자를 위한 별도 문서도 제작해서 배포하고 있습니다.

HTML5는 향후 웹 브라우저의 가장 표준 기반 렌더링 엔진의 문서 타입이 될 것입니다.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>예제 문서</title>
  </head>

  <body>
    <p>예제 단락</p>
  </body>
</html>

1. 효율적인 마크업

HTML 5에서는 그동안 모호하던 웹 브라우저 구현에 대한 상세 스펙을 제공합니다. 따라서, 웹 개발자들이 과거 스펙의 호환성을 유지하면서도 향후 버전에 정확한 기능 사용이 가능합니다. 이미 구글 및 애플 등 많은 사이트들이 HTML5로 문서 작업을 하고 있습니다.

또한, HTML 5에서는 기존의 HTML4 보다 확장된 태그들을 지원합니다. 특히, 문서 구조에 적합하게 header, footer, nav, section 같은 구조화 마크업을 사용할 수 있습니다.

time, mark, meter, datalist 등과 같은 특정 의미 기반 태그들도 추가로 지원 됩니다. 여전히 많이 쓰이고 있는 b의 경우 b는 키워드, i는 학명에 사용하도록 기존 많이 사용하는 요소도 그대로 이용할 수 있습니다.

하지만, CSS로 완전 대체 가능한 big, center, font, s, strike 같은 스타일 기반 요소는 완전히 없어집니다. 또한, frame과 applet, acronym 같은 부정적인 요소들도 사용하지 않습니다.

2. 편리한 웹 폼(WebForm) 기능

HTML5는 개발자의 수고를 들어 줄 Form 기능 개선을 담고 있습니다. input 태그의 각종 type 속성이 추가되어 다양한 기능을 제공해 줍니다.

datetime 속성값을 사용하면 달력을 웹 브라우저에서 제공해 주며, range 속성은 스크롤바를, url은 웹 사이트 목록, email은 메일 주소 유효성 확인을 해 주기도 합니다. color 속성은 색상표를 별도 개발 없이 사용할 수 있습니다.

Form 양식은 모두 유효성 확인 기능을 켜거나 끌 수 있어, 폼 작업 시 늘 하던 자바스크립트 유효성 검증 개발 시간을 줄여주어 개발자들의 효율적인 개발이 가능합니다.

3. 리치 웹 미디어

HTML 5는 웹 어플리케이션 작성에 도움을 줄 다양한 API를 제공 합니다. 새로 만든 HTML 요소들과 함께 더 좋은 어플리케이션 개발에 사용할 수 있습니다.

  • 2차원 그래픽 API에 사용할 수 있는 canvas 요소.
  • 내장 비디오 및 오디오 재생을 위한 video, audio 요소.
  • 내장 저장소. 키/값이나 SQL 기반 데이터베이스 지원을 위한 기능.
  • 오프라인 웹 애플리케이션 기반 API.
  • 웹 애플리케이션이 독립적으로 특정 프로토콜 및 미디어 형식을 등록할 수 있는 API.
  • contenteditable 속성과 함께 지원 되는 편집 API 기능.
  • draggable 속성과 함께 지원 되는 드래그앤 드롭 API 기능.
  • 페이지 앞/뒤 네비게이션을 지원할 방문 기록 표시용 API 기능. (보안 제한 모델이 있음)
  • (원격) 다중 메시징 처리 기능.

특히, 멀티미디어 가능을 제공하는 Audio, Video, Canvas는 기존의 플러그인 기능을 대체할 수 있는 요소로서 웹의 일부로 자리 잡았ㅇ으며, 내장 저장소(DOM Storage)와 오프라인 캐시(Offline Cache)등은 웹 문서를 로컬에 소프트웨어 처럼 설치할 수 있도록 하고 버전 업데이트를 할 수 있게 하여 온라인 상태에서 항상 웹 서버에 접속 해야하는 웹 애플리케이션의 문제를 해결해 줍니다.

II. HTML 5 표준 문서 소개

웹 표준을 만드는 웹 컨소시움(W3C)의 표준 문서들은 대체로 읽기 어려운 것으로 알려져 있다. HTML 워킹그룹에서는 이용자와 가장 친숙하게 접근할 수 있도록 이러한 문제점을 보완하기 다양한 관점에서 각기 다른 표준 문서를 제공하고 있습니다.

본 문서는 HTML5를 접하는 이용자들을 위해 어떠한 표준 문서가 제작되고 있는지 소개해 주고자 한다. 2009년 4월 이전에는 아래 소개된 문서들이 HTML 5 표준안에 함께 담겨 있었으나 분량이 많고 기존 마크업 기반 내용과 혼란을 준다는 측면에서 분리해서 관리하고 있습니다.

1. 일반 문서

1.1 HTML 5 :A vocabulary and associated APIs for HTML and XHTML
HTML 5의 원래 표준안으로 분량이나 내용이 모두 웹 브라우저 개발자를 위해서 만들어져 있다. 가급적이면 HTML 5 표준안 보다 아래에 있는 대로 관점에 따라 적당한 문서를 보는 것이 좋겠다.

1.2 HTML 4와 HTML 5의 차이점 (한국어)
HTML 5 differences from HTML 4라는 문서는 기존 HTML에 익숙하던 사람들이 HTML5에서 무엇이 바뀌었는지 알 수 있도록 만든 소개 문서이다. 이 문서는 HTML 5 입문자들이 읽기에 적당하며 연도별 주요 변경 내용도 담고 있으며 한국어로 번역되어 제공된다.

1.3 HTML 디자인 원칙
이 문서는 HTML5 표준을 만드는 데 있어, 의사 결정의 기본 원칙이 되는 사항을 모아 두고 있다.

  1. 호환성 – 기존의 HTML 문서를 최대한 지원, 단계적 기능 축소(Graceful degradation), 기존 기능 재사용 및 엄격한 잣대를 대지 않는 것
  2. 유용성 – 실제 웹 개발자들이 겪고 있는 가장 중요한 문제를 순위에 따라 나누되 문제점을 분리해서 독립적으로 해결 함.
  3. 상호 호환성 – 브라우저 엔진 호환을 위해 최대한 자세한 스펙을 기술하되 복잡하지 않고 오류 처리 방법을 꼭 기술.
  4. 보편적 접근성 – 미디어 포맷 독립성, 전 세계 언어 지원, 웹 접근성 보장

2. 웹 퍼블리셔

2.1 HTML5 표준안(웹 개발자 관점)
기존 HTML 5 스펙은 웹 브라우저 개발 회사를 위해 기술된 표준안이다. 개발자 관점에서 무엇이 어떻게 바뀌었고 어떻게 사용할 수 있는지 보여 줄 수 있는 문서가 필요하다. 과거 W3C 표준안들의 문제점이 바로 이용자가 아닌 개발자 위주로 만들어져 있어 읽기 어려웠다는 것이다. 이 문서는 바로 이용자 즉, 웹 개발자를 위한 스펙이다.

2.2 HTML 마크업(저작자 관점)
이 문서는 HTML5 표준안(웹 개발자 관점)의 하부 문서로서 HTML 문서를 주로 저작하는 웹 퍼블리셔 혹은 HTML 코더를 위해 만들어진 문서이다.

2.3 HTML Microdata
마이크로 데이터는 흔히 마이크로 포맷으로 알려진 시맨틱 데이터 정의를 범용적으로 만든 것이다. itemprop라는 속성을 통해 사용자 정의로 의미를 부여해 검색 엔진이나 시맨틱 엔진이 이를 처리할 수 있게 하였다. 사실상 비슷한 역할을 하는 RDFa와 함께 논의 되고 있는 중이다.

3. Rich UI 개발자

3.1 HTML Canvas 2D API
HTML5의 Canvas 태그 내 각종 객체를 그리고 생성하는 데 필요한 API를 기술하고 있다.

3.2 HTML Canvas 2D Context
HTML5의 Canvas 태그 내 각종 객체를 회전, 변환하고 그레디언트, 이미지 생성 등 각종 효과를 주는 기능 부분을 기술하고 있다.

참고로 Mozilla의 Canvas 튜토리얼이나 애플의 Canvas 예제를 보면 편할 것이다.

4. 웹 애플리케이션 및 백엔드 개발자

4.1 Server-Sent Events
웹 서버로 부터 전달(Push)되는 데이터 예를 들어 SMS 같은 것을 받을 수 있도록 EventSource를 정의하고 이벤트를 기다릴 수 있도록 하는 API를 기술하고 있다.

4.2 HTML5 Communications
이 스펙은 기존 Ajax의 단점으로 알려진 크로스 도메인 문서 접근을 가능하게 해 주는 스펙이다. 마이크로소프트의 XHR 때문에 약간 논의가 지지부진한 면이 있지만 텍스트를 위한 서버 통신을 지원해 준다. 물론 보안 사항에 대한 부분도 중요하게 다루어지고 있다.

4.3 Web SQL Database
자바 스크립트를 이용해 웹 브라우저 내장 데이터베이스에 SQL을 통해 질의하는 API이다. 오프라인 웹 애플리케이션 개발이나 모바일에서 로컬 데이터 캐싱이 필요할 때 유용하게 사용할 수 있으며, 일반적인 DB 라이브러리 수준의 메소드를 지원해 준다.

4.4 IndexedDB
IndexedDB는 Key와 Value를 기반한 데이터 스토어를 제공하는 새로운 웹 기반 클라이언트 데이터 베이스 형식으로 Web SQL Database와 경쟁을 하는 스펙으로 Mozilla와 Oracle에서 지지 하고 있다.

4.5 Web Sockets API
한 웹 페이지에서 서로 다른 서버에 있는 웹 페이지에 양방향 통신을 할 수 있는 별도 프로토콜을 정의할 수 있는 API이다.

4.6 Web Workers
웹 애플리케이션이 주 문서와 병렬적으로 스크립트를 백그라운드로 수행할 수 있게 해 주는 API. 쓰레드 기반 메시지 처리를 가능하게 해 준다. CPU 부하를 많이 잡는 작업을 여러 워커(worker)로 나누어 작업하거나 클라이언트 DB를 업데이트 하거나 나누어서 작업이 가능한 자바 스크립트 API를 제공해 준다. 흥미로운 점은 암호화 작업에 대한 유즈케이스를 담고 있어서 웹 브라우저들이 지원만 한다면 향후 전자 서명 기능을 제공해 줄 수도 있을 듯.

III. HTML 5 관련 발표 자료 및 글모음

본 문서는 제가 2005년 부터 HTML 5에 관심을 가져 오면서 만들었던 자료와 블로그 글 모음입니다. 예전 자료들인 만큼 낡은 내용도 있지만, 그간의 발전 과정 및 관련 이슈를 상세하게 다루고 있으므로 HTML 5의 역사를 파악하는데 도움이 될 것 입니다.

1. 발표 자료

HTML5와 모바일 웹 (2009)

View more presentations from Channy Yun.

HTML5 역사와 현황 (2008)

History and Status of HTML5
View more presentations from Channy Yun.

웹 표준의 미래 – HTMl5 (2006)

View more presentations from Channy Yun.

2. 블로그 글 모음

  1. IE9, HTML5 준수한다! 2009-11-19
  2. 요즘 HTML5에 무슨 일이… 2009-09-27
  3. 모바일과 HTML5 – 미래웹포럼 후기 2009-09-10
  4. HTML5 킬러앱은 ‘모바일’? 2009-08-28
  5. 마크업의 미래에 대한 오해 2009-08-24
  6. 구글은 왜 on2를 샀을까? 2009-08-07
  7. XHTML2.0 역사속으로? 2009-07-03
  8. Mozilla, 오픈 비디오 지원 10만불 쏜다! 2009-01-28
  9. 웹 애플리케이션은 전쟁 중! 2008-02-28
  10. 웹 표준, 나쁜 뉴스와 좋은 뉴스 2008-01-24
  11. HTML5에서 미디어 포맷 논쟁 중… 2007-12-12
  12. 반론: 차세대 웹은 브라우저를 초월하여… 2007-11-28
  13. 파이어폭스 SVG 비디오 시연 2007-08-22
  14. HTML5를 주목해야 하는 이유 2007-07-11
  15. HTML5와 HTML4의 차이점 2007-07-01
  16. 웹어플리케이션 전쟁 본격화 되나? 2007-06-07
  17. W3C HTML 워킹 그룹 부활! 2007-03-14
  18. HTML5와 웹 표준 전망에 대한 발표 자료 2006-12-04
  19. 팀 버너스리, 위기의 W3C 구하기 (2) 2006/11/09
  20. 팀 버너스리, 위기의 W3C 구하기 (1) 2006/11/03
  21. RFC: 새 HTML에 대한 의견 청취 2006-11-10
  22. 2차 웹 브라우저 전쟁, 관전 포인트는? 2006-11-01
  23. WHATWG의 도전 2005-9-15

3. 외부 기고

4. 만화

HTML 5가 대두되면서 기존 XHTML과의 관계에 대한 이야기를 만화로 만든 것으로 Jeremy Keith 원작이며 마크업의 미래에 대한 오해에 한국어 전문이 있다.

IV. HTML5 외부 자료

본 문서는 HTML5에 대한 외국에 있는 각종 웹 사이트, 튜토리얼, 데모, 참고 문헌 등을 모은 것입니다. 모두 영문으로 되어 있지만 많은 것을 얻을 수 있습니다. 관련 자료가 한국어로도 제공됐으면 하는 바램이 있습니다.

1. 웹 사이트

  • HTML5 Rocks – 구글이 만든 예제 슬라이드, 코드 샘플 등
  • HTML5 Games – HTML5로 만든 웹 기반 게임 목록
  • HTML5 Test- 웹 브라우저의 HTML5 지원 점수 확인 사이트
  • HTML5 Doctor – HTML5 이용 시 궁금증에 대한 해답을 제공.
  • HTML5 Gallery – HTML5 문서 형식으로 만든 웹 사이트 모음
  • HTML5 Tutorials- 간단한 예제를 튜토리얼 형식으로 소개
  • Planet HTML5 – HTML5 관련 전문가 블로그 모음

2. 문서 저작 튜토리얼

HTML5 기반 WordPress 테마

3. 리치 기능 데모

  1. SketchPad – HTML 5 Canvas 기반 그래픽 저작 도구 – by Colorjack
  2. Sublime Video Player – HTML 5 Video Player (H.264만 지원)
  3. RGraph – HTML5 Canvas Graph 라이브러리
  4. Offline Image Editor and Uploader – Drag & Drop API, DOM Storage, Application Cache, Canvas, Cross Domain Sharing 기능 등을 활용. by Mozilla Hack
  5. HTML5 Adventure – Google I/O 2009 컨퍼런스 때 선 보였던 데모 모음.
  6. HTML 5 Demos and Examples Remy Sharp가 만드는 간단한 데모 사이트
  7. Mozilla Hack Demos Firefox에 탑재된 HTML5 등 신 기능 기반 데모 모음

4. 참고 자료

각 웹 브라우저에서 HTML5의 기능을 어디까지 구현하고 있는 지 현황을 담은 문서를 제공한다.

  1. When can I use… HTML5, CSS3, SVG 등 최신 기술에 대한 브라우저 호환도표
  2. HTML5 Comparison of Layout Engines 위키피디아의 HTML5 기능별 렌더링 엔진 호환도표
  3. List of Known Implementations of HTML 5 in Web Browsers WHATWG에서 관리하고 있는 웹 브라우저 구현 문제점 목록
  4. HTML 5 coverage WHATWG 표준안 기초 호환 도표
  5. HTML5 Compatibility Quirksmode에서 관리하는 HTML5 DOM 관련 기능 호환표.
  6. HTML5 Cheat Sheet

V. 최신 소식 업데이트

이 부분은 본 가이드가 만들어진 후 추가 되는 부분을 작성한 곳입니다. 업데이트 링크를 사용할 수 있습니다. 원 글 내용 부터 가시려면 여기를 누르세요.

1. 실전 HTML5 가이드

국내 웹 표준 커뮤니티에서 HTML5 오픈 콘퍼런스를 개최하고 강사들이 발표 자료 및 실전 가이드를 공개하였습니다.

본 가이드는 HTML5의 기본 개념을 배우고 모바일 웹에서 실질적으로 사용할 수 있도록 다섯명의 발표자들이 각자 자원 봉사로 작성하였습니다. 총 5장으로 구성 되어 있으며, HTML5 소개 및 마크업, CSS3, HTML5 APIs 및 iPhone에서의 웹 앱 개발이 포함되어 있습니다.

A4크기로 총 170페이지이고, B5크기로 206페이지입니다. 우선 A4에서 출력가능한 PDF 파일을 배포합니다. 많은 이용 바랍니다.

실전 HTML5 가이드 다운로드(A4 인쇄용) | B5 인쇄용 CC nc nd

2. HTML5 강의 동영상

실전 HTML5 가이드 저자들이 HTML5 오픈 콘퍼런시 시 한 강의 동영상 전체를 다운로드해서 보실 수 있습니다.

3. HTML5 교육 과정

지난 8월에 웹 개발자를 위하여 HTML5에 대한 10일간의 개발 교육 과정을 운영하였습니다. 강의 자료 역시 다운로드 가능합니다. 대학 및 회사에서 HTML5 교육 과정에 관심이 있으시면 연락하시기 바랍니다.

4. W3C HTML5 한국어 관심 그룹

W3C와 W3C 한국 사무국에서 일본과 중국에 이어 HTML5에 대한 한국어 사용자의 논의를 활성화 하고, 이들 표준과 관련된 한국의 코멘트와 질문들을 모아 표준에 정의된 기술에 대한 특별한 유즈케이스(Use Case)를 정리하고자 W3C HTML 한국어 관심 그룹을 만들었습니다.

본 그룹은 메일링리스트에 가입함으로서 참여 가능하며, 가입하지 않더라도 전체 메일 보기를 통해 논의 내용을 볼 수 있습니다.

5. W3C HTML5 한국어판

국내 웹 표준 커뮤니티 중 하나인 클리어보스에서 작업한 W3C HTML5 명세서 한국어 번역판을 공개하였습니다. 웹 브라우저 엔진 개발자가 참조해야 하는 부분을 제외하고 일반적인 부분은 거의 모두 번역 되어 있습니다.

상단에 마우스를 보내면 영어, 한국어를 나누어 볼 수 있고 잘못된 부분이나 궁금한 내용은 HTML5 토론방에서도 활용 가능합니다. 검은태양(kipenzam)님의 주도로 번역 되었고, 스터디에 활용하기 위해 일부 마크업과 스타일 그리고 스크립트에 변경에 가해졌습니다.

단, 마크업을 다루는 사람들에게 필요한 내용이라고 판단되는 내용 위주로 번역이 진행되었기 때문에(브라우저 엔진 개발자가 읽어야 하는 부분 생략) 완역은 아닙니다. 또한, 일부 번역에 오류가 있을 수도 있습니다.


http://channy.creation.net/blog/776 펌

'HTML5.0' 카테고리의 다른 글

캔버스 이미지 뛰우기 .  (0) 2012.06.04
canvas 사이트 모음 .  (0) 2012.05.24
Canvas  (0) 2012.05.22
html4.0 을 html 5.0 으로 변환  (0) 2012.05.14
Aptana 설치  (0) 2012.05.14
Posted by 사라링
컬러 이름 16진수       색상     
red #FF0000  
crimson #DC143C  
firebrick #B22222  
maroon #800000  
darkred #8B0000  
brown #A52A2A  
sienna #A0522D  
saddlebrown #8B4513  
indianred #CD5C5C  
rosybrown #BC8F8F  
lightcoral #F08080  
salmon #FA8072  
darksalmon #E9967A  
coral #FF7F50  
tomato #FF6347  
sandybrown #F4A460  
lightsalmon #FFA07A  
peru #CD853F  
chocolate #D2691E  
orangered #FF4500  
orange #FFA500  
darkorange #FF8C00  
tan #D2B48C  
peachpuff #FFDAB9  
bisque #FFE4C4  
moccasin #FFE4B5  
navajowhite #FFDEAD  
wheat #F5DEB3  
burlywood #DEB887  
darkgoldenrod #B8860B  
goldenrod #DAA520  
gold #FFD700  
yellow #FFFF00  
lightgoldenrodyellow #FAFAD2  
palegoldenrod #EEE8AA  
khaki #F0E68C  
darkkhaki #BDB76B  
lawngreen #7CFC00  
greenyellow #ADFF2F  
chartreuse #7FFF00  
lime #00FF00  
limegreen #32CD32  
yellowgreen #9ACD32  
olive #808000  
olivedrab #6B8E23  
darkolivegreen #556B2F  
forestgreen #228B22  
darkgreen #006400  
green #008000  
seagreen #2E8B57  
mediumseagreen #3CB371  
darkseagreen #8FBC8F  
lightgreen #90EE90  
palegreen #98FB98  
springgreen #00FF7F  
mediumspringgreen #00FA9A  
teal #008080  
darkcyan #008B8B  
lightseagreen #20B2AA  
mediumaquamarine #66CDAA  
cadetblue #5F9EA0  
steelblue #4682B4  
aquamarine #7FFFD4  
powderblue #B0E0E6  
paleturquoise #AFEEEE  
lightblue #ADD8E6  
lightsteelblue #B0C4DE  
skyblue #87CEEB  
lightskyblue #87CEFA  
mediumturquoise #48D1CC  
turquoise #40E0D0  
darkturquoise #00CED1  
aqua #00FFFF  
cyan #00FFFF  
deepskyblue #00BFFF  
dodgerblue #1E90FF  
cornflowerblue #6495ED  
royalblue #4169E1  
blue #0000FF  
mediumblue #0000CD  
navy #000080  
darkblue #00008B  
midnightblue #191970  
darkslateblue #483D8B  
slateblue #6A5ACD  
mediumslateblue #7B68EE  
mediumpurple #9370DB  
darkorchid #9932CC  
darkviolet #9400D3  
blueviolet #8A2BE2  
mediumorchid #BA55D3  
plum #DDA0DD  
lavender #E6E6FA  
thistle #D8BFD8  
orchid #DA70D6  
violet #EE82EE  
indigo #4B0082  
darkmagenta #8B008B  
purple #800080  
mediumvioletred #C71585  
deeppink #FF1493  
fuchsia #FF00FF  
magenta #FF00FF  
hotpink #FF69B4  
palevioletred #DB7093  
lightpink #FFB6C1  
pink #FFC0CB  
mistyrose #FFE4E1  
blanchedalmond #FFEBCD  
lightyellow #FFFFE0  
cornsilk #FFF8DC  
antiquewhite #FAEBD7  
papayawhip #FFEFD5  
lemonchiffon #FFFACD  
beige #F5F5DC  
linen #FAF0E6  
oldlace #FDF5E6  
lightcyan #E0FFFF  
aliceblue #F0F8FF  
whitesmoke #F5F5F5  
lavenderblush #FFF0F5  
floralwhite #FFFAF0  
mintcream #F5FFFA  
ghostwhite #F8F8FF  
honeydew #F0FFF0  
seashell #FFF5EE  
ivory #FFFFF0  
azure #F0FFFF
snow #FFFAFA  
white #FFFFFF  
gainsboro #DCDCDC  
lightgrey #D3D3D3  
silver #C0C0C0  
darkgray #A9A9A9  
lightslategray #778899  
slategray #708090  
gray #808080  
dimgray #696969  
darkslategray #2F4F4F  
black #000000  


출처 http://griper.tistory.com/entry

'안드로이드' 카테고리의 다른 글

You must supply a layout_width attribute  (0) 2012.05.15
Progressbar  (0) 2012.05.15
안드로이드 강좌 모음 pdf&동영상 강좌.  (0) 2012.05.11
화면회전  (0) 2012.05.08
배경화면꾸미기  (0) 2012.05.08
Posted by 사라링

스프링 3.0 강좌

2012. 5. 11. 11:25
http://dev.anyframejava.org/docs/anyframe/5.1.0/reference/pdf/anyframe-5.1.0.pdf

애니프레임 PDF 강좌 입니다. 


출처및 사이트: http://www.anyframejava.org/

'스프링3.0' 카테고리의 다른 글

스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
Spring3.0 DI AOP  (0) 2012.05.14
스프링 3.0 동영상 강좌.  (0) 2012.05.09
Posted by 사라링


PDF]  안드로이드 입문서 3rd Edition 파일의 링크

http://www.kandroid.com/kandroid_book_3rd_edition.pdf


'안드로이드' 카테고리의 다른 글

Progressbar  (0) 2012.05.15
안드로이드 색상표  (0) 2012.05.11
화면회전  (0) 2012.05.08
배경화면꾸미기  (0) 2012.05.08
배경화면꾸미기  (0) 2012.05.08
Posted by 사라링

Spring 3.0 동영상 강좌 바로가기

https://www.ibm.com/developerworks/mydeveloperworks/blogs/9e635b49-09e9-4c23-8999-a4d461aeace2/entry/264?lang=ko



'스프링3.0' 카테고리의 다른 글

스프링 3.0 @ 어노테이션 기반 설정  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
Spring3.0 DI AOP  (0) 2012.05.14
스프링 3.0 강좌  (0) 2012.05.11
Posted by 사라링
  1. JDK 설치

  2. 되도록 이면 컴퓨터가 64bit 라도 32bit를 설치 하자. 일부 컴퓨터 에서 크래쉬 현상이 발견 되는데 해결 실패 했다.

    www.orcale.com 에서 JAVA SE-> jdk 다운.. 후 설치..

    JAVA EE - Enterprise(기업..)

    JAVA ME -micro(휴대폰 등..)

    JAVA SE - Standard (기본)


  1. 환경변수 설정

    1. 내컴퓨터->속성->고급->환경설정-> 시스템변수의 CLASSPATH에 C:\Program Files\Java\jdk1.6.0_30\bin를 추가..
    2. JAVA_HOME 에 C:\Program Files\Java\jdk1.6.0_30 설정 추가
  2. 클래스명은 파일명과 동일하게 만들어야 한다.
  3. 자바는 모든명령문들이 class 내에 존재해야 한다.
  4. main method는 이 class를 실행할 때 최초 실행되는 method이다.


이클립스 설치 하자.


http://www.eclipse.org/downloads/ 에 접속 하여 다운 받자



위에서 부터 인디고 클래식 헬리오스 였던것 같다.

web 즉 JSP 등을 공부 한다면 인디고 버전을 받고 기본적으로 가볍게 사용 하고 싶다면  헬리오스 버전을 다운 받아 설치 하면 된다.

다운받을 용량을 보면 알겠지만. 위에것이 가장 무겁다...;

실전 에서 사용하는 경우 최대한 가볍게 구동 하기 위해 헬리오스 버전을 설치후에 필요한 것만 플로그인해 사용 한다.


참고로 윈도우7 64bit 설치 시에 자바및 이클립스를 되도록이면 32bit로 설치 하자.

64bit 자바와 64bit 버전 을 설치 한 경우 이유 없이 메모리 부족으로 인한 크래쉬 현상이 발견 되는데 아무리 메모리 조정을 하더라도 해결이 안되엇다.

실제 사용 하는 프로그래머 분도 있으며 속도가 매우 빠른다고 하여 멋모르고 도전 했다가. 결국 java 부터 다 지우고 32bit 로 다시 설치 한 기억이 있다.


이제 이클립스 환경 변수를 해보자

이클립스 초기 설정. // eclipse.ini 파일 추가 vm 메모리 설정. 빨간색 부분 추가 한다.  버전을 1.5-> 1.6 으로 변경

Xms 는 메모리가 여유 있는 경우 (6기가 이상) 1024m 으로 해도 되고 아니면 둘다  512m 정도로 해도 된다.

 

-vm
C:/java/jdk1.6.0_25/bin/javaw.exe
-startup
plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.100.v20110502
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms1024m
-Xmx1024m



 java jre : JDK 로 잡혀 져 있는지 확인

vm.jpg
 인코딩 : 모두 utf-8  CSS HTML JSP FIles XML FIles 모두 바꿈. UTF-8로

encoding.jpg
 spelling : 끄기

spelling끄기.jpg


 서버 설정

server.jpg
자바 자동완성 끄기  - Enable auto activation 체크 해제

자동완성기능.jpg

 





Posted by 사라링


가상머신 : Virtualbox 2.2.4
OS : ubuntu 9.0.4 (커널 2.6.28-11-generic)
Oracle : Oracle Database 10g Release 2 (10.2.0.1.0) for Linux x86 

 

참고한 사이트

 


1. 설치 파일 준비리눅스용 오라클 버전을 오라클 홈페이지에서 다운을 받는다.

다운을 받기 위해서는 오라클에 가입이 되었어야 하므로 다운받기전에 회원가입을 먼저 하도록 하자.

다운로드한 파일은 리눅스의 특정 디렉토리로 옴겨놓자.

 



2. 설치를 위한 환경구성

1) 먼저 터미널을 열고 설치에 필요한 기본 시탭틱을 설치한다.

$sudo apt-get install gcc binutils libaio1 lesstif2 lesstif2-dev make rpm libc6 libstdc++5 build-essential


2) 설치에 필요한 그룹과 유저를 생성한다.

$sudo groupadd oinstall
$sudo groupadd dba
$sudo groupadd nobody
$sudo useradd -m oracle -g oinstall -G dba -s /bin/bash
$sudo passwd oracle


3) 오라클에 필요한 memory와 CPU resources를 위해 커널 파라미터를 수정한다.
    (메모리와 CPU자원이 충분하지 않으면 오라클 인스턴스가 올라가질 않는다. 물론 설치도 안됨.)
    우선 파일 수정을 위해 sysctl.conf파일을 연다. (vi편집기, vim, gedit 등 사용해 파일을 연다.)

$sudo vim /etc/sysctl.conf


 오픈된 파일의 맨 하단에 아래의 내용을 추가하고 저장한다.

kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000


저장하고 파일을 닫는다. 위에서 수정한 sysctl.conf파일은 Ubuntu시스템이 처음 부팅시 한번 읽어들이는 정보이므로 재부팅을 한다. 귀찮으면 모듈을 강제로 내렸다가 올리면 된다.

$sudo /sbin/sysctl -p



4) 시스템에 security의 limits파일을 열고 다음 정보를 추가한다.

$sudo vim /etc/security/limits.conf


   추가할 정보를 아래와 같다. 맨 하단에 추가하자 ^^

* soft nproc 2047
* hard nproc 16384
* soft nofile 1024
* hard nofile 65536


5) 몇가지 링크와 폴더 생성 및 권한설정을 해주자

$sudo ln -s /usr/bin/awk /bin/awk
$sudo ln -s /usr/bin/rpm /bin/rpm
$sudo ln -s /lib/libgcc_s.so.1 /lib/libgcc_s.so
$sudo ln -s /usr/bin/basename /bin/basename
$sudo mkdir /oracle
$sudo mkdir /oracle/10g
$sudo chown -R oracle:oinstall /oracle
$sudo chmod -R 775 /oracle


6) 환경변수 설정 (etc 및에 profile을 수정한다.)

$sudo vim /etc/profile


   마찬가지로 젤 하단에 아래의 정보를 복사해서 붙여넣는다.

export ORACLE_BASE=/oracle
export ORACLE_HOME=/oracle/10g
export ORACLE_SID=orcl10
export PATH=$PATH:$ORACLE_HOME/bin


  환경변수가 적용되었는 여부를 확인해 보자.

$ su - oracle
Password:
$ echo $ORACLE_BASE
/oracle
$ echo $ORACLE_HOME
/oracle/10g$ exit
logout


  위와 같이 설정한대로 출력된다면 정상이다.


7) 레드헷 엔터프라이즈 릴리즈 파일을 만들어준다.  (음.. 왜 하는지는 정확히 모르겠다.  ^^;;;)

$sudo vim /etc/redhat-release


  파일에 아래의 정보를 복사해서 붙여넣는다.

Red Hat Enterprise Linux AS release 3 (Taroon)



3. 설치1) 다운받아 놓은 오라클 파일(10201_database_linux32.zip)의 압축을 풀어주자.
    만약 압축 파일이 /home/user/ 디렉토리 아래 있다면 다음과 같이 실행한다.
  

$sudo chown oracle:oinstall /home/user/10201_database_linux32.zip
$sudo chmod 775 /home/user/10201_database_linux32.zip
$sudo mv /home/user/10201_database_linux32.zip /home/oracle
$su - oracle
$unzip 10201_database_linux32.zip


2. 재부팅을 해주자. (reboot)
   
   여기서 재부팅을 안해줄 경우 아래와 같은 에러를 만날수도 있다.

 

3)  재부팅후, oracle 유저로 접속한 후 터미널에서 설치 실행파일(runlnstaller)를 실행한다.

     이때, 설치실행창의 문자가 깨져서 출력되는 것을 막기 위해 간단한 언어 설정을 꼭 해주자.

 

$expert LANG=C
$/home/oracle/database/runInstaller

 


4) 설치를 진행한다.  (난 Basic installation을 선택하였다. ) 
   
   설치 화면에서 부터는 Windows에서 설치하는방법과 동일하지만 한가지 주의 해야 될 부분은 SID입력
   부분이다. 위 6) 환경변수 설정 에서 환경변수 설정에서 입력한 SID인 orcl10을 입력하지 않으면 
   안된다. 
  


 "Inventory directory" 를 "/oracle/oraInventory"로 하고
시스템그룹은 "oinstall"로 지정하고 다음  default 값을 사용하면 될 것 같다.


 설치된 것에 대한 개요를 보여준다. "INSTALL" 클릭


설치가 진행된다.



중간에 설치된 정보를 보여주는 창이 뜸 "OK"


설치 .. ing (iSQL 등이 설치되고 있다. ㅎ)


거의 막바지다. 중간에 아래와 같은 창이 뜬다면 터미널을 하나 열어서 "root" 계정으로 명시된 스크립트를 실행해 준다.
 

#/oracle/oraInventory/orainstRoot.sh
#/oracle/10g/root.sh


스크립트 실행이 끝나면 설치화면 창으로 돌아와 "OK"를 눌러준다.
스크립트 실행이 곤란하면 설치 완료후 실행해 주어도 무방 한 것 같다. ^^;;

설치가 완료되었다.

 

아래에 표시되는URL 정보는 적어두었다가 활용하도록하자. ^^



4. 설치완료 후 사용을 위한 환경구성
1) 재부팅 후 oracle이 유저가 아닌 본인의 원래유저로 로그인해 아래 파일을 수정해 준다.

$sudo vim /etc/oratab


etc밑에 oratab파일에서 orcl10:/oracle/10g:N부분을 orcl10:/oracle/10g:Y로 수정한다. 덧붙여 설명하면 orcl10은 인스턴스이고 가운데 부분은 ORACLE_HOME 마지막 부분은 오라클 인스턴스의 자동 실행 여부(Y/N)이다.

orcl10:/oracle/10g:Y


2) 오라클 유저(oracle)로 로그인한 후 오라클 리스너의 절대 패스를 수정해 준다.

$su - oracle
$vim $ORACLE_HOME/bin/dbstart


다음라인을 찾아.

# Set this to bring up Oracle Net Listener
ORACLE_HOME_LISTNER=/ade/vikrkuma_new/oracle
if [ ! $ORACLE_HOME_LISTNER ] ; then
echo "ORACLE_HOME_LISTNER is not SET, unable to auto-start Oracle Net Listener"
else
LOG=$ORACLE_HOME_LISTNER/listener.log


아래와 같이 패스를 수정해 준다.

ORACLE_HOME_LISTNER=/oracle/10g


이제 모든 설치가 끝났다.
(0 ^o^)0

다음은 실행화면 ^^*  열공합시다.

이 글은 스프링노트에서 작성되었습니다.


Posted by 사라링

설치전. 확인사항. 이클립스는

 JAVA  기반의 프로그램이기때문에  JDK 를 반드시 설치 한후 환경변수 설정을 한후에 설치 해야만 된다.
환경 변수는   // 장으로 가자.


Introduction

Eclipse란?

Eclipse 아키텍처

  • Eclipse 플랫폼은 Platform, JDT 및 PDE와 같은 3개의 주요 서브시스템으로 구성된다. 이 서브시스템들은 별도로 진행되지만 릴리즈나 다운로드는 통합되어 제공된다.
  • 서브시스템 설명
    • Platform: Eclipse 플랫폼 서브 시스템은 핵심 기반 구조와 UI 프레임웤들로 구성되어 있다.
    • JDT (Java Development Tools): JDT 서브시스템은 자바 애플리케이션을 개발, 테스트 및 디버깅을 하기 위한 통합 툴들로 구성되어 있다.
    • PDE (Plug-in Development Environment): PDE는 Eclipse 플러그인을 개발, 테스트, 디버깅 및 패키징을 하기 위한 통합 툴들로 구성되어 있다.

설치와 구성 요소

설치

  • 설치 파일 다운로드
  • Eclipse 설치
    • J2SE 1.4.1 이상의 Java Runtime 이나 JDK를 먼저 설치
    • 위에서 다운 받은 압축 파일을 풀면 설치 끝. (eclipse는 windows의 registry를 사용하지 않음)

구성 요소

  • Eclipse.exe를 실행
  • 아래와 같은 workspace 설정 화면이 나타난다.
    • 이 workspace에는 사용자의 환경 설정 정보, 리소스들 (프로젝트 실행 파일 및 소스 등)이 저장될 장소이므로 잘 관리해야 한다.
  • 초기 화면
    • 오른쪽 위의 큰 화살표를 선택하면 "Welcome""" 최소화되며 디폴트 화면인 자바 퍼스팩티브로 바뀐다.
  • 화면 구성
    • 워크벤치 (workbench): eclipse의 사용자 인터페이스. 윈도우의 집합이며, 각 윈도우는 위 화면과 같은 구성 요소들로 구성된다. New window를 이용하여 새로운 윈도우를 생성시킬 수 있다.
    • 퍼스펙티브 바 (perspective bar): 위 그림에서 화면의 위 오른쪽에 위치하고 있는 툴바. 이 버튼을 이용하여 퍼스펙티브 간의 이동을 용이하게 할 수 있다. 컨텍스트 메뉴 (오른쪽 버튼 > 팝업 메뉴)를 이용하여 퍼스펙티브 메뉴의 위치를 바꿀 수 있다 (top left, top right, left)
    • 뷰 (view): 정보를 표시하는데 사용. 예를 들면 위 화면에서 왼쪽의 Package Explorer 뷰는 프로젝트별로 패키지, 파일 등의 여러 가지 정보들을 계층적으로 보여주며, 화면의 오른쪽에 있는 Outline 뷰는 활성화되어 있는 Java 에디터의 소스코드 개요를 보여준다. 하나의 워크벤치 내에서는 같은 뷰가 2개 이상 존재할 수 없다.
    • 퍼스펙티브 (perspective): 각종 에디터와 뷰의 모임. 작업의 종류에 따라 다른 모양이 된다. 예를 들어, 퍼스펙티브 바에서 'java'' 선택하면 자바 프로그램을 하기 위한 여러 가지 뷰로 바뀌며 (default), 'debug'' 선택하면, 자바 코드를 디버깅하기 위한 뷰들로 바뀐다. 플러그 인의 설치에 따라 플러그 인과 관련된 추가의 퍼스펙티브를 선택할 수 있다.
    • Fast 뷰 (fast view): 작업 영역을 넓게 사용하기 위해 잘 사용하지 않는 화면들을 최소화 시켜놓고 필요한 시점에만 잠깐 활성화 시킬 때 사용된다. 최소화 할 뷰의 타이틀에서 컨텍스트 메뉴의 [fast view] 를 선택하면 최소화가 되며, 'fast view'' 있는 관련 아이콘을 누르면 뷰가 활성화가 된다.

기본 기능

  • 간단한 자바 애플리케이션의 작성을 통해 eclipse의 기본 기능들을 살펴보자
  • 프로젝트 생성
    • [File > New > Project > New Project] 팝업 창
    • [New Project] > Java project 선택 > Next
    • [New Java Project] 창에서 > Project 명 입력 > [Finish]버튼
    • 입력한 Project 명으로 프로젝트가 생성되며, [Package Explorer] 뷰에서 트리 형태로 볼 수 있다.
  • 클래스 생성
    • [File > New > Class > New Java Class] 팝업 창
    • 작성하고자 하는 클래스 이름과 관련 정보들 입력 > [Finish]
    • 입력한 class명으로 클래스가 생성되며, [Package Explorer] 뷰에서 트리 형태로 볼 수 있다.
  • 코드 입력
    • 자바 에디터에 작성할 코드들을 입력한다.
  • 컴파일
    • Eclipse에서는 기본적으로 작성한 소스를 저장하면 자동 컴파일이 되어 소스 코드가 검증된다.
  • 실행
    • [Run > Run As > Java Application] 를 선택하면 작성한 자바 애플리케이션을 실행 시켜볼 수 있다.
    • 실행 후 출력이 있을 경우 아래의 [Console] 뷰에서 출력된 결과를 볼 수 있다.
  • 그 외 기능들
    • 코드 어시스트 (Code Assist)

      자바 코드 입력 중 [Ctrl + Space]를 눌러 입력하던 내용을 완성하는데 필요한 코드 (메서드, 템플릿)가 팝업 되어 나타나며, Enter를 눌러 선택하여 완성한다. [Window > Preferences > Preferences 팝업 창 > Java > Editor > Templates] 에서 템플릿을 편집할 수 있다.)
    • 빠른 수정 (Quick Fix)

      에러가 있는 경우 빨간색 밑줄과 함께 왼쪽의 마커바에 빨간색 (X) 표시가 나타난다. 이 때 빠른 수정 (Quick Fix) 기능을 사용할 수 있는 상황인 경우에는 위의 화면에서와 같이 빨간색 (X) 표시와 함께 전구 모양의 아이콘이 나타난다. 마커바에 있는 이 아이콘에 커서를 놓고 [Ctrl + 1]을 누르면 에러를 제거할 수 있는 가능한 몇 가지 방법들이 나타난다.
    • Quick Outline

      에디터에서 [Ctrl + O]를 누르면 Outline View와 같은 내용이 팝 업 창에 나타나며 찾고자 하는 메서드의 이름을 입력하면 입력하는 문자열에 해당하는 메서드들만이 팝업 창 목록에 나타나 빠르게 메서드로의 접근이 가능하다.
    • 소스 코드 네비게이션
      소스 코드에서 메서드, 필드 또는 클래스의 정의를 보고자 할 때 커서를 그 위에 놓고 F3를 누르면 정의된 곳으로 이동한다. 다시 제자리로 돌아오려면 [Ctrl + 왼쪽화살표]를 누르며, 정의된 곳으로 다시 이동하려면 [Ctrl + 오른쪽화살표]를 누른다.
      또 다른 방법으로는 커서를 메서드나 클래스 명 위에 놓고 [Ctrl]을 누르면 마우스 커서를 위치시키면 하이퍼링크로 바뀌며 마우스를 누르면 해당 메서드나 클래스가 정의된 곳으로 이동한다.
      원하는 행으로의 이동은 [Ctrl + L]을 눌러 나타나는 팝업 창에 이동할 행 번호를 입력 후 [OK]를 누른다.
    • Mark Occurrences

      특정 변수나 메서드들이 사용되고 있는 곳을 한꺼번에 찾아보고 싶을 때. 해당 변수나 메서드를 선택한 후 툴바에 있는 [Mark Occurrences] 버튼을 누른다. 변수, 상수, 필드, 메서드, 클래스 등에 모두 적용된다.
      조건에 맞는 항목들은 노란색 background의 문자열로 표시된다.
      editor 뷰의 스크롤 바 바로 오른쪽(2번 부분)에 방금 Mark된 항목들이 전체 화면 기준으로 상대위치로 표시되며, 흰 부분을 누르면 원하는 위치의 Mark된 항목으로 바로 가기를 할 수 있다.
    • 코드 생성

      Eclipse가 코드를 자동 생성해주는 기능이다. 업무 처리 로직의 자동 생성이 아니라 정의된 코드 템플릿을 적용시키는 것이다.
      적용은 소스 코드의 특정위치에서 [컨텍스트 메뉴 > Source > Override/Implement Methods부터 ~ Add Comment까지]를 선택하면 되며,
      코드 템플릿에 대한 설정은 [Windows > Preferences > Preferences 팝업 창 > Java > Code Style > Code Templates] 에서 한다.
    • 로컬 히스토리

      코드를 생성한 후 수정/저장을 하면 그 내역도 함께 저장된다. Package Explorer 뷰에서 히스토리 내역을 보고자 하는 파일을 선택하고 [컨텍스트 메뉴 > Compare With > Local History]를 선택하면 내역을 볼 수 있다.
      [컨텍스트 메뉴 > Replace With]를 이용하여 로컬 히스토리의 상태로 되돌리 수도 있다.
    • 코드 스타일

      코드 작성자 또는 코딩 표준을 담당하는 사람은 가독성의 향상과 작업의 일관성 유지를 위해 코딩 작성의 기준을 정할 수 있다. [Window > Preferences > Java > Code Styles > Formatter > Show > Show Profile 팝업 창]에서 코드 관련 여러 스타일들을 지정할 수 있다.
    • Hot Key
      Eclipse가 활서화 되어 있을 경우 [Ctrl + Shift + L]을 누르면 기 정의된 Hot Key 정보가 워크벤치 오른쪽 아래에 팝업 창으로 나타난다. 다시 [Ctrl + Shift + L]을 누르면 Hot Key를 재 정의할 수 있는 Preferences 팝업 창이 나타난다. [Window > Preferences... > General > Keys] 의 메뉴를 통해서도 Preferences... 창을 띄울 수 있다.
    • 검색
      [Ctrl + F] > [Find/Replace] 팝업 창 에 찾고자 하는 문자열을 입력하거나
      간단한 문자열을 찾고자 할 때에는 [Ctrl + J]를 눌러 워크벤치 아래의 상태바 메시지 표시 영역에 'Incremental File' 표시가 되면서 점증적 찾기 모드로 바꾼 후 찾고자 하는 문자열을 입력한다. 찾고 있는 문자열의 다음 위치를 계속해서 찾으려면 [Ctrl + J]를 누르며, [Ctrl + Shift + J]를 누르면 문자열의 이전 위치로 이동한다.
    • 주석 처리/풀기
      코드의 정해진 블록을 주석 처리 또는 주석 풀기를 할 수 있다.
      정해진 블록을 '/* ~ */'로 블록 단위로 주석 처리를 할 때 [코드에서 주석 처리할 블록 선택 > 컨텍스트 메뉴 > Source > Add Block Comment] 또는 [코드에서 주석 처리할 블록 선택 > Ctrl + Shift + /]를 누르며, 설정된 '/* ~ */' 블록 주석을 풀려면, [코드에서 주석 처리된 블록 선택 > 컨텍스트 메뉴 > Source > Remove Block Comment] 또는 [코드에서 주석 처리된 블록 선택 > Ctrl + Shift + \ ]를 누르면 주석이 풀린다.
      정해진 블록을 '//'로 블록 단위로 주석 처리를 할 때 [코드에서 주석 처리할 블록 선택 > 컨텍스트 메뉴 > Source > Toggle Comment] 또는 [코드에서 주석 처리할 블록 선택 > Ctrl + /]를 누르며, 설정된 '//' 블록 주석을 풀려면, [코드에서 주석 처리된 블록 선택 > 컨텍스트 메뉴 > Source > Toggle Comment] 또는 [코드에서 주석 처리된 블록 선택 > Ctrl + /]를 누르면 주석이 풀린다.

Debugging

  • 디버그 모드로 디버깅을 시작하기 전 집중적으로 검토하고자 하는 부분이 있을 경우 해당 코드에 브레이크포인트를 설정해 놓는다. (자바 에디터에서 검토할 코드 행의 마커바에서 마우스 더블 클릭을 하면 브레이크포인트가 설정되며, 다시 더블 클릭하면 해제된다.)
  • [Run > Debug > Debug 팝업 창 > 왼쪽의 'Configurations' 영역에서 실행할 클래스선택 > Debug 버튼 > Perspective 전환 메시지 창 > OK] --> 디버그 모드로 변환되며 디버그가 시작된다.
  • [Debug 팝업 창] 에서 'Stop in main'을 체크하고 [Debug]를 실행하면 브레이크포인트 설정과 관계없이 main()의 첫 코드부터 실행된다.
  • 설정된 브레이크포인트들은 Breakpoints View에 전부 리스트 되며 설정된 브레이크포인트는 Breakpoints View에서 해당 항목을 check, uncheck 함에 따라 활성화 또는 비활성화된다.
  • 루프 안에 설정된 브레이크포인트의 반복 횟수가 많을 경우 특정 회수에 대해서만 프로그램이 멈추게 하기 위해서는 브레이크포인트가 설정된 마커바에서 오른쪽 버튼의 팝업 메뉴의 [Breakpoint properties]를 눌러 나타나는 팝업 창의 [Hit Count]를 체크하고 방문 횟수를 입력한다.
  • Debug 진행: 설정한 환경 (breakpoint, hit count, stop in main...) 에 따라 프로그램의 진행을 수동으로 관리할 수 있다. 여기에서는 Debug View의 툴 바에 있는 메뉴들을 중심으로 Debug 진행 관리 방법을 살펴보자.
    • (1) Resume (F8): 멈췄던 쓰레드 다시 진행. 다음 브레이크포인트까지 계속 진행
    • (2) Suspend: 쓰레드를 멈춤
    • (3) Terminate: 프로그램 종료
    • (4) Step Into (F5): 스텝 단위로 프로그램 실행, 메서드가 호출될 경우 그 메서드 안으로 이동
    • (5) Step Over (F6): 메서드가 호출되더라도 메서드 안으로 이동하지 않고 현재 코드 진행
    • (6) Step Return (F7): 현재 메서드로부터 리턴. 메서드 호출부로 위치 이동
    • (7) Drop to Frame: 특정 메서드를 실행하다 그 메서드의 처음부터 다시 실행
    • (8) Step Filtering: 디버깅 도중 디버깅 대상이 되지 않는 메서드 안으로는 들어가지 않게 설정하는 곳. [Window > Preferences > Java > Debug > Step Filtering]에서 설정
  • Variables View: Debugging을 하며 관련된 변수들을 관찰할 수 있는 창이다. 현재 가용한 변수들이 나열되고 현재 진행 시점에 할당되어 있는 값을 볼 수 있다.
  • Display View: 현재 스택 프레임의 컨텍스트에서 실행할 수 있는 모든 종류의 수식을 입력 및 실행 가능. 원본 코드의 수정 없이 다양한 형태로 메서드나 변수 값들을 또는 그 조합 결과를 확인해 볼 수 있다. [Window > Show View > Display] 로 Display View를 활성화 시킨다. 관찰하고자 하는 수식이나 메서드들을 기술해 놓는다. Debugging을 하면서 현재 Display View에 기술된 수식 또는 메서드의 상태 값을 알기 위해서는 해당 항목을 선택한 수 뷰 툴바의 [Display Result of Evaluating Selected Test] 또는 [Ctrl + Shift + D]를 누르면 값을 보여준다. 잘못된 입력이나 값을 알 수 없는 상황일 경우 에러를 보여준다.
  • Inspect: Display View에서는 결과를 문자열로만 파악할 수 있다. 때문에 객체의 상태를 알기 위해서는 다른 방법을 사용해야 하며 그 중 하나가 Inspect 기능을 이용하는 것이다. Inspect 는 관찰 대상 수식을 선택하고 컨텍스트 메뉴에서 Inspect를 선택 (Ctrl + Shift + I)하는 것이다. 하지만 Inspect는 일시적인 관찰 방법이며 자세한 관찰을 하고 싶을 경우 [Ctrl + Shift + I]를 다시 눌러 Expression View 로 대상을 옮겨 관찰한다.

  • Watch: 특정 수식을 지속적으로 관찰하고 싶을 경우 inspect 기능이나 Display View를 이용하는 것은 번거로울 수 있다. 이런 때 Watch 기능이 아주 유용할 수 있다. Watch 기능은 Expressions View안에서 작동한다. 위 그림에서 작은 '(X+Y)' 아이콘이 붙은 항목들이 Watch 기능이 적용되고 있는 것들이다. Watch 항목은 Expressions View 내에서 [컨텍스트 메뉴 > Add Watch Expression]을 눌러 나타나는 [Add Watch Expression] 위한 팝업 창에 여러 가지 수식을 입력하여 지속 관찰할 수 있다.

Refactoring

  • Eclipse의 리팩토링 기능을 활용하여 코드에 대한 리팩토링을 수행해 보자
  • Rename: 클래스 이름을 바꿔보자. 클래스 "BubbleSortApp"" 이름을 "BubbleSortApplication""" 바꾼다.
    • 소스 코드에서 변경할 클래스 이름을 선택한다.
    • [Refactor > Rename > Rename Type 팝업 창 > 바꿀 클래스 명 입력 > Preview]

  • Push Down: 하나의 서브클래스에서만 필요한 메소드를 슈퍼클래스에 포함시켰다. 이 메소드를 실제 사용하는 서브클래스로 내려보자
    • Employee 슈퍼클래스에서 옮길 메소드를 선택하고, [Refactor > Push Down > Push Down 팝업 창]

    • [OK]
    • Employee에 있던 getQuota() 메소드가 Salesman 클래스의 메소드가 됨
  • Pull Up: 서브클래스인 Salesman과 Engineer에 각각 포함되어 있던 getName 메소드를 슈퍼 클래스로 이동시켜 보자
    • Employee 슈퍼클래스로 옮길 메소드를 서브클래스에서 선택하고, [Refactor > Pull Up > Pull Up 팝업 창]에서 옮길 메소드와 변수를 선택한 후, [Next]를 누른다.
    • 선택한 메소드를 제거할 서브클래스를 선택한다. 여기에서는 두 개의 서브클래스 전부를 선택하고 [Finish]를 누른다.
    • 서브클래스인 Engineer와 Salesman에서 getName메소드가 제거되고 슈퍼클래스인 Employee에 추가가 되었음을 확인할 수 있다.

이클립스 적용 사례

참고 문헌

문서에 대하여

최초작성자 : 고덕성
최초작성일 : 2006년 2월 4일
버전 : 1.2
문서이력 :

 

*** 이클립스 코드 작성 유용 작성방법.

-주석 달기 .                    범위를 잡은후 ctrl+shift+ /                             <-- 경우 한꺼번에 주석이 잡힌다. 하지만 지우는건 수동으로 해야함.

-프린트출력단축키.           syso 친후 ctrl+space바                               <--- 자동으로 system.out.println() 으로 바꾸어준다. 유용하게 쓰자.

-전체 변수(같은것)변경     변수 드레그 및 커서로 간후 alt+shift+R           <--- 코딩 짜는도중 멤버 변수와 겹치거나 햇갈릴경우 한꺼번에 변경하자. 변수는 너무 간단하면 오히려 더 햇갈린다.

지역변수 같은 경우 int x ,int y 처럼 쓰는게 좋으면 멤버 변수의 경우  InputStr 같은 형식으로 써보자.

-반복문,조건문 둘러싸기   범위를 모두 긁은후 alt+shift+z 후 선택             <--- 변수및 조건문을 적은후 둘러 쌓는경우가 필요한 경우 사용 하자. 미리 구성을 갖추어주기 떄문에 유용 하다.

-임포트 자동 하기            임포트 시킬 클래스 입력후 ctrl+shift+o             <--- 코딩 맨 위에 자동으로 입력 

-get set 자동 입력 하기    변수 드레그후 alt+shift+s 누룬후 모두 때고 r     <--- 클래스 생성시 기본적으로 변수는 private 시킨후 그 값을 getXXX setXXX 로 가져가던가 바꾸는 메서드를 만들어 사용 한다.

-public static void main(String[] args) {}  자동 만들기

main 입력후 ctrl+space바                             <--- 생성시에 public main 체크바를 한경우 자동으로 생성 되지만.못했을 경우 이런 방법으로 가능 하다.

-복사 하기                드레그 또는 커서 위치후 ctrl+alt 누룬상태에서 방향키 ↓ or ↑   <--- 변수 일부를 제외 하고는 같은 코드를 입력 해야 하는경우 복사 해서 쓰자

-이동 하기                드레그 또는 커서 위치후 alt 누룬상태에서 방향키 ↓ or ↑           한줄 단위 또는 여러줄 단위로 밑의 문장으로 이동 할떄 쓰자

 

주석달기.

이클립스에서 클래스를 생성할 때마다 특정한 주석을 달려고 한다면 

간단한 방법으로 설정을 할 수 있다. 

클래스 생성할 때 기본 주석에 대한 설정을 할 수 있다. 

클래스 생성시 뜨는 창 하단에 보면 그림과 같은 부분에 체크를 해주면 된다. 

그리고 주석에 관련 설정을 하고 싶다고 체크를 한 바로 위의 here을 눌러 주면 된다. 

 



Code Templates에서 Comments의 Types을 선택한 후, Edit버튼을 누르면 다음과 같이 주석 편집창이 뜬다. 

(here을 눌렀을 경우에 이클립스 상단의 Window-Preferences를 눌렀을 때와 같은 창이 뜬다. )

 

 

우리가 원하는 형식의 기본 주석을 만들 수 있다.

 

편집 후 저장, 그리고 클래스 생성 시 클래스의 상단에 우리가 편집하였던 주석이 달려서 생성된다!! 

 

 

 

 

단축키 모음은 심심할때 볼것. 위에꺼는 꼭 볼것.

■ 이클립스 단축키
 ο 단축키 확인
   - Window > Preference > General > Keys 메뉴에서 확인 가능
   - 단축키 보기 Hint : Ctrl + Shift + L

 


 ο 실행
    Ctrl + F11 : 실행(바로 전에 실행했던 클래스 실행)

 


 ο 디버그
    F11 : 디버그 모드로 실행
    F5 : step into(현재의 명령문이 호출되는 메소드 속으로 진행하여, 그 첫 문장을 실행하기 전에 멈춘다. 하지만 자바 라이브러리 클래스 수준까지 들어가므로 단계필터 사용을 체크(Shift + F5)를 하면 필터를 설정한 클래스에 대하서는 Step Over 기능과 같은 기능을 수행한다.)
    F6 : step over(현재의 명령문을 실행하고 다음 명령문 직전에 다시 멈춘다.)
    F8 : 멈추어 있던 쓰레드를 다시 계속 실행한다.(Resume)
    Ctrl + Shift + B : 현재커서위치에 Break point설정 또는 해제
    Display view(표시) : Window > Show View > Other > Debug > Display를 선택하여 소스상에서 필요한 부분을 선택해서 실행시켜 볼 수 있다.  한 순간의 값만 필요할 때 볼 수 있는 반면에 아래놈은 계속적으로 값이 변하는 것을 확인 할 수 있다.

 


 ο 소스 네비게이션
    Ctrl + 객체클릭(혹은 F3) : 클래스나 메소드 혹은 멤버를 정의한 곳으로 이동(Open Declaration)
    Ctrl + O : 해당 소스의 메소드 리스트를 확인하려 할때
    F4 : 클래스명을 선택하고 누르면 해당 클래스의 Hierarchy 를 볼 수 있다.
    F3 : 메소드 정의부로 이동
    Alt + Shift + R : 변수 및 메소드 변경(변경할 변수 에서 단축키를 누르고 변경 후에 엔터를 누르면 변수명이 모두 변경)

 


 ο 소스 편집
    Ctrl + spacebar : 자동 완성 기능. 어휘의 자동완성(Content Assistance)
    Ctrl + Shift + O : 자동으로 import 하기(사용하지 않는 Class는 삭제)
    Ctrl + Shift + M : 캐럿이 위치한 대상에 필요한 특정클래스 import
    Ctrl + Shift + G : 클래스의 메소드나 필드를 Reference하고 있는 곳으로 이동
                             반대 : F3 (Reference하는 클래스로 이동)
    Shift + Alt + S R : getter/setter 자동 생성
    Ctrl + Shift + Space : 메소드 파라미터 힌트 (메소드에 입력해야 하는 파라미터 정보가 표시된다.)
    F2 : 에러의 원인에 대한 힌트 (에러 라인에 커서를 위치시키고...)

 

    Ctrl + Shift + / : 블록 주석(/*..*/) 추가
    Ctrl + Shift + \ : 블록 주석 제거
    Ctrl + / : 한줄 또는 선택영역 주석처리 또는 제거(//)
    Alt + Shift + J : 설정해 둔 기본주석 달기(JavaDoc 주석)

 

    Ctrl + S : 저장 및 컴파일
    Ctrl + Shift + F4 : 열린 파일 모두 닫기
    Ctrl + Shift + W : 열린 파일 모두 닫기
    Ctrl +W : 창 닫기

 

    Ctrl + Q : 마지막 편집위치로 가기
    Ctrl + L : 특정줄번호로 가기. 로컬 히스토리 기능을 이용하면 이전에 편집했던 내용으로 변환이 가능하다.
    Ctrl + O : 현재 편집 화면의 메소드나 필드로 이동하기
    CTRL + 휠 : 페이지 단위 이동

 

    Ctrl + D : 한줄삭제

 

    Ctrl + I : 들여쓰기 자동 수정
    Ctrl + Shift + F : 소스 정리

 

    Alt + Up(Down) : 위(아래)줄과 바꾸기
    Ctrl + Alt + ↑↓(상/하) : 한줄(블럭) 복사
    Alt + Shift + 방향키 : 블록 선택하기

 

    Ctrl + M : 전체화면 토글
    Ctrl + Z / Ctrl + Y : Undo / Redo
    Ctrl + , or . : 이전 또는 다음 annotation(에러, 워닝, 북마크 가능)으로 점프
    Ctrl + T : 하이어라키 팝업 창 띄우기(인터페이스 구현 클래스간 이동시 편리)
    Ctrl + F6 (재정의 하는게 편리) : ULTRAEDIT나 EDITPLUS 의 Ctrl +TAB 과 같은 기능
    Alt + ←→(좌/우) : 이후, 이전(뷰 화면의 탭에 열린 페이지 이동)
    Ctrl + Shift + R : Open Resource
    Ctrl + Shift + ↑↓(상/하) : 다음/이전 메소드로 이동
    Ctrl + Shift + E : Switch to Editor (탭에 열려있는 Editor 이동)
    Ctrl + Shift + G : 클래스의 메소드나 필드를 Reference하고 있는 곳으로 이동
   
    Ctrl + 1  : Quick Fix(구현하지 않은 메소드 추가, 로컬 변수 이름 바꾸기, 행둘러싸기(if, while, for emd))
    Ctrl + 2 + R : Rename(리팩토링)

 


  ο 문자열 찾기
    Ctrl + K : 찾고자 하는 문자열을 블럭으로 설정한 후 키를 누른다.
    Ctrl + Shift + K : 역으로 찾고자 하는 문자열을 찾아감.
    Ctrl + J : 입력하면서 찾을 수 있음.
    Ctrl + Shift + J : 입력하면서 거꾸로 찾아갈 수 있음.
    Ctrl + F : 기본적으로 찾기
    Ctrl + H : Find 및 Replace

 


 ο 템플릿 사용
    1) sysout 입력한 후 Ctrl + Space 하면 System.out.println(); 으로 바뀐다.
    2) try 입력한 후 Ctrl + Space 하면 try-catch 문이 완성된다.
    3) for 입력한 후 Ctrl + Space 하면 여러가지 for 문을 완성할 수 있다.
    4) 템플릿을 수정하거나 추가하려면 Window > Preference > Java > Editor > Templates 에서 할 수 있다.

 


 ο 에디터 변환
   1) 에디터가 여러 파일을 열어서 작업중일때 Ctrl + F6 키를 누르면 여러파일명이 나오고 F6키를 계속 누르면 아래로
   2) Ctrl + Shift + F6 키를 누르면 위로 커서가 움직인다.
   3) Ctrl + F7 : 뷰간 전환
   4) Ctrl + F8 : 퍼스펙티브간 전환
   5) Ctrl + E : 뷰 화면의 탭에 열린 페이지 이동
   6) Ctrl + H6 : 열린 페이지 이동
   7) F12 : 에디터로 포커스 위치

 

 

입력 버튼에서 onclick="this.disabled=true;

하지않을 경우 해당 버튼을 빠르게 연타하면 같은 값이 여러번 들어갈 수 도 있으므로

disabled=true체크를 해야 한다. 체크를 한 경우 한번 클릭 후 서버에 갔다올 동안 버튼이 잠궈지기 때문에 버튼 동작이러번 들어가는 것을 방지 할 수 있다.

 

 ---------------------------------------------------------------------------------------------------------------------------------------------

  1. http://localhost:8080/mirae_server_app 접속 (원래는" http://210.168.99.210:8080/...." (localhost로는 접근이 되지만 아이피로 접근이 되지를 않음..)
  2. WEB-INF/web.xml에 들어가 <welcome-file> index.jsp</welcome-file>를 확인하여 mirae_server_app 바로 밑에있는 index.jsp를 부름.
  3. index.jsp 안의 내용
  4. <%@ include file="./jsp/include.jsp" %> // WEB-INF/jsp/include.jsp 파일을 인클루드함.
  5. <c:redirect url="/jsp/login.jsp" /> // WEB-INF/jsp/login.jsp 파일을 화면에 보여줌.
  6. id, pw를 넣고 로그인 버튼클릭시 loginForm.submit() -> action = "login.do" 이므로 sptingapp-servlet.xml 에 들어가보면 <bean name="/jsp/login.do" class="springapp.web.LoginController">..이 있다. src/springapp.web.LoginController 파일에 들어가 넘어온 id와 pw를 command 객체로 받고
  7. .
  8. . 6라인 protected final Log logger = LogFactory.getLog(getClass()); //이부분 모르겟음
  9. .
  10. . 24라인 UserInfo loginForm = (UserInfo) command; id,pw를 loginForm에 저장.
  11. . 25라인 logger.info("loginForm=" + loginForm); > loginForm = id.pw
  12. .
  13. . 1.
  14. sqlMapConfig.xml에 DB접속정보 DB튜닝 트랜잭션 관리자 SQL-MAP 정의파일등의 정보가 들어있다.
  15. jdbc.properties 안에는 db와 연동시키기 위한 내용이 들어있다.
  16. Userinfo.xml안에는 UserInfo 클래스에 받아온 파라미터 값(id, pw)을 받아 { call APP_LOGIN(#EMP_NO#, #PASSWD#) } 를통해 아이디와 비번을 넣게 되어 resultClass 역시 UserInfo로 보낸다.

 ---------------------------------------------------------------------------------------------------------------------------------------------

 

 

jsp페이지에서 세션에 저장된 값을가져오려고

<% String s_userInfo = session.getAttribute("session_userInfo");%>

했는데 session에 빨간불들어오며 session cannot be resolved 가뜸.

해결 - session = false 로되어있었음..;;; false일 경우 session 사용불가;

          session 사용중 에러가 떴다.
          java.lang.ClassCastException: mirae.login.UserInfo cannot be cast to java.lang.String

String u_userInfo = (String)session.getAttribute("session_userInfo");

--> session_userInfo는 객체여서 (String)타입으로는 받을 수 없었다

controller에서 session_userInfo = userInfo.getEMP_NO; 로 해서 사용하던가

아니면

<%@ page import="mirae.login.UserInfo"%> // 해당 dto?를 임포트하고

          UserInfo s_userInfo = (UserInfo)session.getAttribute("session_userInfo");
          처럼 쓰고  사용할 때는 
          u_no = <%=s_userInfo.getEMP_NO()%>; 
          이런 식으로 사용하면 된다.


-------------------------------------------------------------------------------------------------

JSP에서

<input type="text" name="test" value ="1" />

// <input type="text" name="test" value ="2" />

<script>

function aa(frm){

alert(frm.test.value.length); // 이럴경우 1이 출력되지만 test가 2개이상되서 배열로 되면 에러...

alert(frm.test.length); // 이건 2개이상이면 길이는 잘나오지만 하나인경우 에러..

}

이런식으로 에러.. 해결방법은..
aa = document.getElementsByName("test");
alert(aa.length);

alert(aa[0].value);

사용하면 잘됨..

-----------------------------------------------------------------------------------------------

DB: MS-SQL 사용 + ibatis + proceduer 일 때.... ( DB가 orcle, my-sql은 상관없음.... ) 사용 시

프로시저 상 insert와 select가 함께 일어나는 경우가 있다.

이럴 경우 단순히 getSqlMapClient().queryForObject("proceduer id", object); 를 사용할 경우 select값이 반화이 되긴 하지만 insert문이 commit이 안된다.. 그렇다고 해서 getSqlMapClient().update("proceduer id", object); 를 하면 반환 값을 가져올 수 없게된다..

그러므로 Transaction 설정을 해야한다..

  1. sqlMapConfig.xml 설정

  2. <transactionManager type="JDBC">
  3. <dataSource type="SIMPLE">
  4. <property name="JDBC.Driver" value="${jdbc.driver}" />
  5. <property name="JDBC.ConnectionURL" value="${jdbc.url}" />
  6. <property name="JDBC.Username" value="${jdbc.username}" />
  7. <property name="JDBC.Password" value="${jdbc.password}" />
  8. <property name="commitRequired" value="true" /> //value="true" 설정..
  9. </dataSource>
  10. </transactionManager>

  1. Daoimpl 부분......................

  2. String out_balju_id = null;

  3. try {
  4. // 트랜잭션 start...
  5. getSqlMapClient().startTransaction();

  6. out_balju_id = (String) getSqlMapClient().queryForObject("APP_BALJU_INSERT_HD", insertHd);

  7. logger.info("out_balju_id="+ out_balju_id);

  8. // 트랜잭션 commit...
  9. getSqlMapClient().getCurrentConnection().commit();

  10. } catch(Exception e) {
  11. logger.error("insertHD ERROR 발생!!!", e);
  12. // 트랜잭션 rollback...
  13. getSqlMapClient().getCurrentConnection().rollback();
  14. throw e;

  15. } finally {
  16. // 트랜잭션 end.
  17. getSqlMapClient().endTransaction();
  18. }

  19. logger.info("[End] baljusave impl");

  20. resultInfo.setBALJU_ID(out_balju_id); //set 해줌.....

  21. return resultInfo;
  22. }

이 글은 스프링노트에서 작성되었습니다.


Posted by 사라링

오라클연습

2012. 5. 8. 18:39

--(반장님꺼)
-- 대상테이블 : 회원정보테이블
-- 조회컬럼   : 회원아이디 Id, 회원이름 성명, 회원성별 성별, 회원의 결혼유무(회원기념일의 데이터를근거로)를
--              유추해서 출력(decode이용) 결혼유무, 회원의 메일서버계정은 'naver.com'으로 일괄변경,
--              회원의 주민번호1을 이용해 'yy년도mm월dd일출생'으로 출력, 주민번호2의 2번째인덱스에서 4개로
--              출생신고지역코드 출력,
--              주민번호의 유효성검사후 '유효' 또는 '무효' 출력
--              예시) 123456-1234563 =>  1 2 3 4 5 6 1 2 3 4 5 6     3(매직넘버)
--                                     *2 3 4 5 6 7 8 9 2 3 4 5
--                                                   --------------------
--                                                     2+6+12+.................+30 = 206   => 206을 11로 나눈 나머지를 11에서 빼기하고, 그 수를 다시
--                                                                                            10으로 나눈 나머지가 주민번호 마지막수와 일치하면 유효주민번호
-- 정렬       : 회원아이디 내림차순
select * from member;
select (to_number(substr(mem_regno1,1,1))*2) from member;
select mem_id id,mem_name 성명,
       case when substr(mem_regno2,1,1)=1 then '남'
       else '여'
       end 성별,
       case when substr(mem_memorial,1,2)='결혼'  then '기혼'
       when substr(mem_memorial,1,2)='아내' then '기혼'
       when substr(mem_memorial,1,2)='남편' then '기혼'
       else '미혼'
       end 결혼유무,
       regexp_substr(mem_mail,'[a-zA-Z0-9]+')||'@naver.com' 메일,
       substr(mem_regno1,1,2)||'년도'||substr(mem_regno1,3,2)||'월'||substr(mem_regno1,5,2)||'일출생' 생년월일,
       decode(
       ( mod(11-mod(
       (to_number(substr(mem_regno1,1,1))*2)+(  to_number(substr(mem_regno1,2,1))*3 )+(  to_number(substr(mem_regno1,3,1))*4  )+
       ( to_number(substr(mem_regno1,4,1))*5  )+(  to_number(substr(mem_regno1,5,1))*6  )+( to_number(substr(mem_regno1,6,1))*7 )+
       ( to_number(substr(mem_regno2,1,1))*8 )+( to_number(substr(mem_regno2,2,1))*9 )+( to_number(substr(mem_regno2,3,1))*2 )+
       ( to_number(substr(mem_regno2,4,1))*3 )+( to_number(substr(mem_regno2,5,1))*4 )+( to_number(substr(mem_regno2,6,1))*5 )
       ,11),10)  )
       ,to_number(substr(mem_regno2,7,1)) ,'적합','부적합') 주민번호적합여부
from member order by 1;

 

--(반장님꺼)
--대상테이블 : 회원정보테이블, 장바구니테이블
--대상컬럼   : 회원아이디 아이디, 회원이름 성명, 구매번호 구매번호,
--            구매번호에서 구매년도 추출 구매년,
--            구매금액의합 (구매수량*판매가) 널인경우 0으로해서 천단위
--           출력형태, 원화표시 출력 구매금액
--조건      : 회원아이디가 'r001'이고 회원의 주소가 '대전',
--           구매금액은 50000000 이하
--정렬      : 회원아이디 오름차순
select substr(cart_no,1,4) 구매년 from cart;

nvl(to_char(sum(cart_qty*prod_sale),'999,999,999,999,999.00L'),0) 구매금액의합
select * from member;
select * from cart where cart_member='r001';
select * from prod;
select mem_id 아이디,mem_name 성명,cart_no 구매번호,
      substr(cart_no,1,4) 구매년,
       nvl(to_char(sum(cart_qty*prod_sale),'999,999,999,999,999L'),0) 구매금액의합
from member left outer join cart on(mem_id=cart_member)
    left outer join prod on(prod_id=cart_prod)
where mem_add1 like '대전%'
      and mem_id='r001'
group by mem_id,mem_name,cart_no
having sum(cart_qty*prod_sale)<=50000000
order by 1;

이 글은 스프링노트에서 작성되었습니다.


'오라클' 카테고리의 다른 글

SYS_CONNECT_BY_PATH  (0) 2012.07.26
오라클 구조 보기 sql 문 (desc)  (0) 2012.06.07
sqlplus에서 셀렉트 update문 가져 오기.  (0) 2012.05.08
OCP정리  (0) 2012.05.08
오라클(ORACLE)  (0) 2012.05.08
Posted by 사라링

  셀렉트 업데이트문 갖고 오기.

 

WITH
TAB_COMMENTS_CAST AS (
        SELECT *
          FROM USER_TAB_COMMENTS
         WHERE TABLE_NAME ='MEMBER' --여기에 테이블 명을 입력하세요 접속한 USER 테이블만 가능
        ),
TAB_COLUMNS_CAST AS (
        SELECT A.COLUMN_NAME
             , A.COLUMN_ID
          FROM USER_TAB_COLUMNS     A
             , TAB_COMMENTS_CAST    B
         WHERE A.TABLE_NAME = B.TABLE_NAME
         ORDER BY A.COLUMN_ID
        ),
PK_COLUMNS_CAST AS (
        SELECT A.*
          FROM USER_IND_COLUMNS   A
             , USER_CONSTRAINTS   B
             , TAB_COMMENTS_CAST  C
         WHERE A.TABLE_NAME = B.TABLE_NAME
           AND A.INDEX_NAME  = B.CONSTRAINT_NAME
           AND B.CONSTRAINT_TYPE = 'P'
           AND A.TABLE_NAME = C.TABLE_NAME
         ORDER BY A.COLUMN_POSITION
                
        )
  SELECT DECODE(ROWNUM, 1,'SELECT ','     , ')|| DECODE(SUBSTR(COLUMN_NAME, LENGTH(COLUMN_NAME)-1,2),'YN','DECODE('||COLUMN_NAME||',''1'',''1'',''0'') AS '||COLUMN_NAME, COLUMN_NAME)
    FROM TAB_COLUMNS_CAST
   WHERE COLUMN_NAME NOT IN('INSERT_ID','INSERT_IP','INSERT_PGM','INSERT_DATE','UPDATE_ID','UPDATE_IP','UPDATE_PGM','UPDATE_DATE')
  UNION ALL
  SELECT '  FROM '||TABLE_NAME  FROM TAB_COMMENTS_CAST
  UNION ALL
  SELECT DECODE(A.COLUMN_POSITION, 1,' WHERE ','   AND ') || A.COLUMN_NAME || LPAD(' = ',B.MAXLEN-LENGTH(A.COLUMN_NAME),' ') || '#'|| A.COLUMN_NAME ||'#'
    FROM PK_COLUMNS_CAST A
       , (
            SELECT MAX(LENGTH(COLUMN_NAME))+3 AS MAXLEN FROM PK_COLUMNS_CAST
         ) B
  UNION ALL SELECT '' FROM DUAL UNION ALL SELECT '' FROM DUAL
  -------------
  --UPDATE 시작
  -------------
  --UNION ALL SELECT COMMENTS || ' UPDATE' FROM TAB_COMMENTS_CAST
  UNION ALL
  SELECT 'UPDATE '||TABLE_NAME FROM TAB_COMMENTS_CAST
  UNION ALL
  SELECT DECODE(ROWNUM, 1,'   SET ','     , ') || A.COLUMN_NAME || LPAD(' = ', B.MAXLEN-LENGTH(A.COLUMN_NAME),' ')
        || DECODE(A.COLUMN_NAME,'UPDATE_DATE','SYSDATE',DECODE(SUBSTR(A.COLUMN_NAME, LENGTH(A.COLUMN_NAME)-1,2),'YN','DECODE(#'||A.COLUMN_NAME||'#,''1'',''1'',''2'')', '#'||A.COLUMN_NAME||'#') )
    FROM (
            SELECT A.COLUMN_NAME
              FROM TAB_COLUMNS_CAST  A
                 , PK_COLUMNS_CAST      B
             WHERE A.COLUMN_NAME = B.COLUMN_NAME(+)
               AND B.COLUMN_NAME IS NULL
               AND A.COLUMN_NAME NOT IN ('INSERT_ID','INSERT_IP','INSERT_PGM','INSERT_DATE')
             ORDER BY A.COLUMN_ID
          ) A
        ,(
            SELECT MAX(LENGTH(A.COLUMN_NAME))+3 AS MAXLEN
              FROM TAB_COLUMNS_CAST  A
                 , PK_COLUMNS_CAST   B
             WHERE A.COLUMN_NAME = B.COLUMN_NAME(+)
               AND B.COLUMN_NAME IS NULL
               AND A.COLUMN_NAME NOT IN ('INSERT_ID','INSERT_IP','INSERT_PGM','INSERT_DATE')
         ) B
  UNION ALL
  SELECT DECODE(A.COLUMN_POSITION, 1,' WHERE ','   AND ') || A.COLUMN_NAME || LPAD(' = ', B.MAXLEN-LENGTH(A.COLUMN_NAME),' ') || '#'|| A.COLUMN_NAME ||'#'
    FROM PK_COLUMNS_CAST A
       , (
            SELECT MAX(LENGTH(COLUMN_NAME))+3 AS MAXLEN FROM PK_COLUMNS_CAST
         ) B
  UNION ALL SELECT '' FROM DUAL UNION ALL SELECT '' FROM DUAL

이 글은 스프링노트에서 작성되었습니다.


'오라클' 카테고리의 다른 글

SYS_CONNECT_BY_PATH  (0) 2012.07.26
오라클 구조 보기 sql 문 (desc)  (0) 2012.06.07
오라클연습  (0) 2012.05.08
OCP정리  (0) 2012.05.08
오라클(ORACLE)  (0) 2012.05.08
Posted by 사라링

OCP정리

2012. 5. 8. 18:38

제 1 장 데이터의 검색
SQL 명령어는 다음과 같이 기술한다.
■ SQL 명령어는 한 줄 혹은 여러 줄에 기술한다.
■ 일반적으로 절들은 수정하기 쉽게 다른 줄에 기술한다.
■ TAB 을 사용할 수 있다.
■ SQL 명령어 단어는 생략하거나 분리할 수 없다.
■ SQL 명령어는 대소문자를 구분하지 않는다.
■ SQL 명령어는 ; 으로 종료한다.
■ SQL 명령어는 SQL BUFFER 에 저장된다.
■ SQL BUFFER 에 저장된 SQL 명령어는 / 혹은 RUN 으로 실행할 수 있다.
SQL*PLUS 명령어는 다음과 같이 기술한다.
■ SQL*PLUS 명령어는 기본적으로 한 줄에 기술한다.
■ SQL*PLUS 명령어는 대소문자를 구별하지 않는다.
■ SQL*PLUS 명령어는 SQL BUFFER 에 저장되지 않는다.
■ SQL*PLUS 명령어는 다음과 같다.
• DESCRIBE table명 : TABLE 의 구조를 보여준다.
• SAVE file명 : SQL BUFFER 를 file 로 저장한다.
• START file명 : file 을 수행한다.
• @ file명 : file 을 수행한다.
• EDIT file명 : EDITOR 를 사용하여 file 을 편집한다.
• SPOOL file명 : QUERY 결과를 file 에 저장한다.
• SPOOL OFF : SPOOL FILE 을 닫는다.
• HOST : SQL*PLUS 를 떠나지 않고 HOST 상태로 간다.
• HELP 명령어 : SQL, SQL*PLUS, PL/SQL 에 대한 HELP 를 보내준다.
• EXIT : SQL*PLUS 를 종료한다.

전체 데이타의 검색
가장 간단한 SELECT 문장의 형식은 다음과 같다.
. SELECT 절에는 검색하고 싶은 COLUMN 명들을 기술한다.
. FROM 절에는 SELECT 절에서 기술된 COLUMN 명들이 포함된 TABLE 명을 기술한다.
TABLE 의 모든 ROW 와 모든 COLUMN 을 검색한다.
SELECT *
FROM table명 ;
[ 예제 ]
S_DEPT TABLE 로부터 모든 ROW 와 COLUMN 을 검색하시오.
SELECT *
FROM S_DEPT ;

특정 column의 검색
SELECT 절에서 검색하고자 하는 COLUMN 명을 COMMA 를 사용하여 나열한다.
COLUMN 순서는 검색하고 싶은 순서대로 나열한다.
COLUMN HEADING 은 COLUMN 명이 대문자로 출력된다.
SELECT column명, column명, column명,..
FROM table명 ;
[ 예제 ]
S_EMP TABLE 로부터 ID, LAST_NAME, START_DATE 를 검색하시오.

SELECT ID, LAST_NAME, START_DATE
FROM S_EMP ;

산술식을 사용한 검색
산술 연산자를 사용하여 검색되는 데이타 값을 변경할 수 있다.
산술 연산식은 COLUMN 명, 상수 값, 산술 연산자로 구성된다.
SELECT 산술연산식
FROM table명 ;
[ 예제 ]
S_EMP TABLE 로부터 ID, LAST_NAME, 연봉을 검색하시오.
연봉은 SALARY * 12 로 계산한다. (+,-,*,/,())
SELECT ID, LAST_NAME, SALARY * 12
FROM S_EMP ;

Column alias
기본적으로 COLUMN HEADING 은 COLUMN 명이 대문자로 출력된다.
그러나 많은 경우 COLUMN 명이 이해하기 어렵거나 무의미하기 때문에 COLUMN ALIAS 를 사용하여
COLUMN HEADING 을 변경할 수 있다.
ANSI SQL 92 와 호환을 위해 ALIAS 앞에 AS 를 붙일 수 있다.
ALIAS 에 공백이나 특수문자가 포함되거나 대소문자를 구별하고 싶으면 " " 로 막아준다.
COLUMN ALIAS 를 사용하여 COLUMN HEADING 을 변경할 수 있다.
SELECT column명 alias, column명 "alias", column명 as alias
FROM table명 ;
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, (SALARY + 100) * 12, DEPT_ID 를 검색하시오.
단, COLUMN ALIAS 는 Employee, ANNUAL_SALARY, DEPARTMENT NO 로 정의하시오.
SELECT LAST_NAME "Employee", (SALARY + 100) * 12 AS ANNUAL_SALARY,
DEPT_ID "DEPARTMENT NO"
FROM S_EMP ;

Column의 결합
COLUMN 과 다른 COLUMN, 산술연산식, 상수 값과 결합하여 하나의 COLUMN 으로 결합할 수 있다.
SELECT column명|| column명
FROM table명;
[ 예제 ]
S_EMP TABLE 에서 FIRST_NAME 과 LAST_NAME 을 결합하여 ALIAS EMPLOYEE 로 검색하시오.
SELECT FIRST_NAME || LAST_NAME EMPLOYEE
FROM S_EMP ;

Null값 처리
특정 COLUMN 에 값이 입력되어 있지 않을 때, 그 값을 NULL 이라 부른다.
NULL 값은 0 이나 공백과 같지 않다.
NULL 값이 산술 연산식에 포함되면 그 결과도 NULL 이다.
그러므로 NVL FUNCTION 을 사용하여 NULL 값을 다른 값으로 대체하여야 한다.
NULL 값을 다른 값으로 대체한다.
NVL (number_column, 9)
NVL (date_column, '01-JAN-95')
NVL (character_column, 'ABCDE')
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, COMMISSION 값을 검색하시오.
COMMISSION 은 SALARY * COMMISSION_PCT /100 으로 계산하시오.
SELECT LAST_NAME, SALARY * NVL(COMMISSION_PCT,0) /100 COMMISSION
FROM S_EMP ;

중복 row의 제거
SELECT 결과 값에 중복된 값이 있을 때 중복을 피하고 UNIQUE 하게 검색한다.
중복된 ROW 를 제거한다.
SELECT DISTINCT column명, column명
FROM table명;
[ 예제 ]
S_DEPT TABLE 에서 NAME 이 중복되지 않게 검색하시오.
SELECT DISTINCT NAME
FROM S_DEPT ;

데이타의 정렬
SELECT 되는 ROW 의 순서는 알 수 없다.
그러므로 ROW 를 SORT 하고 싶으면 ORDER BY 절을 사용하여야 한다.
DATA 의 DEFAULT SORT 순서는 ASCENDING 이며 다음과 같다.
• 숫자 : 1 에서 999 순으로 SORT 한다.
• 날짜 : 01-JAN-92 에서 01-JAN-95 순으로 SORT 한다.
• 문자 : A 에서 Z 순서로 SORT 한다.
• NULL : ASC 순에서는 뒤에, DESC 순에서는 앞에 나온다.
역순으로 SORT 하고 싶으면 COLUMN 명 뒤에 DESC 를 붙인다.
COLUMN 명 대신에 ALIAS 혹은 SELECT 한 COLUMN 의 순서로 지정할 수도 있다.
SELECT expr
FROM table명
ORDER BY {column명, expr} [ASC|DESC] ;
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, DEPT_ID, START_DATE 를 LAST_NAME 순으로 검색하시오.
SELECT LAST_NAME, DEPT_ID, START_DATE
FROM S_EMP
ORDER BY LAST_NAME ;

특정 row의 검색
WHERE 절에서 조건식을 기술하여 조건을 만족하는 ROW 만 검색할 수 있다.
조건식은 COLUMN 명, COMPARISON OPERATOR, VALUE 로 구성되어 있다.
문자 값은 ' ' 으로 묶어주고 값의 대소문자를 구별하여 적어준다.
날짜 값은 ' ' 으로 묶어주고 지정된 날짜 형태로 적어준다. '01-MAR-97'
숫자값은 값만 적어준다.
특정 ROW 만 검색한다.
SELECT expr
FROM table명
WHERE expr operator value
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME 이 Magee 인 사원의 FIRST_NAME, LAST_NAME,
TITLE 을 검색하시오. (=,>,<,>=,<=,<>)
SELECT FIRST_NAME, LAST_NAME, TITLE
FROM S_EMP
WHERE LAST_NAME = 'Magee' ;

Between...and
BETWEEN OPERATOR 를 사용하여 범위를 지정할 수 있다.
범위를 지정할 때는 작은 값을 먼저 큰 값을 나중에 지정한다.
두 범위의 한계 값을 포함한다.
BETWEEN...AND...
NOT BETWEEN...AND...
[ 예제 ]
S_EMP TABLE 에서 START_DATE 가 09-MAY-91 에서 17-JUN-91 사이에 입사한
사원의 FIRST_NAME, LAST_NAME, START_DATE 를 검색하시오.
SELECT FIRST_NAME, LAST_NAME, START_DATE
FROM S_EMP
WHERE START_DATE BETWEEN '09-MAY-91' AND '17-JUN-91' ;

In[list]
IN OPERATOR 를 사용하여 나열된 값들 중에서 값을 검사한다.
IN(LIST), NOT IN(LIST)
[ 예제 ]
S_EMP TABLE에서 DEPT_ID 가 10 , 31, 41 혹은 50 인 사원의 FIRST_NAME,
LAST_NAME, DEPT_ID 를 검색하시오.
SELECT FIRST_NAME, LAST_NAME, DEPT_ID
FROM S_EMP
WHERE DEPT_ID IN (10, 31, 41, 50) ;

like
찾고자 하는 값을 정확히 모를 때, LIKE OPERATOR 를 사용하여 문자형태가 같은 ROW 를 검색한다.
WILDCARD 를 사용하여 문자의 형태를 지정한다.
% : 여러 문자, _ : 한문자
LIKE '형태', NOT LIKE '형태'
[ 예제 ]
S_EMP TABLE에서 LAST_NAME 이 M 으로 시작하는 사원의 LAST_NAME 을 검색하시오.
SELECT LAST_NAME
FROM S_EMP
WHERE LAST_NAME LIKE 'M%' ;
SELECT LAST_NAME
FROM S_EMP
WHERE LAST_NAME LIKE '__M____' ;

is null
IS NULL OPERATOR을 사용하여 값이 NULL 인 것을 찾을 수 있다.
NULL 값은 값이 정의되지 않은 것을 의미하기 때문에 = OPERATOR를 사용하여
어떤 값과 비교할 수 없기 때문에 사용한다.
IS NULL, IS NOT NULL
[ 예제 ]
S_EMP TABLE에서 COMMISSION_PCT 가 NULL 인 사원의 LAST_NAME, SALARY,
COMMISSION_PCT 를 검색하시오.
SELECT last_name, salary,commission_pct,last_name, salary
FROM s_emp
WHERE commission_pct is null;

조건식의 결합
조건식을 기술할 때 AND 와 OR 를 사용하여 여러가지 조건을 결합할 수 있다.
AND 와 OR 가 같이 사용됐을 때 AND 가 먼저 수행되고 OR 가 나중에 수행된다.
그러므로 우선순위를 바꾸고자 하면 ( ) 를 사용한다.
WHERE 조건식 AND | OR 조건식
[ 예제 ]
S_EMP TABLE에서 DEPT_ID 가 41 이고 TITLE 이 Stock Clerk 인 사원의
LAST_NAME, SALARY, DEPT_ID, TITLE 을 검색하시오.
SELECT LAST_NAME, SALARY, DEPT_ID, TITLE
FROM S_EMP
WHERE DEPT_ID = 41
AND TITLE = 'Stock Clerk' ;

제 2 장 Single Row Functions
소문자로 변환
모든 문자를 소문자로 변환시킨다.
LOWER(COLUMN명)
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME 이 Smith 인 사원의 FIRST_NAME, LAST_NAME 을 소문자로 출력시키시오.
SELECT LOWER(FIRST_NAME), LOWER(LAST_NAME)
FROM S_EMP
WHERE LOWER(LAST_NAME) = 'smith' ;

대문자로 변환
모든 문자를 대문자로 변환시킨다.
UPPER(COLUMN명)
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME 이 Smith 인 사원의 TITLE 을 대문자로 출력하시오.
SELECT UPPER(TITLE)
FROM S_EMP
WHERE UPPER(LAST_NAME) = 'SMITH';

첫글자만 대문자로 변환
단어의 첫글자는 대문자로, 나머지는 소문자로 변환시킨다.
INITCAP(COLUMN명)
[ 예제 ]
S_EMP TABLE 에서 TITLE 을 단어의 첫글자만 대문자로 출력시키시오.
SELECT INITCAP(TITLE)
FROM S_EMP ;

문자의 부분을 자름
문자를 시작위치(M)에서 자리수(N) 만큼 잘라준다.
자리수(N)이 생략되면 시작위치(M)에서 끝까지 잘라준다.
SUBSTR(COLUMN명, M, N)
[ 예제 ]
S_PRODUCT TABLE 에서 NAME COLUMN 의 앞에서 부터 3글자가 Ace 인 제품의
NAME 을 출력하시오.
SELECT NAME
FROM S_PRODUCT
WHERE SUBSTR(NAME, 1, 3) = 'Ace' ;

문자의 길이를 계산
문자의 길이를 RETURN 한다.
LENGTH(COLUMN명)
[ 예제 ]
S_PRODUCT TABLE 에서 NAME, NAME 의 길이를 출력하시오.
SELECT NAME, LENGTH(NAME)
FROM S_PRODUCT;

숫자의 반올림
지정된 자리수(M) 밑에서 반올림한다.
COLUMN 값이 1 2 3 4. 5 6 7 일 때 자리수(M)는 다음과 같다.
     M : -3-2-1 0 1 2 3
ROUND(COLUMN명, M)
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, SALARY/22 의 값을 소수 2째 자리까지 나타내고
소수 3째 자리에서 반올림하시오.
SELECT LAST_NAME, ROUND(SALARY/22, 2)
FROM S_EMP ;

숫자의 절사
지정된 자리수(M) 까지 나타내고 그 밑은 잘라버린다.
COLUMN 값이 1 2 3 4. 5 6 7 일 때 자리수(M)은 다음과 같다.
     M : -3-2-1 0 1 2 3
절사 값은 RETURN 한다.
TRUNC(COLUMN명, M)
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, SALARY / 22 의 값을 십의 자리까지 나타내고
일의 자리는 버림
SELECT LAST_NAME, TRUNC(SALARY/22, -1)
FROM S_EMP ;

나누기의 나머지
M 을 N 으로 나누고 남은 나머지를 RETURN 한다.
MOD(M, N)
[ 예제 ]
10 을 3 으로 나눈 나머지를 구하시오.
SELECT MOD(10, 3)
FROM SYS.DUAL ;

날짜의 연산
DATABASE 안의 DATE 값은 다음과 같은 숫자로 저장되어 있다.
■ CENTURY, YEAR, MONTH, DAY, HOURS, MINUTES, SECONDS
그러므로 산술 연산을 할 수 있다.
● DATE + NUMBER : 숫자만큼 일이 더해진 날짜가 RETURN 된다.
● DATE - NUMBER : 숫자만큼 일이 빼진 날짜가 RETURN 된다.
● DATE1 - DATE2 : 두 날짜 사이의 일수가 계산된다.
날짜 계산을 한다.
DATE + NUMBER
DATE - NUMBER
DATE1 - DATE2
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, 입사한지 90 일째 되는 날, 입사한지 며칠 됐는 지 검색하시오.
SELECT LAST_NAME, START_DATE + 90, SYSDATE - START_DATE
FROM S_EMP;
( 날짜에는 시간도 포함되어 있으므로 일수 계산의 결과가 소수로 나온다. )

날짜 사이의 개월 수
두 날짜 사이의 개월 수를 RETURN 한다.
MONTHS_BETWEEN(DATE1, DATE2)
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, 입사한지 몇 달이 됐는지 출력하시오.
SELECT LAST_NAME, MONTHS_BETWEEN(SYSDATE, START_DATE)
FROM S_EMP ;
(일이 포함되어 있어서 소수로 출력된다.)

날짜에 달을 더함
날짜에서 숫자(N) 개월만큼 더해진 날짜를 RETURN 한다.
ADD_MONTHS(DATE, N)
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, START_DATE, 입사한지 3 개월되는 날짜를 출력하시오.
SELECT LAST_NAME, START_DATE, ADD_MONTHS(START_DATE, 3)
FROM S_EMP ;

지정한 요일 날짜
날짜에서 지정한 요일(CHAR)이 될 날짜를 RETURN 한다.
NEXT_DAY(DATE, 'CHAR')
[ 예제 ]
오늘을 기준으로 돌아오는 금요일이 언제인지 출력하시오.
SELECT SYSDATE, NEXT_DAY(SYSDATE, 'FRIDAY')
FROM SYS.DUAL ;

그 달의 마지막 날
날짜가 포함된 달의 마지막 날을 RETURN 한다.
LAST_DAY(DATE)
[ 예제 ]
이번 달의 마지막 날은 언제인지 출력하시오.
SELECT SYSDATE, LAST_DAY(SYSDATE)
FROM SYS.DUAL ;

날짜의 반올림
형태에 따른 반올림 기준은 다음과 같다.
• YEAR : 6월 이후
• MONTH : 15일 이후
• DAY : 12시 이후
날짜 데이타를 지정된 형태까지 나타내고 그 이하에서 반올림한다.
ROUND(COLUMN명, '형태')
[ 예제 ]
S_EMP TABLE 에서 ID, LAST_NAME, 입사 시작 달을 검색하시오.
단, 15일 이후는 다음달로 올리시오.
SELECT ID, LAST_NAME, ROUND(START_DATE, 'MONTH')
FROM S_EMP ;

날짜의 절사
날짜 데이타를 지정된 형태까지 나타내고 그 밑은 잘라낸다.
TRUNC(COLUMN명, '형태')
[ 예제 ]
S_EMP TABLE 에서 ID, LAST_NAME, 입사 시작 달을 검색하시오.
단, 일자는 잘라버리시오.
SELECT ID, LAST_NAME, TRUNC(START_DATE, 'MONTH')
FROM S_EMP ;

문자를 날짜로 변환
CHARACTER TYPE 을 지정된 형태의 DATE TYPE 으로 변환한다.
TO_DATE(character_column명, '형태')
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, START_DATE 를 검색하시오.
단, START_DATE 의 값이 92/02/07 인 사원을 검색하시오.
SELECT LAST_NAME, START_DATE
FROM S_EMP
WHERE START_DATE = TO_DATE('92/02/07', 'YY/MM/DD') ;

날짜를 문자로 변환
DATE 값은 기본적으로 DD-MON-YY 형태로 출력된다.
이것을 TO_CHAR FUNCTION 을 사용하면 원하는 다른 형태로 변환할 수 있다.
■ 형태를 지정할 때 사용된 대소문자로 출력된다.
■ DAY 와 MONTH 형태는 공백을 포함한 9 자리로 출력된다.
■ TO_CHAR 의 결과는 80 자리로 출력된다.
DATE TYPE 을 지정된 형태의 CHARACTER TYPE 으로 변환한다.
TO_CHAR(date_column, '형태')
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, START_DATE 를 검색하시오.
단, START_DATE 의 형태는 1991/06/17 14:20:00 와 같이 출력하시오.
SELECT LAST_NAME, TO_CHAR(START_DATE, 'YYYY/MM/DD HH24:MI:SS'), START_DATE
FROM S_EMP ;

숫자를 문자로 변환
NUMBER TYPE 을 지정된 형태의 CHARACTER TYPE 으로 변환한다.
TO_CHAR(number_column명, '형태')
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME, SALARY 를 검색하시오.
단 SALARY 를 $1,450 와 같은 형태로 출력시키시오.
SELECT LAST_NAME, TO_CHAR(SALARY, '$999,999')
FROM S_EMP ;


제 3 장. 여러Table로부터 Data검색
Equijoin
SIMPLE JOIN (EQUI-JOIN)
여러개의 TABLE 들로부터 정보를 검색하려면, SELECT 문장의 FROM 절에 TABLE명들을 적고
WHERE 절에 각 TABLE의 ROW들을 연결시킬 조건식을 기술한다.
각 TABLE 의 COLUMN명이 중복될 때는 반드시 COLUMN명 앞에 TABLE명을 붙여야 한다.
(중복되지 않을 때는 붙이지 않아도 되지만 명확성을 위해서나 ACCESS 를 위해서 붙이는 것이 좋다.)
N 개의 TABLE 을 JOIN 할 때는 최소한 N-1 개의 조건식이 필요하다.
복합 COLUMN 으로 JOIN 할 때는 더 많은 조건식이 필요하다.
2개 이상의 TABLE 에서 = 조건식을 만족시키는 ROW 들을 연결하여 검색한다.
SELECT table명.column명, table명.column명...
FROM table1명, table2명
WHERE table1명.column1명 = table2명.column명 ;
[ 예제 ]
S_EMP TABLE 과 S_DEPT TABLE 을 사용하여 사원들의 LAST_NAME, DEPT_ID,
NAME 을 검색하시오.
SELECT S_EMP.LAST_NAME, S_EMP.DEPT_ID, S_DEPT.NAME
FROM S_EMP, S_DEPT
WHERE S_EMP.DEPT_ID = S_DEPT.ID ;

특정 row의 join
JOIN 문장을 기술할 때 JOIN 조건식 이외에 다른 조건식을 AND 로 연결할 수 있다.
SELECT table명.column명, table명.column명...
FROM table1명, table2명
WHERE table1명.column1명 = table2명.column2명 AND condition ;
[ 예제 ]
S_EMP TABLE과 S_DEPT TABLE 을 사용하여 LAST_NAME 이 Menchu 인 사원의
LAST_NAME, DEPT_ID, NAME 을 검색하시오.
SELECT S_EMP.LAST_NAME, S_EMP.DEPT_ID, S_DEPT.NAME
FROM S_EMP, S_DEPT
WHERE S_EMP.DEPT_ID = S_DEPT.ID AND S_EMP.LAST_NAME = 'Smith' ;

Table alias
JOIN 문장에서 TABLE명이 긴 경우 TABLE명.COLUMN명 으로 적는 것이 매우 불편하다.
그런데 TABLE명 대신 ALIAS 를 사용하면 편하게 사용할 수 있다.
(SELECT 문장에서 TABLE명 대신 ALIAS 를 지정했다면 그 문장에서는 계속해서
ALIAS 로 사용하여야 한다.)
TABLE ALIAS를 사용하여 JOIN 문장을 간단하게 기술한다.
SELECT alias명.column명, alias명.column명
FROM table1명 alias1명, table2명 alias2명
WHERE alias1명.column1명 = alias2명.column2명 ;
[ 예제 ]
S_CUSTOMER TABLE과 S_REGION TABLE 을 사용하여 고객 명,지역번호,지역 명을 검색하시오.
단, COLUMN ALIAS 와 TABLE ALIAS 를 사용하시오.
SELECT C.NAME "Customer Name", C.REGION_ID "Region Id",
R.NAME "Region Name"
FROM S_CUSTOMER C, S_REGION R
WHERE C.REGION_ID = R.ID ;

Non-Equijoin
NON-EQUIJOIN
JOIN 문장에서 두 TABLE 을 JOIN 하는 조건식에 = OPERATOR 가 사용되지 않고
다른 OPERATOR 가 사용되는 것을 말한다.
SELECT table명.column명, table명.column명...
FROM table1명, table2명
WHERE 조인조건식 ;
[ 예제 ]
EMP TABLE 과 SALGRADE TABLE 을 사용하여 사원의 ENAME, JOB, SAL,GRADE를 검색하시오.
SELECT E.ENAME, E.JOB, E.SAL, S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL ;
(BETWEEN OPERATOR 대신에 <= 와 >= 를 사용해도 되지만 BETWEEN 이 간편하다.)

Outer Join
두 TABLE 을 JOIN 할 때 JOIN 조건식을 만족시키지 못하는 ROW 는 검색에서 빠지게 된다.
그런데 이러한 ROW 들이 검색되도록 하는 것이 OUTER JOIN 이다.
(+) OUTER JOIN OPERATOR 를 데이타가 없는 어느 한쪽의 COLUMN 쪽에 붙인다.
JOIN 결과, 데이타가 없는 쪽의 COLUMN 값은 NULL로 검색된다.
조건식을 만족시키지 못하는 데이타도 검색한다.
SELECT table명.column명, table명.column명
FROM table1명, table2명
WHERE table1명.column1명 = table2명.column2명(+)
[ 예제 ]
S_EMP TABLE 과 S_CUSTOMER TABLE 을 사용하여 영업사원의 LAST_NAME,
SALES_REP_ID, NAME 을 검색하시오.
단, 영업사원이 정해져 있지 않은 고객의 이름도 검색하시오.

SELECT E.LAST_NAME, C.SALES_REP_ID,
C.NAME
FROM S_EMP E, S_CUSTOMER C
WHERE E.ID(+) = C.SALES_REP_ID ;

Self Join
TABLE 의 ALIAS 를 사용하여, 마치 2 개의 TABLE 처럼 생각하여 자신의 TABLE 과 자신의 TABLE 을 JOIN 한다.
SELECT alias명.column명, alias명.column명...
FROM table명 alias1명, table명 alias2명
WHERE alias1명.column1명 = alias2명.column2명 ;
[ 예제 ]
S_EMP TABLE 에서 사원들의 LAST_NAME 과 그들의 상사 LAST_NAME 을 검색하시오.
SELECT W.LAST_NAME "Woker",
M.LAST_NAME "Manager"
FROM S_EMP W, S_EMP M
WHERE W.MANAGER_ID = M.ID ;

제 4 장. Group Functions
Group Function
각각의 FUNCTION 은 ARGUMENT 를 받는데 기능은 다음과 같다.
■ DISTINCT : 중복된 값은 제외한다.
■ ALL : DEFAULT 로써 모든 값을 포함한다.
■ COLUMN명 : NULL 값은 제외한다.
■ * : NULL 값도 포함한다.
TABLE 전체를 하나의 GROUP 으로 보고 GROUP FUNCTION 값을 RETURN 한다.
SELECT group_function(column명), group_function(column명)...
FROM table명 ;
[ 예제 ]
S_EMP TABLE 에서 회사 전체의 급여합계, 최고급여, 최소급여, 인원수를 검색하시오.
SELECT SUM(SALARY), MAX(SALARY), MIN(SALARY), COUNT(SALARY)
FROM S_EMP ;
( COUNT(SALARY) 는 급여를 받는 사원의 총 인원수고 COUNT(*) 는 급여를 받지 않는 사원의 인원수도 포함된다.)

소group으로 분리
기본적인 SELECT 절(그룹화 되지 않은 SELECT절)에는 COLUMN 명과 GROUP FUNCTION 이 같이 기술될 수 없다.
SELECT 절에 COLUMN 명이 기술되려면 GROUP BY 절이 반드시 기술되어야 한다.
SELECT 절에 기술된 COLUMN 명들은 전부 GROUP BY 절에 기술되어야 하며
GROUP BY 절에 기술된 COLUMN 명들은 SELECT 절에 기술되지 않아도 된다.
(하지만 결과를 파악하기 위해서는 SELECT 절에 기술해주는 것이 좋다.)
GROUP BY 절을 기술하면 GROUP BY 절에 기술된 COLUMN 값으로 1 개의 TABLE이 소 GROUP 으로 나눠진다.
결과는 COLUMN 값으로 SORT 되어서 출력된다.
1 개의 TABLE 을 소 GROUP 으로 나누어 GROUP FUNCTION 값을 구한다.
SELECT column1명[, column2명], group_function(column명)
FROM table명
GROUP BY column1명[, column2명] ;
[ 예제 ]
S_EMP TABLE 에서 DEPT_ID, TITLE 별로, 최고급여, 최소급여, 인원수를 검색하시오.
SELECT DEPT_ID, TITLE,
MAX(SALARY), MIN(SALARY),
COUNT(SALARY)
FROM S_EMP
GROUP BY DEPT_ID, TITLE;

특정 group의 선택
HAVING 절이 기술됐을 때 처리되는 순서는 다음과 같다.
① ROW 들이 GROUPing 된다.
② GROUP 에 대해 GROUP FUNCTION 이 적용된다.
③ HAVING 절을 만족하는 GROUP 을 선택한다.
그러므로 GROUP BY 절과 HAVING 절의 순서는 바뀌어도 되지만 의미상 GROUP BY
절 다음에 HAVING 절을 기술하는 것이 좋다.
HAVING 절에서는 GROUP FUNCTION 을 사용하여 GROUP 에 대한 조건식을 기술한다.
SELECT column1명[, column2명], group_function(column명)
FROM table명
GROUP BY column1명[, column2명]
HAVING 그룹조건식 ;
[ 예제 ]
S_EMP TABLE 에서 TITLE 별로 급여합계를 검색하시오.
단, 급여합계가 5000 이상인 GROUP 만 출력하시오.
SELECT TITLE, SUM(SALARY) PAYROLL
FROM S_EMP
GROUP BY TITLE
HAVING SUM(SALARY) >= 5000 ;

Group의 정렬
기본적으로 GROUP BY 절에 기술된 COLUMN 값으로 SORT 된다.
이 순서를 바꾸고자 하면 ORDER BY 절을 기술하면 된다.
DATA 의 SORT 순서를 정한다.
SELECT column1명[, column2명], group_function(column명)
FROM table명
GROUP BY column1명[, column2명]
ORDER BY column명| group_function(column명) ;
[ 예제 ]
S_EMP TABLE에서 DEPT_ID 별로 인원수를 검색하시오.
단, 인원수가 많은 부서부터 출력하시오.
SELECT DEPT_ID, COUNT(*)
FROM S_EMP
GROUP BY DEPT_ID
ORDER BY COUNT(*) DESC ;

제 5 장. Subquery
Single Row Subquery
SUBQUERY 의 결과가 1 개의 ROW 로 나오는 것을 SINGLE ROW SUBQUERY 라 하며
다음과 같은 OPERATOR 를 사용할 수 있다.
=, >, >=, <, <=
VALUE 값을 구하기 위해 SELECT 문장을 사용한다.
SELECT column명, column명...
FROM table명
WHERE column명 operator (SELECT column명
FROM table명
WHERE 조건식 );
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME 이 Smith 인 사원과 같은 업무(TITLE)를 하고 있는
사원의 LAST_NAME, TITLE 을 검색하시오.
SELECT LAST_NAME, TITLE
FROM S_EMP
WHERE TITLE =
( SELECT TITLE
FROM S_EMP
WHERE LAST_NAME = 'Smith') ;

From절의 Subquery
FROM 절에 기술된 SUBQUERY 문은 VIEW 처럼 사용된다.
SELECT alias명.column명, alias명,column명...
FROM table1명 alias1명, (SELECT column2명
FROM table2명
WHERE 조건식) alias2명
WHERE alias1명.column1명 OPERATOR alias2명.column2명 ;
[ 예제 ]
S_EMP TABLE 에서 SALARY 가 회사평균급여 보다 적은 사원의 LAST_NAME,
SALARY, 회사평균급여를 검색하시오.
SELECT E.LAST_NAME, E.SALARY, S.AVGSAL
FROM S_EMP E,
(SELECT AVG(SALARY) AVGSAL
FROM S_EMP) S
WHERE E.SALARY < S.AVGSAL ;

Multi Row Subquery
SUBQUERY 의 결과가 여러 ROW 일 때는 반드시 IN OPERATOR 를 사용하여야 한다.
SELECT column명, column명...
FROM table명
WHERE column명 IN ( SELECT column명
FROM table명
WHERE 조건식);
[ 예제 ]
S_EMP TABLE 과 S_DEPT TABLE 에서 Operations 부서에서 근무하는 사원의
LAST_NAME, TITLE, DEPT_ID 를 검색하시오.
SELECT LAST_NAME, TITLE, DEPT_ID
FROM S_EMP
WHERE DEPT_ID IN (SELECT ID
FROM S_DEPT
WHERE NAME = 'Operations') ;

Multi Column Subquery
SELECT 문장의 WHERE 절에서 여러개의 COLUMN 값을 비교하려면 LOGICAL
OPERATOR 를 사용하여 여러개의 조건식을 기술하여야 한다.
그런데 MULTI COLUMN SUBQUERY 를 사용하면 이를 해결할 수 있다.
SELECT column명, column명,,,
FROM table명
WHERE (column명, column명...) IN (SELECT column명, column명...
FROM table명
WHERE 조건식);
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME Patel 인 사원과 같은 부서, 같은 업무를
맡고 있는 사원의 LAST_NAME, TITLE, DEPT_ID 를 검색하시오.
SELECT LAST_NAME, TITLE, DEPT_ID
FROM S_EMP
WHERE (DEPT_ID, TITLE) IN
(SELECT DEPT_ID, TITLE
FROM S_EMP
WHERE LAST_NAME = 'Patel') ;
SELECT LAST_NAME, TITLE, DEPT_ID
FROM S_EMP
WHERE (DEPT_ID) IN
(SELECT DEPT_ID
FROM S_EMP
WHERE LAST_NAME = 'Patel')
OR (TITLE) IN
(SELECT TITLE
FROM S_EMP
WHERE LAST_NAME = 'Patel') ;

제 6 장. Table 생성
이름 붙이는 법
이름은 다음의 규칙을 따라서 지정한다.
■ TABLE 명이나 COLUMN 명은 문자로 시작하고 30 자 이내로 지정한다.
■ A ~ Z, a ~ z, 0 ~ 9, _ , $ , # 을 사용할 수 있다.
■ 한 USER 내에서는 다른 OBJECT 의 이름과 동일하게 지정할 수 없다.
■ ORACLE7 SERVER 예약어를 사용할 수 없다.
■ 대소문자를 구별하지 않는다.

Oracle 7 datatype
COLUMN 의 DATATYPE 은 다음과 같다.
■ CHAR(size) : 고정된 size 의 문자 값, 최대 255 자까지 지정할 수 있다.
■ VARCHAR2(size) : size내에서의 가변길이 문자 값,최대 2000자까지 지정할 수 있다.
■ LONG : 가변길이 문자 값, 최대 2 기가 바이트까지 사용할 수 있다. TABLE 당 한 개의 COLUMN 에만 지정 가능하다.
■ NUMBER(p,s) : 정수, 소수 자리수의 합이 P, 소수 자리수가 s 인 숫자값, 최대 38 자리수까지 지정할 수 있다.
■ DATE : 날짜와 시간 값, B.C. 4712년 1월 1일부터 A.D. 4712년 12월 31일까지 입력할 수 있다.
■ RAW(size) : size 내에서의 가변길이 BINARY DATA
■ LONGRAW : 가변길이 BINARY DATA

다른 table로부터 table생성
기존하는 TABLE 로 부터 데이타와 구조를 복사하여 TABLE 을 생성한다.
CREATE TABLE table명 [(column명, column명...)]
AS subquery ;
[ 예제 ]
S_EMP TABLE 에서 DEPT_ID 가 41 인 사원들의 ID, LAST_NAME, USERID,
START_DATE 만을 복사하여 EMP_41 TABLE 을 생성하시오.
CREATE TABLE EMP_41
AS SELECT ID, LAST_NAME, USERID, START_DATE
FROM S_EMP
WHERE DEPT_ID = 41;
(S_EMP TABLE 에서 COLUMN명, TYPE, SIZE, NOT NULL CONSTRAINT 가 복사되어 EMP_41 TABLE 이 생성되며, 데이타는 DEPT_ID = 41 인 ROW 만 복사된다.)

Constraint
CONSTRAINT 의 종류는 다음과 같다.
■ NOT NULL
COLUMN 에 NULL 값이 입력되는 것을 허용하지 않는다.
COLUMN-CONSTRAINT 로만 기술해야 한다.
■ UNIQUE
한 개의 COLUMN 혹은 복합 COLUMN 을 UNIQUE KEY 로 지정한다.
UNIQUE KEY 에는 중복된 값을 허용하지 않는다.
한개의 COLUMN 으로 구성된 UNIQUE KEY 는 NULL 값을 허용한다.
COLUMN 이나 TABLE-CONSTRAINT 로 기술할 수 있다.
복합 COLUMN 으로 구성된 UNIQUE KEY 는 TABLE-CONSTRAINT 로만 기술해야 한다.
UNIQUE KEY COLUMN 의 UNIQUE INDEX FILE 이 자동 생성된다.
■ PRIMARY KEY
ROW 를 UNIQUE 하게 대표할 수 있는 한개의 COLUMN 혹은 복합 COLUMN 으로 지정한다.
PRIMARY KEY 에는 중복된 값과 NULL 값을 허용하지 않는다.
TABLE 당 한 개의 PRIMARY KEY 만 지정할 수 있다.
COLUMN 이나 TABLE-CONSTRAINT 로 기술할 수 있다.
복합 COLUMN 으로 구성된 PRIMARY KEY 는 TABLE-CONSTRAINT 로만 기술해야 한다.
PRIMARY KEY COLUMN 의 UNIQUE INDEX FILE 이 자동 생성된다.
■ FOREIGN KEY
한개의 COLUMN 혹은 복합 COLUMN 으로 지정한다.
같은 TABLE 혹은 다른 TABLE의 PRIMARY KEY 나 UNIQUE KEY 값을 참조한다.
FOREIGN KEY 값은 모 TABLE 에 존재하는 데이타와 같던가 NULL 값을 허용한다.
COLUMN 이나 TABLE-CONSTRAINT 로 기술할 수 있다.
※ CHECK : 각각의 ROW 가 만족해야할 조건을 지정한다.
조건식은 QUERY 조건식과 동일하게 지정한다.
단, 다음과 같은 것은 사용할 수 없다.
CURRVAL, NEXTVAL, LEVEL, ROWNUM, SYSDATE, USER COLUMN 이나
TABLE-CONSTRAINT 로 기술할 수 있다.
CONSTRAINT 명은 다음과 같이 지정한다.
• CONSTRAINT 는 DICTIONARY 에 저장되므로 참조하기 쉽게 의미있게 붙여준다.
• 일반적으로 TABLE명_COLUMN명_CONSTRAINT종류와 같은 형태로 지정한다.
• 사용자가 CONSTRAINT 명을 지정하지 않으면 ORACLE7이 SYS_Cn의 형태로 붙인다.
• 동일한 USER 내에서 CONSTRAINT명은 UNIQUE해야 한다.
CONSTRAINT 는 다음과 같이 기술할 수 있다.
COLUMN-CONSTRAINT : column명 [CONSTRAINT constraint명] constraint종류
TABLE-CONSTRAINT : [CONSTRAINT constraint명] constraint종류
(column명, column명..)

Table 생성
CREATE TABLE table명
(column명 type(size) [DEFAULT VALUE] [column constraint],
column명 type(size) [DEFAULT VALUE] [column constraint],
.... ,
[table constraint] ,
[table constraint] ,
.... ) ;
[ 예제 ]
S_EMP TABLE CHART를 보고 TABLE 을 생성하시오.
단, TABLE CONSTRAINT 로 기술할 수 있는 것은 TABLE CONSTRAINT 로 정의하시오.
CREATE TABLE S_EMP
(ID NUMBER(7),
LAST_NAME VARCHAR2(25) CONSTRAINT S_EMP_LAST_NAME_NN NOT NULL,
FIRST_NAME VARCHAR2(25),
USERID VARCHAR2(8) CONSTRAINT S_EMP_USERID_NN NOT NULL,
START_DATE DATE DEFAULT SYSDATE,
COMMENTS VARCHAR2(25),
MANAGER_ID NUMBER(7),
TITLE VARCHAR2(25),
DEPT_ID NUMBER(7),
SALARY NUMBER(11,2),
COMMISSION_PCT NUMBER(4,2),
CONSTRAINT S_EMP_ID_PK PRIMARY KEY(ID),
CONSTRAINT S_EMP_USERID_UK UNIQUE,
CONSTRAINT S_EMP_DEPT_ID_FK FOREIGN KEY(DEPT_ID)
REFERENCES S_DEPT(ID),
CONSTRAINT S_EMP_COMMISSION_PCT CHECK
(COMMISSION_PCT IN (10, 12.5, 15, 17.5, 20))) ;

제 7 장. Data DICTIONARY
DICTIONARY
• DATABASE 가 만들어 졌을때 DICTIONARY TABLE 도 만들어 진다.
• DATABASE 가 사용중일때 DICTIONARY TABLE 은 ORACLE7 SERVER 에 의해 UPDATE 된다.
• 사용자들은 DICTIONARY TABLE 을 SELECT 할 수 있다.
• DICTIONARY TABLE 은 SYS USER 의 소유다.
• DICTIONARY TABLE 의 값은 대문자로 들어있다.
• DICTIONARY TABLE 의 종류는 다음과 같은 방법으로 알 수 있다.
SELECT   *
FROM    DICTIONARY ;
DICTIONARY TABLE 의 종류는 다음과 같다.
• USER : USER 가 소유하고 있는 OBJECT 의 정보를 보여준다.
• ALL : USER 가 ACCESS 할 수 있는 OBJECT 의 정보를 보여준다.
• DBA : DBA USER 가 ACCESS 할 수 있는 OBJECT 의 정보를 보여준다.

활용예
DICTIONARY TABLE 의 검색예는 다음과 같다.
■ 자신이 갖고 있는 TABLE 의 이름을 검색한다.
SELECT   OBJECT_NAME
FROM    USER_OBJECTS
WHERE   OBJECT_TYPE = 'TABLE';
■ 자신이 갖고 있는 OBJECT 의 종류를 검색한다.
SELECT   DISTINCT OBJECT_TYPE
FROM   USER_OBJECTS;
■ GRANT 와 관련된 DICTIONARY TABLE 의 이름을 검색한다.
SELECT   TABLE_NAME
FROM   DICTIONARY
WHERE   UPPER(COMMENTS) LIKE '%GRANT%';
■ S_EMP TABLE 의 CONSTRAINT 종류를 검색한다.
SELECT   CONSTRAINT_NAME, CONSTRAINT_TYPE, SEARCH_CONDITION,
R_CONSTRAINT_NAME
FROM   USER_CONSTRAINTS
WHERE   TABLE_NAME = 'S_EMP';
■ S_EMP TABLE 의 COLUMN CONSTRAINT 를 검색한다.
SELECT   CONSTRAINT_NAME, COLUMN_NAME
FROM   USER_CONS_COLUMNS
WHERE   TABLE_NAME = 'S_EMP';

제 8 장. Data 조작
데이타 입력
TABLE 전체 COLUMN 에 값을 입력한다.
INSERT INTO table명
VALUES (value, value...);
[ 예제 ]
S_EMP TABLE 에 다음과 같은 데이타를 입력하시오.
ID : 26, LAST_NAME : Jung Mi, FIRST_NAME : Hong, USERID : Hjungmi,
START_DATE : 05-APR-97, COMMENTS : Teacher, MANAGER_ID : 10,
TITLE : Stock Clerk, DEPT_ID : 45, SALARY : 1200 COMMISSION_PCT : 10
INSERT INTO S_EMP
VALUES (26, 'Jung Mi', 'Hong', 'Hjungmi', '05-APR-97',
'Teacher', 10, 'Stock Clerk', 45, 1200, 10) ;
(값을 지정하는 순서는 TABLE 의 COLUMN 순서에 맞춰서 지정한다.
이 방법보다는 COLUMN명을 기술하여 입력하는 방법이 더 좋다.)

특정 column에 데이타입력
데이타를 입력하고자 하는 COLUMN을 선택하여 입력한다.
INSERT INTO table명(column명, column명....)
VALUES (value, value....);
[ 예제 ]
S_EMP TABLE 에 다음과 같은 데이타를 입력하시오.
ID : 27, LAST_NAME : Smith, FIRST_NAME : Donna, START_DATE : 05-APR-97
INSERT INTO S_EMP(ID, LAST_NAME, FIRST_NAME, START_DATE)
VALUES (27, 'Smith', 'Donna', '05-APR-97') ;

Null, 특수 value 입력
COLUMN 값에 NULL 값을 지정하는 방법은 3 가지가 있다.
• INSERT 문장의 COLUMN LIST 에서 생략한다.
• INSERT 문장의 VALUE 절에서 NULL 로 지정한다.
• INSERT 문장의 VALUE 절에서 '' 로 지정한다.
COLUMN 값에 특수한 값을 입력할 수 있다.
SYSDATE : 현재날짜와 시간
USER : 현재 USERID
[ 예제 ]
S_EMP TABLE 에 다음과 같은 데이타를 입력하시오.
ID : 29, LAST_NAME : Donna, USERID : USER, SALARY : NULL, START_DATE : SYSDATE
INSERT INTO S_EMP(ID, LAST_NAME, USERID, SALARY, START_DATE)
VALUES (29, 'Donna', USER, NULL, SYSDATE);

특수형태의 날짜/시간입력
DATE 값을 입력할 때는 지정된 DATE 형태로 입력하여야 한다.
일반적으로 DD-MON-YY 형태를 사용하며, 이 형태로 데이타를 입력하면 세기는 현재의 세기로, 시간은 자정으로 입력된다.
다른 세기의 날짜나 시간을 입력하고 싶으면 TO_DATE FUNCTION 을 사용한다.
지정된 형태가 아닌 다른 형태의 날짜 값을 입력한다.
TO_DATE('날짜값','날짜형태')
[ 예제 ]
S_EMP TABLE 에 다음과 같은 데이타를 입력하시오.
ID : 30, LAST_NAME : Donna, USERID : SQL01, START_DATE : 199704051400
INSERT INTO S_EMP(ID, LAST_NAME, USERID, START_DATE)
VALUES (30, 'Donna', 'SQL01', TO_DATE('199704051400','YYYYMMDDHH24MI'));

다른table로부터 데이타입력
INSERT 문장을 사용하여 기존하는 TABLE 의 데이타를 다른 TABLE 로 COPY 할 수 있다.
INSERT INTO table명[(column명, column명...)]
SUBQUERY;
[ 예제 ]
S_EMP TABLE 의 ROW들을 HISTORY TABLE 로 COPY 하시오.
단, 01-JAN-94 이전에 입사한 사원의 ID,LAST_NAME,SALARY,START_DATE 를 COPY 하시오
INSERT INTO HISTORY(ID, LAST_NAME, SALARY, START_DATE)
SELECT ID, LAST_NAME, SALARY, START_DATE
FROM S_EMP
WHERE START_DATE < '01-JAN-94' ;
(INSERT 절의 COLUMN 수와 SELECT 절의 COLUMN 수는 같아야 한다.)

데이타 수정
UPDATE 문장을 사용하여 이미 존재하는 COLUMN 값을 수정한다.
UPDATE table명
SET column명 = value, [column명 = value]
[WHERE 조건식] ;
[ 예제 ]
S_EMP TABLE 에서 ID 가 1 인 사원의 데이타를 다음과 같이 수정하시오.
DEPT_ID : 32, SALARY : 2550
UPDATE S_EMP
SET DEPT_ID = 32, SALARY = 2550
WHERE ID = 2 ;

데이타 삭제
DELETE 문장을 사용하여 데이타를 삭제한다.
DELETE FROM table명
[WHERE 조건식] ;
[ 예제 ]
S_EMP TABLE에서 ID 가 20 보다 큰 사원을 삭제하시오.
DELETE FROM S_EMP
WHERE ID > 20 ;

저장
COMMIT 문장(COMMIT;)에 의해 변경된 모든 내용이 DATABASE 에 저장된다.
변경된 모든 데이타는 DATABASE 에 저장된다.
그 전의 데이타는 완전히 없어진다.
모든 사용자가 변경한 내용을 볼 수 있다.
변경된 ROW 에 걸려있던 LOCK 이 해제된다.
그러므로 다른 사용자가 수정할 수 있다.
모든 SAVEPOINT 가 없어진다.
TRANSACTION 을 종료하고 TRANSACTION 안의 모든 변경된 작업을 저장한다.

취소
ROLLBACK 문장(ROLLBACK)을 사용하여 모든 변경된 내용을 취소한다.
모든 변경이 취소되며 수정하기 전의 데이타가 복구된다.
변경된 ROW 에 걸려있던 LOCK 이 해제된다.
다른 사용자들이 그 ROW 에 대해서 변경을 할 수 있다.
TRANSACTION 을 종료하고 TRANSACTION 안의 모든 변경된 작업을 취소한다.

Savepoint지정~취소
TRANSACTION 안에서 ROLLBACK 할 수 있는 POINT 를 지정한다.
지정된 POINT 까지만 ROLLBACK 한다.
SAVEPOINT savepoint명 ;
ROLLBACK TO savepoint명 ;
[ 예제 ]
S_EMP TABLE 에서 TITLE 이 Stock Clerk 인 사원의 SALARY 를 10% 인상하시오.
SAVEPOINT 를 지정하시오.
S_REGION TABLE 에 다음과 같은 데이타를 입력하시오.
ID : 8, NAME : Central
SAVEPOINT 까지 ROLLBACK 하시오.
UPDATE 결과를 저장하시오.
UPDATE S_EMP
SET SALARY = SALARY * 1.1
WHERE TITLE = 'Stock Clerk' ;
SAVEPOINT S1;
INSERT INTO S_REGION(ID, NAME)
VALUES (8, 'Central') ;
ROLLBACK TO S1;
COMMIT;


제 9 장. Table변경/삭제
Column 추가
TABLE 에 새로운 COLUMN 을 추가한다.
ALTER TABLE table명
ADD (column명 type(size) [DEFAULT value] [column_constraint],
...........) ;
[ 예제 ]
S_REGION TABLE 에 다음과 같은 COLUMN 을 추가하시오.
COMMENTS VARCHAR2(25)
ALTER TABLE S_REGION
ADD (COMMENTS VARCHAR2(25))
(추가될 COLUMN 의 위치는 지정할 수 없다. 새로운 COLUMN 은 마지막 위치에 생성된다.)

Column 변경
ALTER TABLE 문장의 MODIFY 절을 사용하여 다음과 같은 변경을 할 수 있다.
COLUMN 의 크기를 확장할 수 있다.
데이타가 들어있지 않으면 COLUMN 의 크기를 줄일 수 있다.
데이타가 들어있지 않다면 COLUMN 의 타입을 수정할 수 있다.
COLUMN 에 NULL 값이 없다면 NOT NULL CONSTRAINT 를 지정할 수 있다.
DEFAULT VALUE 를 변경할 수 있다.
이미 생성되어 있는 COLUMN 을 변경한다.
ALTER TABLE table명
MODIFY (column명 type(size) [DEFAULT value] [NOT NULL],
.............) ;

Constraint 추가
이미 생성되어 있는 TABLE 에 CONSTRAINT 를 추가한다.
ALTER TABLE table명
ADD (table_constraint) ;
[ 예제 ]
S_EMP TABLE 에 다음과 같은 CONSTRAINT 를 추가하시오.
MANAGER_ID COLUMN 이 S_EMP TABLE 의 ID COLUMN 을 REFERENCE 하는
FOREIGN KEY CONSTRAINT 를 추가하시오.
ALTER TABLE S_EMP
ADD (CONSTRAINT S_EMP_MANAGER_ID_FK FOREIGN KEY(MANAGER_ID)
REFERENCES S_EMP(ID)) ;

Constraint 삭제
이미 생성되어 있는 TABLE 의 CONSTRAINT 를 삭제한다.
ALTER TABLE table명
DROP PRIMARY KEY |
UNIQUE(column명) |
CONSTRAINT constraint명 [CASCADE] ;
[ 예제 ]
S_EMP TABLE 의 다음과 같은 CONSTRAINT 를 삭제하시오.
MANAGER_ID COLUMN 의 FOREIGN KEY CONSTRAINT
ALTER TABLE S_EMP
DROP CONSTRAINT S_EMP_MANAGER_ID_FK ;

전체 데이타의 삭제
TRUNCATE 문장은 DDL 이다.
ROLLBACK SEGMENT 를 만들지 않고 모든 데이타를 삭제한다.
데이타가 삭제된 FREE 영역은 환원된다.
TABLE 로부터 모든 데이타를 삭제한다.
TRUNCATE TABLE table명 ;
[ 예제 ]
S_ITEM TABLE 의 모든 데이타를 삭제하시오.
TRUNCATE TABLE S_ITEM ;

Constraint disable/enable
TABLE 에 있는 모든 데이타가 CONSTRAINT 를 만족시켜야 ENABLE 할 수 있다.
PRIMARY KEY, UNIQUE CONSTRAINT 를 ENABLE 하면 그에 따른 INDEX FILE 이 자동적으로 생성된다.
CASCADE OPTION 은 FOREIGN KEY CONSTRAINT 를 DISABLE 할 때 사용한다.
CONSTRAINT 를 삭제하고 새로 만들지 않고 DISABLE, ENABLE 한다.
ALTER TABLE table명
DISABLE | ENABLE PRIMARY KEY |
UNIQUE(column명) |
CONSTRAINT constraint명 [CASCADE] ;
[ 예제 ]
S_DEPT TABLE 의 PRIMARY KEY CONSTRAINT 를 DISABLE 시키시오.
ALTER TABLE S_DEPT
DISABLE CONSTRAINT S_DEPT_ID_PK CASCADE;
S_EMP TABLE 의 S_EMP_DEPT_ID_FK CONSTRAINT 도 자동적으로 DISABLE 된다.

Table 삭제
TABLE 을 삭제하면 그 TABLE 에 딸린 INDEX FILE 도 삭제된다.
VIEW, SYNONYM, STORED PROCEDURE, FUNCTION, TRIGGER 등은 삭제되지 않는다.
CASCADE CONSTRAINTS 는 모 TABLE 을 삭제하고 자 TABLE 의 FOREIGN KEY CONSTRAINT 도 삭제한다.
DROP TABLE table명 [CASCADE CONSTRAINTS] ;
[ 예제 ]
S_DEPT TABLE 을 삭제하시오.
DROP TABLE S_DEPT CASCADE CONSTRAINTS ;

이름의 변경
TABLE, VIEW, SEQUENCE, SYNONYM 의 이름을 변경한다.
RENAME old명 TO new명 ;
[ 예제 ]
S_ORD TABLE 의 이름을 S_ORDER 로 변경하시오.
RENAME S_ORD TO S_ORDER ;

제 10 장. Sequence
Sequence 생성
SEQUENCE 는 여러 사용자에게 UNIQUE 한 값을 생성해 주는 OBJECT 이다.
SEQUENCE 를 사용하여 PRIMARY KEY 값을 자동적으로 생성한다.
CREATE SEQUENCE sequence명
INCREMENT BY n
START WITH n
MAXVALUE n | NOMAXVALUE
MINVALUE n | NOMINVALUE
CYCLE | NOCYCLE
CACHE n | NOCACHE ;
[ 예제 ]
S_DEPT TABLE 의 ID COLUMN 값에 사용할 SEQUENCE 를 다음과 같이 생성하시오.
START : 51, INCREMENT : 1, MAXVALUE : 9999999, NOCYCLE, NOCACHE
CREATE SEQUENCE S_DEPT_ID
INCREMENY BY 1
START WITH 51
MAXVALUE 9999999
NOCACHE
NOCYCLE ;

Sequence 변경
SEQUENCE 에 정의된 값을 변경한다.
ALTER SEQUENCE sequence명
INCREMENT BY n
MAXVALUE n | NOMAXVALUE
MINVALUE n | NOMINVALUE
CYCLE | NOCYCLE
CACHE n | NOCACHE ;
[ 예제 ]
S_DEPT_ID SEQUENCE 를 다음과 같이 수정하시오.
CACHE : 10
ALTER SEQUENCE S_DEPT_ID
CACHE 10 ;

Sequence 삭제
SEQUENCE 를 삭제한다.
DROP SEQUENCE sequence명 ;
[ 예제 ]
S_DEPT_ID SEQUENCE 를 삭제하시오.
DROP SEQUENCE S_DEPT_ID ;

제 11 장. VIEW

Simple view
SUBQUERY 문장이 간단한 경우 VIEW 를 통해 SELECT,INSERT,UPDATE,DELETE 를 할 수 있다.
■ SELECT : SUBQUERY 의 조건식을 만족하는 데이타만 검색된다.
■ INSERT : NOT NULL COLUMN 을 다 포함하고 있는 경우 INSERT 를 할 수 있다.
SUBQUERY 의 조건식을 만족하지 않는 데이타도 입력이 가능하다.
■ UPDATE : VIEW 를 통해 SELECT 할 수 있는 데이타만 수정할 수 있다.
SUBQUERY 의 조건식을 만족하지 않는 데이타도 수정이 가능하다.
■ DELETE : VIEW 를 통해 SELECT 할 수 있는 데이타만 삭제할 수 있다.
CREATE VIEW view명 [(alias명, alias명....)]
AS SUBQUERY ;
[ 예제 ]
S_EMP TABLE 에서 DEPT_ID 가 45 인 사원의 ID, LAST_NAME, DEPT_ID, TITLE 을
선택해서 VIEW 를 생성하시오.
CREATE VIEW EMP41
AS SELECT ID, LAST_NAME, DEPT_ID, TITLE
FROM S_EMP
WHERE DEPT_ID = 45 ;

With check option
VIEW 를 정의할때 지정한 조건식을 만족하는 데이타만 INSERT, 또는 조건식을 만족하는 데이터로만 UPDATE 가 가능하다.
데이타가 VIEW 의 조건식을 만족하는지 CHECK 한다.
CREATE VIEW view명 [ (alias명, alias명...)]
AS SUBQUERY
WITH CHECK OPTION ;
[ 예제 ]
S_EMP TABLE 에서 DEPT_ID 가 45 인 사원의 ID, LAST_NAME, DEPT_ID, TITLE
을 선택해서 VIEW 를 생성하시오.
단, DEPT_ID 가 45 가 아닌 사원은 입력되지 못하게 만드시오.
CREATE VIEW EMP45
AS SELECT ID, LAST_NAME, DEPT_ID, TITLE
FROM S_EMP
WHERE DEPT_ID = 45
WITH CHECK OPTION ;

With read only
SELECT만 가능한 VIEW 를 생성한다.
CREATE VIEW view명 [(alias명, alias명...)]
AS SUBQUERY
WITH READ ONLY ;
[ 예제 ]
S_EMP TABLE 에서 ID, LAST_NAME, DEPT_ID, SALARY 가 SELECT 만 되도록 VIEW 를 생성
CREATE VIEW R_EMP
AS SELECT ID, LAST_NAME, SALARY
FROM S_EMP
WITH READ ONLY ;

Force
기준 TABLE 이 존재하지 않아도 VIEW 를 생성한다.
CREATE FORCE VIEW view명 [(alias명, alias명...)]
AS SUBQUERY ;
[ 예제 ]
S_EMP TABLE 이 없어도 S_EMP TABLE 에서 ID, LAST_NAME, SALARY 를 선택해서
VIEW 를 생성하시오.
CREATE FORCE VIEW T_EMP
AS SELECT ID, LAST_NAME, SALARY
FROM S_EMP ;

complex view
SUBQUERY 문장에 JOIN, FUNCTION, DISTINCT 또는 연산이 포함된 경우를 말하며 이 경우 VIEW 를 통한 DML 은 수행할 수 없다.
COMPLEX VIEW 를 생성한다.
CREATE VIEW view명 (alias명, alias명...)
AS SUBQUERY ;
[ 예제 ]
S_EMP TABLE 과 S_DEPT TABLE 에서 ID, LAST_NAME, DEPT_ID, NAME 을
선택해서 VIEW 를 생성하시오.
CREATE VIEW EMPDEPT
AS SELECT E.ID, E.LAST_NAME, E.DEPT_ID, D.NAME
FROM S_EMP E, S_DEPT D
WHERE E.DEPT_ID = D.ID ;

View 삭제
VIEW 를 삭제하면 DATABASE 로부터 VIEW 의 정의가 삭제된다.
VIEW 가 기초로 한 TABLE 은 삭제되지 않는다.
DROP VIEW view명 ;
[ 예제 ]
EMPDEPT VIEW 를 삭제하시오.
DROP VIEW EMPDEPT ;

제 12 장. Index

Index 생성
TABLE 생성시 PRIMARY KEY 나 UNIQUE CONSTRAINT 를 지정하면 UNIQUE INDEX 가 자동적으로 만들어 진다.
이 외의 COLUMN 으로 QUERY 를 할 때 속도를 향상시키기 위해서 INDEX 를 생성한다.
INDEX 를 생성하면 QUERY 속도는 빨라질 수 있으나 DML 속도는 늦어질 수 있다.
일반적으로 다음과 같은 경우에 INDEX 를 생성한다.
■ COLUMN 이 WHERE 절이나 JOIN 조건식에 빈번하게 사용될 때
■ COLUMN 값이 넓게 분포되어 있을 때
■ COLUMN 값에 NULL 값이 많이 포함되어 있을 때
■ TABLE 이 크고 QUERY 하는 데이터 양이 10 % 이하일 때
CREATE [UNIQUE] INDEX index명
ON table명(column명[, column명...]) ;
[ 예제 ]
S_EMP TABLE 에서 LAST_NAME 의 QUERY 속도를 향상하기 위하여 INDEX 를 생성하시오.
CREATE INDEX S_EMP_LAST_NAME_IDX
ON S_EMP(LAST_NAME) ;

Index 삭제
INDEX 는 수정할 수 없다. 수정하고 싶은 경우 삭제하고 다시 생성한다.
DROP INDEX index명 ;
[ 예제 ]
S_EMP_LAST_NAME_IDX INDEX 를 삭제하시오.
DROP INDEX S_EMP_LAST_NAME_IDX ;

이 글은 스프링노트에서 작성되었습니다.

'오라클' 카테고리의 다른 글

SYS_CONNECT_BY_PATH  (0) 2012.07.26
오라클 구조 보기 sql 문 (desc)  (0) 2012.06.07
오라클연습  (0) 2012.05.08
sqlplus에서 셀렉트 update문 가져 오기.  (0) 2012.05.08
오라클(ORACLE)  (0) 2012.05.08
Posted by 사라링

BLOG main image
.. by 사라링

카테고리

사라링님의 노트 (303)
JSP (32)
J-Query (41)
디자인패턴 (1)
JAVA (24)
스트러츠 (3)
안드로이드 (11)
오라클 (45)
우분투-오라클 (1)
이클립스메뉴얼 (6)
스프링3.0 (23)
자바스크립트 (11)
HTML5.0 (17)
정보처리기사 (1)
기타(컴퓨터 관련) (1)
문제점 해결 (3)
프로젝트 (2)
AJAX (4)
하이버네이트 (3)
트러스트폼 (11)
Jeus (2)
재무관리(회계) (5)
정규식 (5)
아이바티스 (8)
취미 (2)
소프트웨어 보안 관련모음 (0)
정보보안기사 (6)
C언어 베이직 및 프로그램 (3)
보안 관련 용어 정리 (2)
넥사크로 (6)
웹스퀘어_ (0)
Total :
Today : Yesterday :