Mybatis, Transactional

Slides:



Advertisements
Similar presentations
일정 관리 다이어리 제작 JSP Programming with a Workbook. 학습 목표  사용자의 일정을 관리할 수 있는 다이어리에 대하여 알아보자. JSP Programming with a Workbook2.
Advertisements

2008 년 11 월 20 일 실습.  실험제목 ◦ 데이터베이스 커넥션 풀  목표 ◦ 데이터베이스 커넥션 풀의 사용.
컴퓨터와 인터넷.
Oozie Web API 기능 테스트 이승엽.
PARK SUNGJIN Oracle 설치 PARK SUNGJIN
DB 프로그래밍 학기.
DB 프로그래밍 학기.
1. 신뢰할 수 있는 싸이트 등록 인터넷 익스플로러 실행 후 실행
Power Java 제3장 이클립스 사용하기.
MS-Access의 개요 1강 MOS Access 2003 CORE 학습내용 액세스 응용 프로그램은 유용한 데이터를
4강. Servlet 맛보기 Servlet 문서 작성 하기 web.xml에 서블릿 맵핑 어노테이션을 이용한 서블릿 맵핑
최윤정 Java 프로그래밍 클래스 상속 최윤정
주)INVENTORNICS 노창배 소프트웨어 김 경 순
제 08 장 자바 빈즈 학기 인터넷비즈니스과 강 환수 교수.
연결리스트(linked list).
JSP Programming with a Workbook
Sep Youn-Hee Han 웹서비스 컴퓨팅 수업을 위한 코딩 환경 준비 Sep Youn-Hee Han
Spring 4 기반의 RESTful Web Service 구현
제 09 장 데이터베이스와 MySQL 학기 인터넷비즈니스과 강 환수 교수.
13장. 자바빈과 데이터베이스를 연동한 게시판 시스템
6장 Mysql 명령어 한빛미디어(주).
MVC 기반 게시판 작성 Youbok Choi.
MySQL 및 Workbench 설치 데이터 베이스.
IOC, DI 2015 Web Service Computing.
14장 질의응답 한빛미디어(주).
테이블 : 데이터베이스를 구성하는 요소로 같은 성격에 정보의 집합체. 레코드 : 하나의 정보를 가지고 있는 컬럼의 집합체
5장 Mysql 데이터베이스 한빛미디어(주).
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
ASP.NET : Database 접근 2008 컴퓨터공학실험(Ⅰ)
AOP (Aspect Oriented Programming)
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
6강. DI설정 방법 XML파일을 이용한 DI설정 방법 JAVA를 이용한 DI설정 방법 XML과 JAVA를 같이 사용
컴퓨터응용과학부 Java Enterprize(DB) 제 15 주
18강. 데이터 베이스 - II JDBC 살펴보기 Statement객체 살펴보기 Lecturer Kim Myoung-Ho
D / K / I / T / E / C / H / N / O / L / O / G / Y
17강. 데이터 베이스 - I 데이터 베이스의 개요 Oracle 설치 기본적인 SQL문 익히기
ASP.NET AJAX 비동기 게시판 작성 2007 컴퓨터공학실험( I )
KHS JDBC Programming 4 KHS
자료구조: CHAP 4 리스트 (3) 순천향대학교 컴퓨터공학과 하 상 호.
컴퓨터 프로그래밍 실습 #6 제 4 장 클래스 작성.
5장 Mysql 데이터베이스 한빛미디어(주).
10장. 예외처리.
속성과 리스너 초기화 파라미터 외 파라미터에 대해 이해한다. 리스너를 생성해보고 사용에 대해 이해한다.
You YoungSEok Oracle 설치 You YoungSEok
CHAP 12. 리소스와 보안.
ㅇ 스프링 설정파일 (dispatcher-servlet.xml)
10강. JSP 본격적으로 살펴보기-II 스크립트릿, 선언, 표현식 지시자 주석 Lecturer Kim Myoung-Ho
Method & library.
CHAP 13. 방명록 만들기 실습.
JDBC Lecture 004 By MINIO.
2015학년도 PHP 기말 레포트 로그인 홈페이지 제작.
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
Spring 프레임워크의 이해 3. Spring IoC 이해 및 활용.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
ADO.NET (SqlConnection, SqlCommand)
웹디자인
기말 프로젝트 계획 MVC 패턴 기반 웹 애플리케이션 개발 프로젝트명 : 팀명 : 팀원 :
15강. 폼 데이터 값 검증 Validator를 이용한 검증 ValidationUtils 클래스
CHAP 21. 전화, SMS, 주소록.
학습목표 처음 만드는 비주얼 베이직 프로그램 프로그램 실행과 실행 파일 생성. 학습목표 처음 만드는 비주얼 베이직 프로그램 프로그램 실행과 실행 파일 생성.
12강. 컨트롤러 컨트롤러 클래스 제작 요청 처리 메소드 제작 뷰에 데이터 전달
JSP Programming with a Workbook
세션에 대해 알아보고 HttpSession 에 대해 이해한다 세션 관리에 사용되는 요소들을 살펴본다
9 브라우저 객체 모델.
Android -Data Base 윤수진 GyeongSang Univ. IT 1.
Homework #3 - 페이지 모듈화 및 로그인처리 -
 6장. SQL 쿼리.
7 생성자 함수.
6 객체.
20 XMLHttpRequest.
Presentation transcript:

Mybatis, Transactional 2015 Web Service Computing

Mybatis iBatis Mybatis SQL에 기반한 데이터베이스와 자바, 닷넷(.NET), 루비(Ruby) 등을 연결시켜 주는 역할. JDBC를 대체하는 영속성 프레임워크(Persistence Framework)이다. 소스코드에서 SQL 문장을 분리하여 별도의 XML 파일로 저장하고 이 둘을 연결시켜주는 방식으로 작동한다 Mybatis 아파치 소프트웨어 재단의 iBatis개발자팀이 구글 코드로 이전하기로 결정하고 구글 코드에서 새로이 만들어지는 이름이 MyBatis로 변경 되었다. MyBatis는 개발자가 지정한 SQL, 저장프로시저, 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다. MyBatis는 JDBC 코드와 수동으로 셋팅하는 파라미터와 결과 매핑을 제거한다. MyBatis는 데이터베이스 레코드에 원시타입과 Map 인터페이스 그리고 자바 POJO를 설정하고 매핑하기 위해 XML과 애노테이션을 사용할 수 있다.

Mybatis pom.xml에 dependency 추가 <!– Spring jdbc --> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.2.0.RELEASE</version> </dependency> <!-- Apache Commons --> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> <!-- MySQL Connector --> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> <!-- MyBatis --> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version>

Mybatis /src/resources/common에 mybatis.xml 추가 spring 설정 파일에 다음과 같이 추가 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="mapUnderscoreToCamelCase" value="true" /> </settings> </configuration> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- MyBatis --> <mybatis:scan base-package="koreatech.cse.repository" /> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis.xml" />

Mybatis config.properties에 다음과 같이 추가(DataSource 정보) koreatech.cse.repository 패키지 생성 후 UserMapper.java 다음과 같이 생성 jdbc.driverClassName = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/wsc?characterEncoding=utf8&useUnicode=true&mysqlEncoding=utf8 jdbc.username = root jdbc.password = 비밀번호 package koreatech.cse.repository; import koreatech.cse.domain.User; import org.apache.ibatis.annotations.*; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; @Repository public interface UserMapper { @Insert("INSERT INTO USERS (NAME, EMAIL, PASSWORD, AGE) VALUES (#{name}, #{email}, #{password}, #{age})") @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", before=false, resultType = int.class) void insert(User user); @Update("UPDATE USERS SET NAME = #{name}, EMAIL = #{email}, PASSWORD = #{password}, AGE = #{age} WHERE ID = #{id}") void update(User user); @Select("SELECT * FROM USERS WHERE ID = #{id}") User findOne(@Param("id") int id); @Delete("DELETE FROM USERS WHERE ID = #{id}") void delete(@Param("id") int id); }

Mybatis @Insert Mysql insert문 @Update Mysql update문 @Select Mysql select문 @Delete Mysql delete문 @SelectKey statement: 방금 삽입한 id를 가져오기 위한 문구 keyProperty: ID 프로퍼티 resultType: 결과값 형태 @Param - 매퍼 메서드가 여러개의 파라미터를 가진다면, 이 어노테이션은 이름에 일치하는 매퍼 메서드 파라미터에 적용된다. - 반면에 여러개의 파라미터는 순서대로 명명된다. 예를 들어, #{param1}, #{param2} 등이 기본이다. - @Param(“person”) 를 사용하면, 파라미터는 #{person} 으로 명명된다.

Transaction Transaction이란? A가 B에게 금액을 이체하는 상황을 보자. 데이터베이스 내에서 한꺼번에 수행되어야할 일련의 연산들 DB와 JAVA 언어가 데이터를 주고 받는 과정에 원자성을 부여하는 수단 트랜잭션의 모든 연산들은 한꺼번에 모두 완료되거나 그렇지 않으면 모두 취소되어야 한다. A가 B에게 금액을 이체하는 상황을 보자. 1. A의 계좌에서 잔액을 –한다. 2. B의 계좌에 잔액을 +한다. 만약 1.과 2.의 사이에서 오류가 발생한다면?

Transaction Transaction기술은 하나의 커넥션에서 autoCommit을 해제하고 수동으로 제어하는 기술이다. 즉 이용자가 직접 쿼리 결과를 컨트롤할 수 있는 기술이다. Commit(커밋) : 해당 Connection의 요청을 완료하고 특별한 에러가 없다면 결과를 DB에 반영한다.  RollBack(롤백) : 해당 Connection 수행 중 예기치 않은 에러가 발생하였다면 모든 과정을 취소하고 DB를 Connection이 수행되기 이전상태로 변경한다. 스프링에서는 @Transactional이라는 어노테이션을 이용하여 간단하게 자동으로 적용할 수 있다.

Mybatis spring 설정 파일에 다음과 같이 추가 참고: proxy-target-class=“true”: Spring에서는 interface기반의 다이나믹 프록시를 지원하는데 interface를 사용하지 않고 구체 클래스에 직접 트랜잭션을 적용하려면 위와 같이 설정해준다. <tx:annotation-driven proxy-target-class="true" /> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>

Transaction @Transactional 어노테이션은 컨트롤러나 서비스, 메소드 레벨에 적용시킬 수 있다. 임의로 오류를 발생시키는 코드를 작성해보자. 아래 코드를 실행 후 데이터베이스에 값이 삽입되었는지 확인해보자. @Transactional @RequestMapping(value="/signup", method= RequestMethod.POST) @ResponseBody public String signup(@ModelAttribute User user, BindingResult result) { userMapper.insert(user); double i = 3 / 0; System.out.println("i = " + i); System.out.println("user = " + user); return "success"; }

실습 CRUD(Create, Read, Update, Delete)에 대한 각각의 URL을 구성하고 테스트 해보시오. URL 메소드 설명 view /user/signup GET 회원 가입 폼 양식 표시 signup.jsp POST 회원 가입, 성공하면 /user/list로 이동 /user/list 유저 목록을 테이블로 보여주는 화면 list.jsp /user/edit 특정 ID를 가지는 유저를 수정할 수 있는 화면 /user/signup과 거의 동일하나 특정 ID를 가지는 유저 정보가 미리 폼에 입력되어 있다 edit.jsp 특정 ID를 가지는 유저를 수정한 결과를 받아 데이터베이스에서 업데이트 업데이트 후 /user/list 로 이동 /user/delete 특정 ID를 가지는 유저를 삭제할 수 있는 URL 삭제 후 /user/list로 이동

동적 SQL 경우에 따라 SQL문을 동적으로 처리해야 할 경우가 있다. 첫번째 방법은 SqlProvider와 SqlBuilder를 이용하여 Java에서 동적으로 SQL을 생성하는 방법이다. 예) 동적으로 Select문을 구성할 때는 @SelectProvider 어노테이션을 이용한다. 그 외 @UpdateProvider, @InsertProvider, @DeleteProvider가 있다. UserMapper.java @SelectProvider(type = UserSqlProvider.class, method = "findAllByProvider") List<User> findByProvider(Searchable searchable);

동적 SQL 동적 쿼리를 위한 객체 Searchable.java public class Searchable { private String name; private String email; private String orderParam; public String getName() { return name; } public void setName(String name) { this.name = name; public String getEmail() { return email; public void setEmail(String email) { this.email = email; public String getOrderParam() { return orderParam; public void setOrderParam(String orderParam) { this.orderParam = orderParam;

동적 SQL 동적 쿼리를 작성하는 객체 koreatech.cse.repository.provider.UserSqlProvider.java package koreatech.cse.repository.provider; import koreatech.cse.domain.Searchable; import org.apache.ibatis.jdbc.SQL; public class UserSqlProvider { public String findAllByProvider(final Searchable searchable) { return new SQL() { { SELECT("*"); FROM("USERS"); if(searchable.getName() != null) { WHERE("NAME = #{name}"); if(searchable.getEmail() != null) { OR(); WHERE("EMAIL = #{email}"); } if(searchable.getOrderParam() != null) { ORDER_BY(searchable.getOrderParam() + " DESC"); }.toString();

동적 SQL 동적 쿼리를 위한 Controller 수정 view를 통한 확인 koreatech.cse.controller.UserController.java @RequestMapping(value = "/list", method = RequestMethod.GET) public String list(Model model, @RequestParam(required=false) String name, @RequestParam(required=false) String email, @RequestParam(required=false) String order) { Searchable searchable = new Searchable(); searchable.setName(name); searchable.setEmail(email); searchable.setOrderParam(order); model.addAttribute("users", userMapper.findByProvider(searchable)); return "list"; } /WEB-INF/views/list.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Edit</title> </head> <body> Search Users By Sql Provider<br/> <c:forEach var="u" items="${users}"> ${u}<br/> </c:forEach> </body> </html>

동적 SQL UserController와 UserMapper는 자신에게 어떤 쿼리가 올지 모르는 상태이다. 동적 SQL을 활용해 유저의 URL요청에 따라 동적으로 대응을 하여 보여줄 수 있다. 다음과 같은 주소로 테스트 해보자. http://localhost:8080/user/list?name=admin&email=user1@email.com&order=age http://localhost:8080/user/list?order=age http://localhost:8080/user/list?name=admin

동적 SQL 두번째 방법은 스크립트형식의 쿼리를 작성하는 것이다. Mybatis는 JSTL과 비슷한 형식의 스크립트를 제공한다. 앞서 UserSqlProvider와 비슷한 동작을 하는 스크립트는 다음과 같다. 추가) 리스트와 같은 형식을 for문으로 동적으로 추가하고자 할 때는 아래와 같이 활용할 수 있다. UserMapper.java @Select("<script>" + "SELECT * FROM USERS" + "<if test='name != null'> WHERE NAME = #{name}</if>" + "<if test='name != null and email != null'> OR EMAIL = #{email}</if>" + "<if test='orderParam != null'>ORDER BY ${orderParam} DESC</if>" + "</script>") List<User> findByScript(Searchable searchable); @Select("<script>" + "SELECT * FROM USERS" + "<if test='stringList != null and !stringList.empty'> WHERE NAME IN <foreach item='item' collection='stringList' open='(' separator=',' close=')'>#{item}</foreach></if>" + "</script>") List<User> findByList(@Param("stringList") List<String> stringList);

동적 SQL 이 때, #{string}와 ${string}의 차이는? #{string}은 SQL에서 ‘값’으로써 인식된다. 즉, SELECT * FROM USERS WHERE ID = #{id} 와 같이 해당 컬럼(ID)의 값으로 사용될 때 쓰인다. ${string}은 직접적인 쿼리 그 자체로써 인식된다. 만약 String string = “SELECT * FROM USERS WHERE ID > 0”; 과 같은 쿼리가 있다면 다음과 같이 바로 사용할 수도 있다. @Select("${string}") List<User> findByString(@Param("string") String string);

동적 SQL 즉, String param = “AGE”; 일 때 최종 쿼리는 아래와 같으며, 2)는 오류가 발생한다. 1) SELECT * FROM USERS ORDER BY AGE; 2) SELECT * FROM USERS ORDER BY ‘AGE’; @Select(“SELECT * FROM USERS ORDER BY ${param}") List<User> findByString(@Param(“param") String param); @Select(“SELECT * FROM USERS ORDER BY #{param}") List<User> findByString(@Param(“param") String param);