Spring4 & MyBatis

[부스트코스] 웹 프로그래밍 기반의 설정에서 추가 설정으로 확장하기 위한 포스팅

  • 목표

    • spring4 pom.xml 설정
    • mybatis dependency 추가
    • mybatis java config
    • domain, mapper, sql 샘플 작성
    • mapper 테스트
  • Spring4의 Java Config 향상 기능을 통해 Mybatis를 구성하는 xml 제외하기

  • mybatis-spring 라이브러리에서 제공하는 @MapperScan 어노테이션을 사용하여 MyBatis Domain Mapper에 대해 패키지단위로 검색이 가능하다.

  • Servlet 3+와 결합하는 경우 XML없이 응용 프로그램을 구성하고 실행할 수 있다.

프로젝트 스펙 및 설정 구조

모듈 버전 설명
Spring Framework 4.3.15.RELEASE
MyBatis 3.5.2
mybatis-spring 2.0.2
- src/main
    - java/com/seok/mybatis/
                    config/
                        * AppConfig.java
                        * DBConfig.java
                        * MybatisConfig.java
                    domain/
                        * Product.java
                    persistence/
                        * ProductMapper.java
    - resources/mapper/
            * ProductMapper.xml
* pom.xml

프로젝트 구조

설정

  • pom.xml

    • MyBatis 사용을 위한 mybatis, mybatis-spring dependency를 추가 한다.

    • 물론 DB를 사용하기 위한 프로젝트이기 때문에 spring-jdbc, mysql-connector-java도 추가

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.45</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.2</version>
    </dependency>
  • AppConfig.java
    • 스프링 설정 클래스
    • DBConfig와 MyBatisConfig를 분리해서 Import하였다.
    • 같은 클래스안에서 설정해도 무관

@Configuration
@Import({DBConfig.class, MybatisConfig.class})
public class AppConfig {
}
  • DBConfig.java
    • DB 설정관련 클래스
    • java 파일 내에 설정 정보를 넣지 않고 properties 파일을 사용하여 보안 및 배포 관리

@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:db.properties" })
public class DBConfig implements TransactionManagementConfigurer {

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String userName;

    @Value("${spring.datasource.password}")
    private String password;

    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        return dataSource;
    }
}
  • MybatisConfig.java

    1. line 2: MyBatis Mapper가 있는 패키지 설정
    2. line 9: MyBatis.xml 파일에서 resultType으로 사용할 수 있는 도메인 개체를 포함하는 패키지 설정
      (SQL쿼리에서 Java 객체를 반환하는 것은 ORM 문제를 해결)
    • MyBatis를 설정하기 위해 SqlSessionFactoryBean를 사용

@Configuration
@MapperScan("com.seok.mybatis.persistence")
public class MybatisConfig {

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage("com.seok.mybatis.domain");
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return sessionFactory;
    }
}

  • Product.java
    • Product 도메인 객체는 실제 단순한 POJO

public class Product implements Serializable{

    private static final long serialVersionUID = 3690807750019415954L;

    private int id;
    private int categoryId;
    private String desc;
    private String content;
    private String event;
    // constructor, setter, getter

}
  • ProductMapper.java
    • Mapper 클래스는 해당 mapper.xml에 정의된 sql문과 일치하는 메서드를 정의하는 단순한 인터페이스이다.
    • xml로 SQL을 정의하는 대신 어노테이션으로 간단한 SQL문을 작성하는 것이 가능하지만, query가 번거로워져 복잡한 Query는 사용하지 않는다.

import org.apache.ibatis.annotations.Select;
import kr.or.seok.naver.domain.Product;

public interface ProductMapper {

    public List<Product> getAllProducts();

    // Simple SQL
    @Select("SELECT COUNT(*) totalCnt FROM product")
    public int getTotalCnt();

}

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.seok.mybatis.persistence.ProductMapper">
    <cache />

    <select id="getAllProducts" resultType="Product">
        SELECT 
            id, 
            category_id, 
            description, 
            content, 
            event 
        FROM product
    </select>

</mapper>

테스트

  • TestMyBatis.java
    • Test 코드는 Mockito나 Junit을 사용하는 것이 편리

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class TestMyBatis {

    @Autowired
    ProductMapper prodMapper;

    @Test
    public void testMapper() {
        // prodMapper.getAllProducts();

    }

    @Test
    public void testTotalProducts() {
        // productMapper.getTotalCnt();
    }
}

결과

  • TotalCnt()
    • Product의 전체 row 갯수를 확인하기 위한 메서드로 50개가 조회되고 있음을 알 수 있다.

23:53:03.208 [main] DEBUG com.seok.mybatis.persistence.ProductMapper.getTotalCnt - ==>  Preparing: SELECT COUNT(*) totalCnt FROM product 
23:53:03.251 [main] DEBUG com.seok.mybatis.persistence.ProductMapper.getTotalCnt - ==> Parameters: 
23:53:03.276 [main] DEBUG com.seok.mybatis.persistence.ProductMapper.getTotalCnt - <==      Total: 1
23:53:03.282 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3daf7722]
23:53:03.282 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
23:53:03.336 [main] INFO com.seok.mybatis.config.TestMyBatis - 50
  • getAllProducts()
    • Product의 모든 row를 조회하기 위한 테스트 메서드로 50개의 Product리스트가 조회되고 있음을 확인할 수 있다.

23:53:03.348 [main] DEBUG com.seok.mybatis.persistence.ProductMapper.getAllProducts - ==>  Preparing: SELECT id, category_id, description, content, event FROM product 
23:53:03.348 [main] DEBUG com.seok.mybatis.persistence.ProductMapper.getAllProducts - ==> Parameters: 
23:53:03.372 [main] DEBUG com.seok.mybatis.persistence.ProductMapper.getAllProducts - <==      Total: 50
23:53:03.379 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@52066604]
23:53:03.379 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
23:53:03.419 [main] INFO com.seok.mybatis.config.TestMyBatis - [ {
    "id" : 1,
    "categoryId" : 0,
    "desc" : null,
    "content" : "",
    "event" : ""
    },
    ...
}] 

[Python] Job Scrapper

 * 노마드코더 Python으로 웹 스크래퍼 만들기 강의를 통해 학습하실 수 있습니다.

 

필요한 모듈
모듈명 사이트 설명
requests https://requests.readthedocs.io/en/master/ Python을 위한 간단한 HTTP 라이브러리
BeautifulSoup https://www.crummy.com/software/BeautifulSoup/bs4/doc/ HTML 및 XML 파일에서 데이터를 꺼내기 위한 Python 라이브러리
csv
https://docs.python.org/3.8/library/csv.html  

 

개발 순서
 1. requests를 이용한 URL 호출 (indeed, statck_of_flow)
 2. 검색 키워드, 페이지 파라미터 찾기
 3. URL 호출로 HTML 전문 가져오기
 4. BeautifulSoup을 이용하여 필요한 데이터의 태그 검색하기
 5. 데이터 리스트 만들기
 6. CSV로 내려 받기

 

1 ~ 2. Request
LIMIT = 50
INDEED_URL = f"https://kr.indeed.com/jobs?limit={LIMIT}"
get_request = requests.get(f"{INDEED_URL}&q={keyword}")

 

3. HTML 전문 가져오기
html_parse = bs(get_request.text, 'html.parser')

 

4 ~ 5. 필요한 데이터 태그 검색하기

 - 페이지

 

 

 - job 관련 데이터

 

 

6. CSV 파일로 내려 받기

 

 

Flask를 이용한 Job List Data Crawling

 * 간단한 데이터는 Flask를 이용해 CSV파일로 만들고, 보다 큰 데이터는 Django를 이용해 프로젝트 작성 할 것

'Edu > Nomad Coders' 카테고리의 다른 글

[AWS - Django] 배포하기  (0) 2020.04.09
[Airbnb] 정리  (0) 2020.03.14

[BoostCourse] Swagger API Document 적용

 - 스프링에 Swagger 적용하는 방법 익히기

Pom.xml spac (Source)

 - spring.version = 4.3.15.RELEASE (5.x.x 버전의 경우 모든 메서드를 구현하지 않아도 됨)

 - jackson.version = 2.9.8

 - swagger.version = 2.9.2

groupId module

version

scope

javax.servlet javax.servlet-api 3.1.0 provided
javax.servlet.jsp javax.servlet.jsp-api 2.3.2-b02 provided
javax.servlet jstl 1.2  
org.springframework spring-webmvc ${spring.version}  
org.springframework spring-test ${spring.version}  
com.fasterxml.jackson.core jackson-core ${jackson.version}  
com.fasterxml.jackson.core jackson-databind ${jackson.version}  
junit junit 4.12 test
io.springfox springfox-swagger2 ${swagger.version}  
io.springfox springfox-swagger-ui ${swagger.version}  

 

config 설정 파일 리스트 (Source)

 1. WebAppInitializer

클래스명 상속 설명
WebAppInitializer AbstractAnnotationConfigDispatcherServletInitializer  
구현 메서드  - getRootConfigClasses()  - Spring 기본 설정파일 클래스를 지정
 - ApplicationConfig.class
 - getServletConfigClasses()  - Spring MVC 설정 파일 클래스를 지정
 - MvcConfig.class, SwaggerConfig.class
 - getServletMappings()  - DispatcherServlet이 동작할 맵핑정보를 설정
 - "/"를 설정한다는 것은 모든 요청을 DispatcherServlet이 처리
 - getServletFilters()  - 인코딩 필터를 설정

 

 2. ApplicationConfig

클래스명 상속 설명
ApplicationConfig @Configuration
@ComponentScan(basePackages = {"service"})
 - Spring MVC에서 사용할 Bean들을 설정하는 스프링 설정

 

 3. MvcConfig

클래스명 상속 설명
MvcConfig @Configuration
@EnableWebMvc
WebMvcConfigurer
@ComponentScan(basePackages = { "controller" })
 
구현 메서드  - configureDefaultServletHandling()  - DefaultServlet에 대한 설정
 - DispatcherServlet이 처리하지 못하는 URL은 DefaultServlet이 처리
 - 해당 설정이 없으면 자동 생성된 Swaager 페이지를 볼 수 없다.

 

4. Swagger

클래스명 상속 설명
Swagger @Configuration
@EnableSwagger2
 
구현 메서드 @Bean
Docket api()
 - Swagger 사용 시에는 Docket Bean 을 품고있는 설정 클래스 1개가 기본으로 필요
 - Spring Boot 에서는 기본적인 설정파일 1개로 Swagger 와 Swagger UI를 함께 사용가능하지만 Spring MVC 의 경우 Swagger UI를 위한 별도의 설정이 필요
 - Swagger UI 를 ResourceHandler 에 수동으로 등록해야 하는 작업인데, SpringBoot 에서는 이를 자동으로 설정해주지만 Spring MVC 에서는 그렇지 않기 때문이다.

 

Controller, Service, Dto

 - Controller (Source)

클래스명 Swagger Annotation
CalculatorApiController  
CalculatorResult plus(value1, value2) @ApiOperation(value = "덧셈 구하기") 
@ApiResponses({  
            @ApiResponse(code = 200, message = "OK"), 
            @ApiResponse(code = 500, message = "Exception") 
})
CalculatorResult minus(value1, value2)
@ApiOperation(value = "뺄셈 구하기")
@ApiResponses({  // Response Message에 대한 Swagger 설명
            @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 500, message = "Exception")
})

 

Swagger Page

 - 설정 후 http://localhost:8088/swagger-ui.html로 접근 시 Swagger UI로 확인 가능

 

 * AWS 공식 홈페이지 기반으로 작성하는 Django 배포하기

EB CLI 설치
1. pipenv 환경에 AWS EB CLI 설치 (Link)
 - EB 명령어 (Link)
 - EB 오류관련 (Link)

 * pipenv install awsebcli --dev
 * pathspec 버전 오류가 발생 할 수 있으나 그냥 진행
AWS Elastic Beanstalk Django 배포
1. AWS Elastic Beanstalk 개념 (Link}
2. Elastic Beanstalk 사용 시작하기 (Link)
3. Elastic Beanstalk 파이썬 플랫폼 사용하기 (Link)
4. Django 어플리케이션을 Elastic Beanstalk에 배포하기 (Link)
 - Elastic Beanstalk에 대한 Django 애플리케이션 구성
 * pip freeze > requirements.txt
  > 애플리케이션의 모듈을 로드할 수 있도록 환경 변수를 설정
 * .ebextensions/django.config
  > 어플리케이션 실행 Elastic Beanstalk가 애플리케이션을 시작하는 데 사용하는 WSGI 스크립트의 위치를 지정

 - IAM User 생성
 # access_id, access_secret

 - EB CLI를 사용하여 사이트 배포
 * eb init (Link)
  > 프로젝트 디렉터리 및 EB CLI를 구성할 준비
 * eb create app_name
  > eb create로 해당 환경에 애플리케이션을 배포
 * eb deploy
  > EB CLI가 프로젝트 디렉터리의 콘텐츠를 번들링한 후 이를 환경에 배포

5. Elastic Beanstalk에 첫 Django 애플리케이션을 배포

 

'Edu > Nomad Coders' 카테고리의 다른 글

[Python] Data Crawling  (0) 2020.04.19
[Airbnb] 정리  (0) 2020.03.14
이 글은 노마드코더[풀스택] 에어비엔비 클론 코딩 학습한 뒤 정리중인 내용입니다.
 * 이 글은 강의 핵심 내용외에 참고하기 위한 일부분입니다. 

 

Contents
1. Airbnb ERD
2. Django Project Structure
3. Login Process
4. Host Process
5. Guest Process
6. Reservation Process
7. URL Management
8. AWS Architecture

 

Airbnb ERD
# Airbnb_ERD

 

Django Project Structure
 - URL Mapping
URL Mapping
Login Process

 1. Email Login

 

 2. Github Login

 

 3. Kakao Login

OAuth - Kakao

 

Host Process

 

Guest Process

 

Reservation Process

 

AWS Architecture

 1. EB CLI 설치

 2. EB 구성하기

 3. eb init

 4. Django framework에 Elastic BeanStalk 설정

 5. EB에 Django 설치

 6. Postgresql 설정

 7. Sentry 설치

 8. statics files 업로드를 위한 S3 설정

Graduating From [풀스택] 에어비앤비 클론 코딩

'Edu > Nomad Coders' 카테고리의 다른 글

[Python] Data Crawling  (0) 2020.04.19
[AWS - Django] 배포하기  (0) 2020.04.09
Dynamic Web Project 3.1 spec

 - Servlet 클래스 작성 시 web.xml 변화 확인 3.x spec부터는 annotation으로 설정

 - 프로젝트 생성

 - 다음 페이지

 - 다음 페이지 web.xml 생성

 - 프로젝트 구조 확인

 - web.xml 확인

 - Servlet 클래스 작성

 - URL Mapping 수정

 - 메서드 생성

 - 생성된 서블릿 확인 @WebServlet("URL")이 생기는 점이 2.5 spec과 3.x spec의 차이점
(web.xml에 Servlet 등록 태그로 설정하지 않고 annotation으로 설정)

 - Servlet 생성 후 web.xml 확인 ( 변화없음 )

 

Dynamic Web Project 2.5 spec

 - 해당 페이지 내용은 2.5 spec과 3.0이상 web.xml 변화 차이를 확인하기 위하여 작성하였습니다.

 - Dynamic Web Project 프로젝트 만들기

 - 다음 화면


 - 다음 화면 (Generate web.xml... 체크)

 - 생성된 프로젝트 및 web.xml 확인
폴더 구조

web.xml 생성 확인

 - Servlet 클래스 작성

 - URL Mapping 수정 ("/MainServlet")

 - 

 - servlet 클래스 작성으로 자동으로 수정되는 web.xml 확인

[상권 정보 분석]

목표
 - 파이썬을 통한 데이터 핸들링
 - 주어진 데이터의 분석, 시각화를 통한 인사이트 
 - 데이터 분석을 위한 라이브러리 (Pandas, seaborn)를 이해하고 활용
 - 해당 데이터가 어떤 데이터 분석 유형에 해당하는지 파악

 

목적
 - 서울시 종합병원 데이터 분석

 

데이터 분석 방식
 - 데이터 확인
 - 전처리 ( 불필요한 데이터 삭제, 결측치 컬럼 삭제유무 판단 )
 - 데이터 색인
 - 데이터 시각화 ( seaborn, scatter, folium )

 

데이터 분석의 유형
 1. Descriptive analysis
 - 주어진 데이터를 요약/집계하여 결과를 도출
 2. Exploratory analysis
 - 여러 변수 간 트랜드나 패턴, 관계를 찾는 것
 3. Inferential analysis
 - 모집단 간의 관계를 탐구하는 것
 4. Predictive analysis
 - 머신러닝, 의사결정나무 등 다양한 통계적 기법을 사용하여 미래 혹은 발생하지 않은 어떤 사건에 대한 예측을 하는 것
 5. Causal analysis
 - 독립 변수와 종속 변수 간의 인과관계가 있는지 여부를 확인하기 위한 분석
 6. Mechanistic analysis
 - 독립 변수가 어떤 매커니즘으로 종속 변수에 영향을 미치는지를 분석

 

'Edu > BoostCourse - Data Science' 카테고리의 다른 글

[Python] 데이터 사이언스  (0) 2020.03.01

+ Recent posts