SlideShare a Scribd company logo
Spring Boot with MyBatis
KESTI 개발팀
Spring Boot with MyBatis
• mybatis-spring-boot-starter 소개
• MyBatis Tutorials
• setup
• mappers
• testing
• Bonus Tutorials
• Flyway
• QueryDSL
2016-10-12KESTI 개발팀 세미나 2
MyBatis for Spring Boot
• MyBatis 를 Spring Boot Application 에서 사용하기 위한
라이브러리
• 홈페이지 : http://www.mybatis.org/mybatis-spring-boot/
• 소스 : https://github.com/mybatis/mybatis-spring-boot
• 예제 :
• KESTI SpringBoot-MyBatis Tutorials
• Spring Boot 에서 Java Config를 통해 myBatis 연동하기
2016-10-12KESTI 개발팀 세미나 3
MyBatis Tutorials
2016-10-12KESTI 개발팀 세미나 4
Tutorial Overview
1. mybatis-spring-boot-starter 프로젝트 구성
2. Mapper – Annotation / XML 방식
3. MyBatis 설정 방법
4. Flyway 를 이용한 database migration 방법
5. MyBatis 단위 테스트
2016-10-12KESTI 개발팀 세미나 5
1. 프로젝트 구성
<dependencies>
<dependency>
<groupId>kr.kesti.kesti4j</groupId>
<artifactId>kesti4j-data-java6</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
2016-10-12KESTI 개발팀 세미나 6
Project Structures
configuration
data handling source
Spring Boot Application
Flyway database migration
MyBatis configuration & XML Mappers
환경설정 정보
Test 코드
2016-10-12KESTI 개발팀 세미나 7
XML Mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.kesti.mybatis.examples.domain.models">
<select id="selectActorByFirstname" parameterType="String" resultType="Actor">
SELECT * FROM Actors WHERE firstname = #{firstname} limit 1
</select>
<insert id="insertActor" useGeneratedKeys="true" keyProperty="id">
insert into Actors(firstname, lastname)
values( #{firstname}, #{lastname} )
</insert>
<!-- Oracle, PostgreSQL 은 SEQUENCE -->
<!--
<insert id="insertActorBySequence">
<selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED">
SELECT SEQ_ID.nextval FROM DUAL
</selectKey>
INSERT INTO Autors (id, firstname, lastname)
VALUES (#{id}, #{firstname}, #{lastname})
</insert>
-->
</mapper>
2016-10-12KESTI 개발팀 세미나 8
Annotated Mapper
/**
* Actor 를 위한 MyBatis Mapper 입니다.
*/
public interface ActorMapper {
@Select("SELECT * FROM Actors WHERE firstname = #{firstname}")
Actor findByFirstname(@Param("firstname") String firstname);
@Select("SELECT * FROM Actors")
List<Actor> findAll();
@Delete("DELETE FROM Actors WHERE id=#{id}")
void deleteById(@Param("id") Integer id);
}
/**
* MyBatis 를 Spring boot 에서 사용하기 위한 환경설정
*/
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackageClasses = { ActorRepository.class })
@MapperScan(basePackageClasses = { ActorMapper.class })
public class MyBatisConfiguration extends AbstractFlywayMyBatisConfiguration {
2016-10-12KESTI 개발팀 세미나 9
XML Mapper
보다 좋은점은?
Repository / DAO
/**
* {@link Actor} 를 위한 Repository (DAO) 입니다.
*/
@Slf4j
@Repository
public class ActorRepository {
@Autowired ActorMapper mapper;
@Autowired SqlSessionTemplate session;
public Actor findByFirstname(@NonNull String firstname) {
return mapper.findByFirstname(firstname);
}
public Actor findByFirstnameWithXmlMapper(@NonNull String firstname) {
return session.selectOne("selectActorByFirstname", firstname);
}
public List<Actor> findAll() {
return mapper.findAll();
}
public int insertActor(@NonNull Actor actor) {
return session.insert("insertActor", actor);
}
public void deleteById(@NonNull Integer id) {
mapper.deleteById(id);
}
}
2016-10-12KESTI 개발팀 세미나 10
MyBatis JavaConfig
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackageClasses = { ActorRepository.class })
@MapperScan(basePackageClasses = { ActorMapper.class })
public class MyBatisConfiguration extends AbstractFlywayMyBatisConfiguration {
// datasource 용 properties (application.properties 에서 자동으로 정보를 읽어옴)
@Inject DataSourceProperties dataSourceProperties;
// mybatis 용 properties (application.properties 에서 자동으로 정보를 읽어옴)
@Inject MybatisProperties mybatisProperties;
@Override
protected DatabaseSetting getDatabaseSetting() {
return DatabaseSetting.builder()
.driverClass(dataSourceProperties.getDriverClassName())
.jdbcUrl(dataSourceProperties.getUrl())
.build();
}
@Override
protected String getMyBatisConfigPath() {
return mybatisProperties.getConfig();
}
@Override
protected String getMyBatisMapperPath() {
return mybatisProperties.getMapperLocations()[0];
}
}
2016-10-12KESTI 개발팀 세미나 11
XML Config
와 장단점
비교
Spring Boot application.properties
### DataSource
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.jdbc-url=jdbc:h2:mem
spring.datasource.username=sa
spring.datasource.password=
### MyBatis
mybatis.config=mybatis/mybatis-config.xml
mybatis.mapper-locations=mybatis/mappers/**/*Mapper.xml
mybatis.executor-type=simple
### Logging
logging.level.root=info
logging.level.kr.kesti.mybatis.examples=debug
2016-10-12KESTI 개발팀 세미나 12
Database Setup by Flyway
/**
* Flyway 를 이용한 DB Migration 을 수행하도록 합니다.
*
* @param dataSource DataSource
* @return {@link Flyway} 인스턴스
*/
@Bean(initMethod = "migrate")
protected Flyway flyway(DataSource dataSource) {
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
if (cleanDatabaseForTest()) {
flyway.clean();
}
return flyway;
}
CREATE TABLE Actors (
id SERIAL PRIMARY KEY,
firstname VARCHAR(64),
lastname VARCHAR(64)
);
INSERT INTO Actors (firstname, lastname) VALUES
('Sunghyouk', 'Bae');
INSERT INTO Actors (firstname, lastname) VALUES ('Misook',
'Kwon');
INSERT INTO Actors (firstname, lastname) VALUES ('Jehyoung',
'Bae');
INSERT INTO Actors (firstname, lastname) VALUES ('Jinseok',
'Kwon');
INSERT INTO Actors (firstname, lastname) VALUES ('Kildong',
'Hong');
2016-10-12KESTI 개발팀 세미나 13
Configuration Test
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { MyBatisConfiguration.class })
public class MyBatisConfigurationTest {
@Inject ActorMapper actorMapper;
@Inject ActorRepository actorRepository;
@Inject private SqlSessionFactory sf;
@Test
public void testConfiguration() {
assertThat(actorMapper).isNotNull();
assertThat(actorRepository).isNotNull();
assertThat(sf).isNotNull();
}
}
2016-10-12KESTI 개발팀 세미나 14
Repository Test
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { MyBatisConfiguration.class })
public class ActorRepositoryTest {
@Inject ActorRepository actorRepo;
private static final String FIRST_NAME = "Sunghyouk";
@Test
public void testConfiguration() {
assertThat(actorRepo).isNotNull();
}
@Test
public void testFindByFirstname() {
Actor actor = actorRepo.findByFirstname(FIRST_NAME);
assertThat(actor).isNotNull();
}
@Test
public void testFindByFirstnameWithXmlMapper() {
Actor actor = actorRepo.findByFirstnameWithXmlMapper(FIRST_NAME);
assertThat(actor).isNotNull();
}
@Test
public void testFindAll() {
List<Actor> actors = actorRepo.findAll();
assertThat(actors.size()).isGreaterThan(0);
}
@Test
public void testInsertActor() {
String firstname = "mybatis";
Actor actor = Actor.of(null, firstname, "kesti");
int rowCount = actorRepo.insertActor(actor);
log.debug("rowCount={}", rowCount);
actor = actorRepo.findByFirstname(firstname);
log.debug("actor={}", actor);
assertThat(actor).isNotNull();
assertThat(actor.getFirstname()).isEqualTo(firstname);
actorRepo.deleteById(actor.getId());
}
}
2016-10-12KESTI 개발팀 세미나 15
Flyway
Evolve your Database Schema easily and
reliably across all your instances
2016-10-12KESTI 개발팀 세미나 16
Code 관리는 git
2016-10-12KESTI 개발팀 세미나 17
DB 형상 관리는?
DB Schema Control by Dev Step
2016-10-12KESTI 개발팀 세미나 18
DB Schema Version Control
2016-10-12KESTI 개발팀 세미나 19
QueryDSL
Unified Queries for Java with Typesafe
2016-10-12KESTI 개발팀 세미나 20
QueryDSL 개요
• 질의어를 문자열이 아닌 Java Code로 표현
• Query문 – type check 불가 / 실행 전에는 오류 검출 불가
• Java Code는
• Compile Error를 미리 검출
• Code assistant 활용 100%
• Refactoring 용이
• 다양한 저장소에 대한 일관된 질의어 제작 가능
• Collection, RDBMS, MongoDB, Lucene …
• .NET 의 LINQ 같은 목적 (Langunage-INtegrated Query)
• 참고 : 한글 매뉴얼 (단 3.4.0 기준임. 4.x 는 package 명이
달라졌음)
2016-10-12KESTI 개발팀 세미나 21
QueryDSL 적용 범위
JPA (Java Persistence API)
JDO (Java Data Object)
SQL
Lucence
MongoDB
Collections
QueryDSL
RDBMS
ORM
Lucene
(search
engine)
MongoD
B
List / Map
2016-10-12KESTI 개발팀 세미나 22
QueryDSL for SQL
• Select
• Join (innerJoin, join, leftJoin, rightJoin, fullJoin)
• group by / having
• order by
• limit / offset / restrict
• subquery
• Window functions
• Common Table Expression (CTE)
• Insert
• Update
• Delete
2016-10-12KESTI 개발팀 세미나 23
SELECT with Projections
2016-10-12KESTI 개발팀 세미나 24
QActors $ = QActors.actors;
List<Tuple> rows = query.select($.id, $.firstname, $.lastname)
.from($)
.fetch();
QActors $ = QActors.actors;
List<Actor> actors = query.select(Projections.constructor(Actor.class,
$.id,
$.firstname,
$.lastname))
.from($)
.fetch();
SELECT – Filter, GroupBy
2016-10-12KESTI 개발팀 세미나 25
Actor actor = query.select(Projections.constructor(Actor.class,
$.id,
$.firstname,
$.lastname))
.from($)
.where($.lastname.eq("Bae"))
.fetchFirst();
List<Tuple> rows = query.select($.lastname, $.lastname.count().as("cnt"))
.from($)
.groupBy($.lastname)
.fetch();
SELECT : Subquery
2016-10-12KESTI 개발팀 세미나 26
QActors $ = QActors.actors;
QActors $2 = new QActors("$2");
SQLQuery<Actor> sq = query.select(Projections.constructor(Actor.class,
$.id,
$.firstname,
$.lastname))
.from($)
.where($.id.eq(SQLExpressions.select($2.id.max()).from($2)));
List<Actor> actors = sq.fetch();
CUD
2016-10-12KESTI 개발팀 세미나 27
QActors $ = QActors.actors;
long inserted = query.insert($)
.columns($.firstname, $.lastname)
.values("querydsl", "examples")
.execute();
long updated = query.update($)
.set($.lastname, "updated examples")
.where($.firstname.eq("querydsl"))
.execute();
long deleted = query.delete($)
.where($.firstname.eq("querydsl"))
.execute();
CUD Batch Execution
2016-10-12KESTI 개발팀 세미나 28
QActors $ = QActors.actors;
int COUNT = 100;
// INSERT
SQLInsertClause insertClause = query.insert($);
for (int i = 0; i < COUNT; i++) {
insertClause.set($.firstname, "firstname-" + i)
.set($.lastname, "lastname-" + i)
.addBatch();
}
long insertedCount = insertClause.execute();
// UPDATE
SQLUpdateClause updateClause = query.update($);
for (int i = 0; i < COUNT; i++) {
updateClause.set($.firstname, "updated-firstname-" + i)
.where($.lastname.eq("lastname-" + i))
.addBatch();
}
long updatedCount = updateClause.execute();
// DELETE
SQLDeleteClause deleteClause = query.delete($);
for (int i = 0; i < COUNT; i++) {
deleteClause.where($.firstname.eq("updated-firstname-" + i))
.addBatch();
}
long deletedCount = deleteClause.execute();
QueryDSL Dependency
2016-10-12KESTI 개발팀 세미나 29
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql</artifactId>
<version>${com.querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql-spring</artifactId>
<version>${com.querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql-codegen</artifactId>
<version>${com.querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-spatial</artifactId>
<version>${com.querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql-spatial</artifactId>
<version>${com.querydsl.version}</version>
</dependency>
QueryDSL APT
2016-10-12KESTI 개발팀 세미나 30
<plugin>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>${com.querydsl.version}</version>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbcDriver>org.postgresql.Driver</jdbcDriver>
<jdbcUrl>jdbc:postgresql://localhost/querydsl</jdbcUrl>
<jdbcUser>root</jdbcUser>
<jdbcPassword>root</jdbcPassword>
<packageName>kesti4j.data.querydsl.models</packageName>
<sourceFolder>${project.basedir}/target/generated-sources/java</sourceFolder>
<targetFolder>${project.basedir}/target/generated-sources/java</targetFolder>
<spatial>true</spatial>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1206-jdbc42</version>
</dependency>
</dependencies>
</plugin>
QueryDSL Generated Code
2016-10-12KESTI 개발팀 세미나 31
/**
* QActors is a Querydsl query type for QActors
*/
@Generated("com.querydsl.sql.codegen.MetaDataSerializer")
public class QActors extends RelationalPathSpatial<QActors> {
private static final long serialVersionUID = 822224394;
public static final QActors actors = new QActors("actors");
public final StringPath firstname = createString("firstname");
public final NumberPath<Integer> id = createNumber("id", Integer.class);
public final StringPath lastname = createString("lastname");
public final com.querydsl.sql.PrimaryKey<QActors> actorsPkey = createPrimaryKey(id);
public QActors(String variable) {
super(QActors.class, forVariable(variable), "public", "actors");
addMetadata();
}
public QActors(String variable, String schema, String table) {
super(QActors.class, forVariable(variable), schema, table);
addMetadata();
}
public QActors(Path<? extends QActors> path) {
super(path.getType(), path.getMetadata(), "public", "actors");
addMetadata();
}
public QActors(PathMetadata metadata) {
super(QActors.class, metadata, "public", "actors");
addMetadata();
}
public void addMetadata() {
addMetadata(firstname, ColumnMetadata.named("firstname").withIndex(2).ofType(Types.VARCHAR).withSize(64));
addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(Types.INTEGER).withSize(10).notNull());
addMetadata(lastname, ColumnMetadata.named("lastname").withIndex(3).ofType(Types.VARCHAR).withSize(64));
}
}

More Related Content

What's hot

Spring Boot
Spring BootSpring Boot
Spring Boot
HongSeong Jeon
 
Top 50 Node.js Interview Questions and Answers | Edureka
Top 50 Node.js Interview Questions and Answers | EdurekaTop 50 Node.js Interview Questions and Answers | Edureka
Top 50 Node.js Interview Questions and Answers | Edureka
Edureka!
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
Aaron Schram
 
Spring Web MVC
Spring Web MVCSpring Web MVC
Spring Web MVC
zeeshanhanif
 
Spring jdbc
Spring jdbcSpring jdbc
Spring jdbc
Harshit Choudhary
 
Spring boot
Spring bootSpring boot
Spring boot
Pradeep Shanmugam
 
Building a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootBuilding a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring Boot
Omri Spector
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
Jeevesh Pandey
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
Daniel Rene FOUOMENE PEWO
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
Dzmitry Naskou
 
Spring boot
Spring bootSpring boot
Spring boot
Bhagwat Kumar
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 
Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022
Sam Brannen
 
Spring Framework - MVC
Spring Framework - MVCSpring Framework - MVC
Spring Framework - MVC
Dzmitry Naskou
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
Purbarun Chakrabarti
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
07.pallav
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
Dzmitry Naskou
 
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slidesSpring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Hitesh-Java
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
Sandeep Chawla
 

What's hot (20)

Spring Boot
Spring BootSpring Boot
Spring Boot
 
Top 50 Node.js Interview Questions and Answers | Edureka
Top 50 Node.js Interview Questions and Answers | EdurekaTop 50 Node.js Interview Questions and Answers | Edureka
Top 50 Node.js Interview Questions and Answers | Edureka
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
Spring Web MVC
Spring Web MVCSpring Web MVC
Spring Web MVC
 
Spring jdbc
Spring jdbcSpring jdbc
Spring jdbc
 
Spring boot
Spring bootSpring boot
Spring boot
 
Building a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootBuilding a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring Boot
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
 
Spring boot
Spring bootSpring boot
Spring boot
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022
 
Spring Framework - MVC
Spring Framework - MVCSpring Framework - MVC
Spring Framework - MVC
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slidesSpring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
 

Viewers also liked

Springboot Overview
Springboot  OverviewSpringboot  Overview
Springboot Overview
Jose Patricio Bovet Derpich
 
MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제
정완 전
 
Springboot and camel
Springboot and camelSpringboot and camel
Springboot and camel
Deepak Kumar
 
SeaJUG May 2012 mybatis
SeaJUG May 2012 mybatisSeaJUG May 2012 mybatis
SeaJUG May 2012 mybatisWill Iverson
 
How to Choose an API Automation Tool for a Distributed Cloud-based App: To...
How to Choose an API Automation Tool for a Distributed Cloud-based App: To...How to Choose an API Automation Tool for a Distributed Cloud-based App: To...
How to Choose an API Automation Tool for a Distributed Cloud-based App: To...
Altoros
 
Secure RESTful API Automation With JavaScript
Secure RESTful API Automation With JavaScriptSecure RESTful API Automation With JavaScript
Secure RESTful API Automation With JavaScript
Jonathan LeBlanc
 
OpenERP 6.1 Framework Changes
OpenERP 6.1 Framework ChangesOpenERP 6.1 Framework Changes
OpenERP 6.1 Framework Changes
Odoo
 
Design Summit - RESTful API Overview - John Hardy
Design Summit - RESTful API Overview - John HardyDesign Summit - RESTful API Overview - John Hardy
Design Summit - RESTful API Overview - John Hardy
ManageIQ
 
Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...
Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...
Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...Vladimir Bacvanski, PhD
 
좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012Daum DNA
 
Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»
e-Legion
 
RESTful API Automation with JavaScript
RESTful API Automation with JavaScriptRESTful API Automation with JavaScript
RESTful API Automation with JavaScript
Jonathan LeBlanc
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in action
Ciro Rizzo
 
Querydsl overview 2014
Querydsl overview 2014Querydsl overview 2014
Querydsl overview 2014
Timo Westkämper
 
A brief introduction to Realm with Kotlin
A brief introduction to Realm with KotlinA brief introduction to Realm with Kotlin
A brief introduction to Realm with Kotlin
Leonardo YongUk Kim
 
Frisby: Rest API Automation Framework
Frisby: Rest API Automation FrameworkFrisby: Rest API Automation Framework
Frisby: Rest API Automation Framework
Quovantis
 
Agile 2014 - Personal Kanban
Agile 2014 - Personal KanbanAgile 2014 - Personal Kanban
Agile 2014 - Personal Kanban
Derek Huether
 
Web API Test Automation using Frisby & Node.js
Web API Test Automation using Frisby  & Node.jsWeb API Test Automation using Frisby  & Node.js
Web API Test Automation using Frisby & Node.js
Chi Lang Le Vu Tran
 

Viewers also liked (20)

MyBatis
MyBatisMyBatis
MyBatis
 
Springboot Overview
Springboot  OverviewSpringboot  Overview
Springboot Overview
 
MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제MyBatis 개요와 Java+MyBatis+MySQL 예제
MyBatis 개요와 Java+MyBatis+MySQL 예제
 
Springboot and camel
Springboot and camelSpringboot and camel
Springboot and camel
 
SeaJUG May 2012 mybatis
SeaJUG May 2012 mybatisSeaJUG May 2012 mybatis
SeaJUG May 2012 mybatis
 
How to Choose an API Automation Tool for a Distributed Cloud-based App: To...
How to Choose an API Automation Tool for a Distributed Cloud-based App: To...How to Choose an API Automation Tool for a Distributed Cloud-based App: To...
How to Choose an API Automation Tool for a Distributed Cloud-based App: To...
 
Secure RESTful API Automation With JavaScript
Secure RESTful API Automation With JavaScriptSecure RESTful API Automation With JavaScript
Secure RESTful API Automation With JavaScript
 
OpenERP 6.1 Framework Changes
OpenERP 6.1 Framework ChangesOpenERP 6.1 Framework Changes
OpenERP 6.1 Framework Changes
 
Design Summit - RESTful API Overview - John Hardy
Design Summit - RESTful API Overview - John HardyDesign Summit - RESTful API Overview - John Hardy
Design Summit - RESTful API Overview - John Hardy
 
Telephonic etiquettes
Telephonic  etiquettesTelephonic  etiquettes
Telephonic etiquettes
 
Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...
Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...
Crash Introduction to Modern Java Data Access: Understanding JPA, Hibernate, ...
 
좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012좌충우돌 ORM 개발기 | Devon 2012
좌충우돌 ORM 개발기 | Devon 2012
 
Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»Светлана Исакова «Язык Kotlin»
Светлана Исакова «Язык Kotlin»
 
RESTful API Automation with JavaScript
RESTful API Automation with JavaScriptRESTful API Automation with JavaScript
RESTful API Automation with JavaScript
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in action
 
Querydsl overview 2014
Querydsl overview 2014Querydsl overview 2014
Querydsl overview 2014
 
A brief introduction to Realm with Kotlin
A brief introduction to Realm with KotlinA brief introduction to Realm with Kotlin
A brief introduction to Realm with Kotlin
 
Frisby: Rest API Automation Framework
Frisby: Rest API Automation FrameworkFrisby: Rest API Automation Framework
Frisby: Rest API Automation Framework
 
Agile 2014 - Personal Kanban
Agile 2014 - Personal KanbanAgile 2014 - Personal Kanban
Agile 2014 - Personal Kanban
 
Web API Test Automation using Frisby & Node.js
Web API Test Automation using Frisby  & Node.jsWeb API Test Automation using Frisby  & Node.js
Web API Test Automation using Frisby & Node.js
 

Similar to SpringBoot with MyBatis, Flyway, QueryDSL

OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
mfrancis
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
Christian Baranowski
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Webpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of usWebpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of us
Stefan Adolf
 
Quick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerQuick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase Server
Nic Raboy
 
Kharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backendKharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backend
Max Klymyshyn
 
Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Gunith Devasurendra
 
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyRed Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Mark Proctor
 
Spring design-juergen-qcon
Spring design-juergen-qconSpring design-juergen-qcon
Spring design-juergen-qconYiwei Ma
 
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdfdokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
Appster1
 
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
dokumen.tips_rediscovering-spring-with-spring-boot1.pdfdokumen.tips_rediscovering-spring-with-spring-boot1.pdf
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
Appster1
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New Features
Jay Lee
 
Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4
Yuriy Shapovalov
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
Naresha K
 
Grails, Trails, and Sails: Rails Through a Coffee Filter
Grails, Trails, and Sails: Rails Through a Coffee FilterGrails, Trails, and Sails: Rails Through a Coffee Filter
Grails, Trails, and Sails: Rails Through a Coffee Filterelliando dias
 
Come abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architettureCome abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architetture
Commit University
 
Liferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for DevelopersLiferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for Developers
Azilen Technologies Pvt. Ltd.
 
jclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian Colejclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian ColeEverett Toews
 
Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDB
MongoDB
 

Similar to SpringBoot with MyBatis, Flyway, QueryDSL (20)

OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
 
Introducing jee7 – jsf 2
Introducing jee7 – jsf 2Introducing jee7 – jsf 2
Introducing jee7 – jsf 2
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Webpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of usWebpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of us
 
Quick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerQuick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase Server
 
Kharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backendKharkivpy#3: Javascript and Python backend
Kharkivpy#3: Javascript and Python backend
 
Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)Rediscovering Spring with Spring Boot(1)
Rediscovering Spring with Spring Boot(1)
 
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyRed Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
 
Spring design-juergen-qcon
Spring design-juergen-qconSpring design-juergen-qcon
Spring design-juergen-qcon
 
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdfdokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
 
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
dokumen.tips_rediscovering-spring-with-spring-boot1.pdfdokumen.tips_rediscovering-spring-with-spring-boot1.pdf
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
 
Spring5 New Features
Spring5 New FeaturesSpring5 New Features
Spring5 New Features
 
Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Grails, Trails, and Sails: Rails Through a Coffee Filter
Grails, Trails, and Sails: Rails Through a Coffee FilterGrails, Trails, and Sails: Rails Through a Coffee Filter
Grails, Trails, and Sails: Rails Through a Coffee Filter
 
Come abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architettureCome abbiamo scalato Dazn con micro-architetture
Come abbiamo scalato Dazn con micro-architetture
 
Liferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for DevelopersLiferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for Developers
 
jclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian Colejclouds High Level Overview by Adrian Cole
jclouds High Level Overview by Adrian Cole
 
Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDB
 

More from Sunghyouk Bae

JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
Sunghyouk Bae
 
Introduction of failsafe
Introduction of failsafeIntroduction of failsafe
Introduction of failsafe
Sunghyouk Bae
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Sunghyouk Bae
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
Sunghyouk Bae
 
Requery overview
Requery overviewRequery overview
Requery overview
Sunghyouk Bae
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
measure metrics
measure metricsmeasure metrics
measure metrics
Sunghyouk Bae
 
Alternatives of JPA/Hibernate
Alternatives of JPA/HibernateAlternatives of JPA/Hibernate
Alternatives of JPA/Hibernate
Sunghyouk Bae
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
Sunghyouk Bae
 
Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)
Sunghyouk Bae
 
테스트자동화와 TDD
테스트자동화와 TDD테스트자동화와 TDD
테스트자동화와 TDD
Sunghyouk Bae
 
JUnit & AssertJ
JUnit & AssertJJUnit & AssertJ
JUnit & AssertJ
Sunghyouk Bae
 
좋은 개발자 되기
좋은 개발자 되기좋은 개발자 되기
좋은 개발자 되기
Sunghyouk Bae
 
Using AdoRepository
Using AdoRepositoryUsing AdoRepository
Using AdoRepository
Sunghyouk Bae
 
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개Sunghyouk Bae
 
Strategy Maps
Strategy MapsStrategy Maps
Strategy Maps
Sunghyouk Bae
 

More from Sunghyouk Bae (16)

JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
 
Introduction of failsafe
Introduction of failsafeIntroduction of failsafe
Introduction of failsafe
 
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018Kotlin @ Coupang Backed - JetBrains Day seoul 2018
Kotlin @ Coupang Backed - JetBrains Day seoul 2018
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Requery overview
Requery overviewRequery overview
Requery overview
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 
measure metrics
measure metricsmeasure metrics
measure metrics
 
Alternatives of JPA/Hibernate
Alternatives of JPA/HibernateAlternatives of JPA/Hibernate
Alternatives of JPA/Hibernate
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 
Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)Java naming strategy (자바 명명 전략)
Java naming strategy (자바 명명 전략)
 
테스트자동화와 TDD
테스트자동화와 TDD테스트자동화와 TDD
테스트자동화와 TDD
 
JUnit & AssertJ
JUnit & AssertJJUnit & AssertJ
JUnit & AssertJ
 
좋은 개발자 되기
좋은 개발자 되기좋은 개발자 되기
좋은 개발자 되기
 
Using AdoRepository
Using AdoRepositoryUsing AdoRepository
Using AdoRepository
 
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개
 
Strategy Maps
Strategy MapsStrategy Maps
Strategy Maps
 

Recently uploaded

In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
QuickwayInfoSystems3
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 

Recently uploaded (20)

In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 

SpringBoot with MyBatis, Flyway, QueryDSL

  • 1. Spring Boot with MyBatis KESTI 개발팀
  • 2. Spring Boot with MyBatis • mybatis-spring-boot-starter 소개 • MyBatis Tutorials • setup • mappers • testing • Bonus Tutorials • Flyway • QueryDSL 2016-10-12KESTI 개발팀 세미나 2
  • 3. MyBatis for Spring Boot • MyBatis 를 Spring Boot Application 에서 사용하기 위한 라이브러리 • 홈페이지 : http://www.mybatis.org/mybatis-spring-boot/ • 소스 : https://github.com/mybatis/mybatis-spring-boot • 예제 : • KESTI SpringBoot-MyBatis Tutorials • Spring Boot 에서 Java Config를 통해 myBatis 연동하기 2016-10-12KESTI 개발팀 세미나 3
  • 5. Tutorial Overview 1. mybatis-spring-boot-starter 프로젝트 구성 2. Mapper – Annotation / XML 방식 3. MyBatis 설정 방법 4. Flyway 를 이용한 database migration 방법 5. MyBatis 단위 테스트 2016-10-12KESTI 개발팀 세미나 5
  • 7. Project Structures configuration data handling source Spring Boot Application Flyway database migration MyBatis configuration & XML Mappers 환경설정 정보 Test 코드 2016-10-12KESTI 개발팀 세미나 7
  • 8. XML Mapper <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="kr.kesti.mybatis.examples.domain.models"> <select id="selectActorByFirstname" parameterType="String" resultType="Actor"> SELECT * FROM Actors WHERE firstname = #{firstname} limit 1 </select> <insert id="insertActor" useGeneratedKeys="true" keyProperty="id"> insert into Actors(firstname, lastname) values( #{firstname}, #{lastname} ) </insert> <!-- Oracle, PostgreSQL 은 SEQUENCE --> <!-- <insert id="insertActorBySequence"> <selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED"> SELECT SEQ_ID.nextval FROM DUAL </selectKey> INSERT INTO Autors (id, firstname, lastname) VALUES (#{id}, #{firstname}, #{lastname}) </insert> --> </mapper> 2016-10-12KESTI 개발팀 세미나 8
  • 9. Annotated Mapper /** * Actor 를 위한 MyBatis Mapper 입니다. */ public interface ActorMapper { @Select("SELECT * FROM Actors WHERE firstname = #{firstname}") Actor findByFirstname(@Param("firstname") String firstname); @Select("SELECT * FROM Actors") List<Actor> findAll(); @Delete("DELETE FROM Actors WHERE id=#{id}") void deleteById(@Param("id") Integer id); } /** * MyBatis 를 Spring boot 에서 사용하기 위한 환경설정 */ @Configuration @EnableAutoConfiguration @ComponentScan(basePackageClasses = { ActorRepository.class }) @MapperScan(basePackageClasses = { ActorMapper.class }) public class MyBatisConfiguration extends AbstractFlywayMyBatisConfiguration { 2016-10-12KESTI 개발팀 세미나 9 XML Mapper 보다 좋은점은?
  • 10. Repository / DAO /** * {@link Actor} 를 위한 Repository (DAO) 입니다. */ @Slf4j @Repository public class ActorRepository { @Autowired ActorMapper mapper; @Autowired SqlSessionTemplate session; public Actor findByFirstname(@NonNull String firstname) { return mapper.findByFirstname(firstname); } public Actor findByFirstnameWithXmlMapper(@NonNull String firstname) { return session.selectOne("selectActorByFirstname", firstname); } public List<Actor> findAll() { return mapper.findAll(); } public int insertActor(@NonNull Actor actor) { return session.insert("insertActor", actor); } public void deleteById(@NonNull Integer id) { mapper.deleteById(id); } } 2016-10-12KESTI 개발팀 세미나 10
  • 11. MyBatis JavaConfig @Configuration @EnableAutoConfiguration @ComponentScan(basePackageClasses = { ActorRepository.class }) @MapperScan(basePackageClasses = { ActorMapper.class }) public class MyBatisConfiguration extends AbstractFlywayMyBatisConfiguration { // datasource 용 properties (application.properties 에서 자동으로 정보를 읽어옴) @Inject DataSourceProperties dataSourceProperties; // mybatis 용 properties (application.properties 에서 자동으로 정보를 읽어옴) @Inject MybatisProperties mybatisProperties; @Override protected DatabaseSetting getDatabaseSetting() { return DatabaseSetting.builder() .driverClass(dataSourceProperties.getDriverClassName()) .jdbcUrl(dataSourceProperties.getUrl()) .build(); } @Override protected String getMyBatisConfigPath() { return mybatisProperties.getConfig(); } @Override protected String getMyBatisMapperPath() { return mybatisProperties.getMapperLocations()[0]; } } 2016-10-12KESTI 개발팀 세미나 11 XML Config 와 장단점 비교
  • 12. Spring Boot application.properties ### DataSource spring.datasource.driver-class-name=org.h2.Driver spring.datasource.jdbc-url=jdbc:h2:mem spring.datasource.username=sa spring.datasource.password= ### MyBatis mybatis.config=mybatis/mybatis-config.xml mybatis.mapper-locations=mybatis/mappers/**/*Mapper.xml mybatis.executor-type=simple ### Logging logging.level.root=info logging.level.kr.kesti.mybatis.examples=debug 2016-10-12KESTI 개발팀 세미나 12
  • 13. Database Setup by Flyway /** * Flyway 를 이용한 DB Migration 을 수행하도록 합니다. * * @param dataSource DataSource * @return {@link Flyway} 인스턴스 */ @Bean(initMethod = "migrate") protected Flyway flyway(DataSource dataSource) { Flyway flyway = new Flyway(); flyway.setDataSource(dataSource); if (cleanDatabaseForTest()) { flyway.clean(); } return flyway; } CREATE TABLE Actors ( id SERIAL PRIMARY KEY, firstname VARCHAR(64), lastname VARCHAR(64) ); INSERT INTO Actors (firstname, lastname) VALUES ('Sunghyouk', 'Bae'); INSERT INTO Actors (firstname, lastname) VALUES ('Misook', 'Kwon'); INSERT INTO Actors (firstname, lastname) VALUES ('Jehyoung', 'Bae'); INSERT INTO Actors (firstname, lastname) VALUES ('Jinseok', 'Kwon'); INSERT INTO Actors (firstname, lastname) VALUES ('Kildong', 'Hong'); 2016-10-12KESTI 개발팀 세미나 13
  • 14. Configuration Test @Slf4j @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { MyBatisConfiguration.class }) public class MyBatisConfigurationTest { @Inject ActorMapper actorMapper; @Inject ActorRepository actorRepository; @Inject private SqlSessionFactory sf; @Test public void testConfiguration() { assertThat(actorMapper).isNotNull(); assertThat(actorRepository).isNotNull(); assertThat(sf).isNotNull(); } } 2016-10-12KESTI 개발팀 세미나 14
  • 15. Repository Test @Slf4j @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { MyBatisConfiguration.class }) public class ActorRepositoryTest { @Inject ActorRepository actorRepo; private static final String FIRST_NAME = "Sunghyouk"; @Test public void testConfiguration() { assertThat(actorRepo).isNotNull(); } @Test public void testFindByFirstname() { Actor actor = actorRepo.findByFirstname(FIRST_NAME); assertThat(actor).isNotNull(); } @Test public void testFindByFirstnameWithXmlMapper() { Actor actor = actorRepo.findByFirstnameWithXmlMapper(FIRST_NAME); assertThat(actor).isNotNull(); } @Test public void testFindAll() { List<Actor> actors = actorRepo.findAll(); assertThat(actors.size()).isGreaterThan(0); } @Test public void testInsertActor() { String firstname = "mybatis"; Actor actor = Actor.of(null, firstname, "kesti"); int rowCount = actorRepo.insertActor(actor); log.debug("rowCount={}", rowCount); actor = actorRepo.findByFirstname(firstname); log.debug("actor={}", actor); assertThat(actor).isNotNull(); assertThat(actor.getFirstname()).isEqualTo(firstname); actorRepo.deleteById(actor.getId()); } } 2016-10-12KESTI 개발팀 세미나 15
  • 16. Flyway Evolve your Database Schema easily and reliably across all your instances 2016-10-12KESTI 개발팀 세미나 16
  • 17. Code 관리는 git 2016-10-12KESTI 개발팀 세미나 17 DB 형상 관리는?
  • 18. DB Schema Control by Dev Step 2016-10-12KESTI 개발팀 세미나 18
  • 19. DB Schema Version Control 2016-10-12KESTI 개발팀 세미나 19
  • 20. QueryDSL Unified Queries for Java with Typesafe 2016-10-12KESTI 개발팀 세미나 20
  • 21. QueryDSL 개요 • 질의어를 문자열이 아닌 Java Code로 표현 • Query문 – type check 불가 / 실행 전에는 오류 검출 불가 • Java Code는 • Compile Error를 미리 검출 • Code assistant 활용 100% • Refactoring 용이 • 다양한 저장소에 대한 일관된 질의어 제작 가능 • Collection, RDBMS, MongoDB, Lucene … • .NET 의 LINQ 같은 목적 (Langunage-INtegrated Query) • 참고 : 한글 매뉴얼 (단 3.4.0 기준임. 4.x 는 package 명이 달라졌음) 2016-10-12KESTI 개발팀 세미나 21
  • 22. QueryDSL 적용 범위 JPA (Java Persistence API) JDO (Java Data Object) SQL Lucence MongoDB Collections QueryDSL RDBMS ORM Lucene (search engine) MongoD B List / Map 2016-10-12KESTI 개발팀 세미나 22
  • 23. QueryDSL for SQL • Select • Join (innerJoin, join, leftJoin, rightJoin, fullJoin) • group by / having • order by • limit / offset / restrict • subquery • Window functions • Common Table Expression (CTE) • Insert • Update • Delete 2016-10-12KESTI 개발팀 세미나 23
  • 24. SELECT with Projections 2016-10-12KESTI 개발팀 세미나 24 QActors $ = QActors.actors; List<Tuple> rows = query.select($.id, $.firstname, $.lastname) .from($) .fetch(); QActors $ = QActors.actors; List<Actor> actors = query.select(Projections.constructor(Actor.class, $.id, $.firstname, $.lastname)) .from($) .fetch();
  • 25. SELECT – Filter, GroupBy 2016-10-12KESTI 개발팀 세미나 25 Actor actor = query.select(Projections.constructor(Actor.class, $.id, $.firstname, $.lastname)) .from($) .where($.lastname.eq("Bae")) .fetchFirst(); List<Tuple> rows = query.select($.lastname, $.lastname.count().as("cnt")) .from($) .groupBy($.lastname) .fetch();
  • 26. SELECT : Subquery 2016-10-12KESTI 개발팀 세미나 26 QActors $ = QActors.actors; QActors $2 = new QActors("$2"); SQLQuery<Actor> sq = query.select(Projections.constructor(Actor.class, $.id, $.firstname, $.lastname)) .from($) .where($.id.eq(SQLExpressions.select($2.id.max()).from($2))); List<Actor> actors = sq.fetch();
  • 27. CUD 2016-10-12KESTI 개발팀 세미나 27 QActors $ = QActors.actors; long inserted = query.insert($) .columns($.firstname, $.lastname) .values("querydsl", "examples") .execute(); long updated = query.update($) .set($.lastname, "updated examples") .where($.firstname.eq("querydsl")) .execute(); long deleted = query.delete($) .where($.firstname.eq("querydsl")) .execute();
  • 28. CUD Batch Execution 2016-10-12KESTI 개발팀 세미나 28 QActors $ = QActors.actors; int COUNT = 100; // INSERT SQLInsertClause insertClause = query.insert($); for (int i = 0; i < COUNT; i++) { insertClause.set($.firstname, "firstname-" + i) .set($.lastname, "lastname-" + i) .addBatch(); } long insertedCount = insertClause.execute(); // UPDATE SQLUpdateClause updateClause = query.update($); for (int i = 0; i < COUNT; i++) { updateClause.set($.firstname, "updated-firstname-" + i) .where($.lastname.eq("lastname-" + i)) .addBatch(); } long updatedCount = updateClause.execute(); // DELETE SQLDeleteClause deleteClause = query.delete($); for (int i = 0; i < COUNT; i++) { deleteClause.where($.firstname.eq("updated-firstname-" + i)) .addBatch(); } long deletedCount = deleteClause.execute();
  • 29. QueryDSL Dependency 2016-10-12KESTI 개발팀 세미나 29 <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-sql</artifactId> <version>${com.querydsl.version}</version> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-sql-spring</artifactId> <version>${com.querydsl.version}</version> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-sql-codegen</artifactId> <version>${com.querydsl.version}</version> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-spatial</artifactId> <version>${com.querydsl.version}</version> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-sql-spatial</artifactId> <version>${com.querydsl.version}</version> </dependency>
  • 30. QueryDSL APT 2016-10-12KESTI 개발팀 세미나 30 <plugin> <groupId>com.querydsl</groupId> <artifactId>querydsl-maven-plugin</artifactId> <version>${com.querydsl.version}</version> <executions> <execution> <goals> <goal>export</goal> </goals> </execution> </executions> <configuration> <jdbcDriver>org.postgresql.Driver</jdbcDriver> <jdbcUrl>jdbc:postgresql://localhost/querydsl</jdbcUrl> <jdbcUser>root</jdbcUser> <jdbcPassword>root</jdbcPassword> <packageName>kesti4j.data.querydsl.models</packageName> <sourceFolder>${project.basedir}/target/generated-sources/java</sourceFolder> <targetFolder>${project.basedir}/target/generated-sources/java</targetFolder> <spatial>true</spatial> </configuration> <dependencies> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4-1206-jdbc42</version> </dependency> </dependencies> </plugin>
  • 31. QueryDSL Generated Code 2016-10-12KESTI 개발팀 세미나 31 /** * QActors is a Querydsl query type for QActors */ @Generated("com.querydsl.sql.codegen.MetaDataSerializer") public class QActors extends RelationalPathSpatial<QActors> { private static final long serialVersionUID = 822224394; public static final QActors actors = new QActors("actors"); public final StringPath firstname = createString("firstname"); public final NumberPath<Integer> id = createNumber("id", Integer.class); public final StringPath lastname = createString("lastname"); public final com.querydsl.sql.PrimaryKey<QActors> actorsPkey = createPrimaryKey(id); public QActors(String variable) { super(QActors.class, forVariable(variable), "public", "actors"); addMetadata(); } public QActors(String variable, String schema, String table) { super(QActors.class, forVariable(variable), schema, table); addMetadata(); } public QActors(Path<? extends QActors> path) { super(path.getType(), path.getMetadata(), "public", "actors"); addMetadata(); } public QActors(PathMetadata metadata) { super(QActors.class, metadata, "public", "actors"); addMetadata(); } public void addMetadata() { addMetadata(firstname, ColumnMetadata.named("firstname").withIndex(2).ofType(Types.VARCHAR).withSize(64)); addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(Types.INTEGER).withSize(10).notNull()); addMetadata(lastname, ColumnMetadata.named("lastname").withIndex(3).ofType(Types.VARCHAR).withSize(64)); } }