You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
6.9 KiB
Markdown
155 lines
6.9 KiB
Markdown
3 years ago
|
# Getting Started
|
||
|
|
||
|
## Configuration
|
||
|
### Logging
|
||
|
```
|
||
|
JpaAndRequestLoggingConfig.java : JPA / Web
|
||
|
P6spySqlFormatConfiguration.java - decorator.datasource.p6spy.enable-logging: true
|
||
|
CustomCommonsRequestLoggingFilter.java - org.springframework.web.filter: debug 필수
|
||
|
decorator.datasource.p6spy
|
||
|
|
||
|
Security 비활성
|
||
|
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class})
|
||
|
SecurityJavaConfig.java - 예외 등록
|
||
|
- h2, swagger
|
||
|
|
||
|
Swagger 설정 : SwaggerConfig
|
||
|
|
||
|
resources 설정
|
||
|
WebAndFluxCommonConfig.java - MVC / Flux 공통 사용
|
||
|
|
||
|
MVC / Flux 동시 사용 설정
|
||
|
@EnableWebMvc 만 설정 - @EnableWebFlux는 미사용(사용시 충돌)
|
||
|
MVC application
|
||
|
- @EnableWebMvc
|
||
|
- @SpringBootApplication : exclude에 WebMvcAutoConfiguration.class
|
||
|
```
|
||
|
|
||
|
### swagger
|
||
|
```java
|
||
|
//파라메터 값을 모두 String으로 취급
|
||
|
//String이 아닌 경우 example 값을 부여해야 compile시 WARN 발생 안함
|
||
|
@ApiImplicitParam(name="cmmUserId", value="사용자ID-PK", example = "1")
|
||
|
|
||
|
```
|
||
|
|
||
|
### Reference Documentation
|
||
|
For further reference, please consider the following sections:
|
||
|
|
||
|
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
|
||
|
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.0/maven-plugin/reference/html/)
|
||
|
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.0/maven-plugin/reference/html/#build-image)
|
||
|
|
||
|
# **Tailwind CSS**
|
||
|
- [Tailwind CSS](https://tailwindcss.com/): 경량의 **CSS** 프레임워크이다. 덩치가 큰 **Bootstrap**과 달리 **CSS**로만 작동하면서 사용자에게 **UI** 구현을 맡기는 컨셉이다. 구현이 직관적이고 자유도가 높아 최근 급속도로 생태계가 확장되고 있다.
|
||
|
- [Tailwind Cheat Sheet](https://nerdcave.com/tailwind-cheat-sheet): **Tailwind CSS**의 모든 클래스를 한 눈에 조회 검색 가능한 사이트이다. 사용이 편리하여 레퍼런스 사이트보다 더 찾게 된다.
|
||
|
- [Tailwind Toolbox](https://www.tailwindtoolbox.com/): **Tailwind CSS** 기반으로 **UI** 구현에 참고할만한 여러 완성 템플릿을 제공한다.
|
||
|
- [Tailwind Components](https://tailwindcomponents.com/): **Tailwind CSS** 기반으로 **UI** 구현에 참고할만한 여러 완성 컴포넌트를 제공한다.
|
||
|
- [Awesome Tailwind CSS](https://github.com/aniftyco/awesome-tailwindcss): **Tailwind CSS** 관련 유용한 유용한 정보들을 소개한다.
|
||
|
- [We build a login using TailwindCSS](https://stefanbauer.me/building-pingping/we-build-a-login-using-tailwindcss): **Tailwind CSS**을 이용한 로그인 폼 제작 과정을 설명한다.
|
||
|
|
||
|
# **Webflux 지원 Database**
|
||
|
1. Postgres (io.r2dbc:r2dbc-postgresql)
|
||
|
2. H2 (io.r2dbc:r2dbc-h2)
|
||
|
3. Microsoft SQL Server (io.r2dbc:r2dbc-mssql)
|
||
|
4. MySQL (com.github.mirromutth:r2dbc-mysql)
|
||
|
5. jasync-sql MySQL (com.github.jasync-sql:jasync-r2dbc-mysql)
|
||
|
|
||
|
### mysql 사용시
|
||
|
```xml
|
||
|
<dependency>
|
||
|
<groupId>io.r2dbc</groupId>
|
||
|
<artifactId>r2dbc-pool</artifactId>
|
||
|
<version>0.8.0.RELEASE</version>
|
||
|
</dependency>
|
||
|
|
||
|
<dependency>
|
||
|
<groupId>io.r2dbc</groupId>
|
||
|
<artifactId>r2dbc-pool</artifactId>
|
||
|
<version>0.8.0.BUILD-SNAPSHOT</version>
|
||
|
</dependency>
|
||
|
|
||
|
<dependency>
|
||
|
<groupId>dev.miku</groupId>
|
||
|
<artifactId>r2dbc-mysql</artifactId>
|
||
|
<version>0.8.1.RELEASE</version>
|
||
|
</dependency>
|
||
|
```
|
||
|
### sample
|
||
|
```java
|
||
|
import java.time.Duration;
|
||
|
import java.time.LocalDateTime;
|
||
|
import java.util.HashMap;
|
||
|
|
||
|
import javax.annotation.PostConstruct;
|
||
|
import org.springframework.stereotype.Repository;
|
||
|
import io.r2dbc.pool.ConnectionPool;
|
||
|
import io.r2dbc.pool.ConnectionPoolConfiguration;
|
||
|
import io.r2dbc.spi.ConnectionFactories;
|
||
|
import io.r2dbc.spi.ConnectionFactory;
|
||
|
import io.r2dbc.spi.Result;
|
||
|
import reactor.core.publisher.Flux;
|
||
|
import reactor.core.publisher.Mono;
|
||
|
|
||
|
@Repository
|
||
|
public class DatabaseConfig {
|
||
|
private ConnectionFactory factory;
|
||
|
private ConnectionPool pool;
|
||
|
|
||
|
//연결
|
||
|
@PostConstruct
|
||
|
public void init() {
|
||
|
factory = ConnectionFactories.get("r2dbcs:pool:mysql://비번:아이디@주소:포트/db명");
|
||
|
ConnectionPoolConfiguration configuration = ConnectionPoolConfiguration.builder(factory)
|
||
|
.maxIdleTime(Duration.ofMillis(1000))
|
||
|
.maxSize(20)
|
||
|
.build();
|
||
|
pool = new ConnectionPool(configuration);
|
||
|
}
|
||
|
|
||
|
//단일 셀렉트, 조회할 테이블 데이터가 n개이면 이런식으로 쓰면 안된다.
|
||
|
public Mono<HashMap<Object, Object>> selectSingle() {
|
||
|
Mono<HashMap<Object, Object>> mono = Mono.from(pool.create()).map(connection -> //커넥션 가공
|
||
|
Flux.from(connection.createStatement("select name, desc, date from test where id_=?ids").bind("ids", "2").execute())
|
||
|
.concatMap( result-> //1차 변환
|
||
|
result.map((row, rowMetadata)-> { //결과 재 조립 후 리턴
|
||
|
HashMap<Object, Object> item = new HashMap<>();
|
||
|
item.put("names", row.get("name",String.class));
|
||
|
item.put("desc", row.get("desc",String.class));
|
||
|
item.put("date", row.get("date",Object.class));
|
||
|
return item;
|
||
|
})
|
||
|
).doFinally( (st)->{connection.close();})
|
||
|
).flatMap( ccc -> Mono.from(ccc)); //2차 변환
|
||
|
return mono;
|
||
|
}
|
||
|
|
||
|
//단순 셀렉트 예제
|
||
|
public Flux<HashMap<Object, Object>> selectMany() {
|
||
|
Flux<HashMap<Object, Object>> flux = Flux.from(pool.create()).concatMap(connection -> //커넥션 가공 및 1차 변환
|
||
|
Flux.from(connection.createStatement("select name, desc, date from test where id_=?ids").bind("ids", "2").execute())
|
||
|
.concatMap( result-> //2차 변환
|
||
|
result.map((row, rowMetadata)-> { //결과 재 조립 후 리턴
|
||
|
HashMap<Object, Object> item = new HashMap<>();
|
||
|
item.put("names", row.get("name",String.class));
|
||
|
item.put("desc", row.get("desc",String.class));
|
||
|
item.put("date", row.get("date",Object.class));
|
||
|
return item;
|
||
|
})
|
||
|
).doFinally( (st)->{connection.close();})
|
||
|
);
|
||
|
return flux;
|
||
|
}
|
||
|
|
||
|
//저장 예제
|
||
|
public Mono<? extends Result> insertTest() {
|
||
|
return Mono.from(pool.create()).map( con ->
|
||
|
Mono.from(
|
||
|
con.createStatement(" insert into test(name, desc, date) values (?name, ?desc, ?date) ")
|
||
|
.bind("name", "abcd").bind("desc", "desc").bind("date", LocalDateTime.now()).execute()
|
||
|
).doFinally( st-> con.close()).map( result -> result)
|
||
|
).flatMap( c-> Mono.from(c));
|
||
|
}
|
||
|
}
|
||
|
```
|