
${param.key}
- request에 존재하는 parameter 값 얻어와 출력
- 요청 URL에 쿼리스트링(GET)이나 폼 데이터(POST)로 전달된 파라미터 값을
직접 req에 세팅하지 않아도 바로 접근할 수 있도록 해줌
<ul>
<li th:text="${param.inputName}">제출된 이름</li>
<li th:text="${param.inputAge}">제출된 나이</li>
<!-- 같은 name 속성값(key)을 가진 파라미터는 배열로 전달 -->
<li th:text="${param.color}">제출된 색상</li>
<!-- 전달된 파라미터값이 없으면 null == 빈문자열임 -->
<!-- 타임리프에서는 null값을 빈문자열("")로 처리함 -->
<!-- 반복할 배열/리스트가 존재하지 않으면 반복 자체를 안함 -->
<li th:each="c : ${param.color}" th:text="${c}"></li>
</ul>
th:text = "속성값"
- 해당 태그에 "속성값"을 내용으로 출력
- 단, html 태그, 특수문자는 해석하지 못함
th:utext = "속성값"
- 해당 태그에 "속성값"을 내용으로 출력
- 단, html 태그, 특수문자 해석 o (innerHTML)
<div>
<h4>th:text (HTML 태그 해석 X)</h4>
<th:block th:text="${str}">str</th:block>
</div>
<div>
<h4>th:utext (HTML 태그 해석 O)</h4>
<th:block th:utext="${str}">str</th:block>
</div>
1. th:text="|문자열 ${}|"
- 해당 요소의 내용으로 "문자열" + 변수값 출력
또는
2. + 연산으로 이어쓰기도 가능
<p th:text="|th:text의 str 값 => ${str}|"></p>
<p th:utext="|th:utext의 str 값 => ${str}|"></p>
<p th:text="${str} + 짠"></p>
th:text / th:utext 대신하는 특수 기호
<p>입력 받은 이름 : [[${param.inputName}]]</p>
[(${str})]
⇒ 서버 실행 안됨 ⇒ 문제 해결하기
링크(url) 조합에 사용되는 Spring EL (@{})
<a href="/board?key=제목&query=검색어">게시판(/board)</a>
// 위 형태를 다음과 같이 작성해준다
=>
<a th:href="@{/board(key=${key}, query=${query})}">게시판(/board)</a>
타임리프를 이용한 요청 주소 작성법
<a th:href="@{/example/ex3/{number}(number=${boardNo})}">
/example/ex3/10</a>

⇒ PathVariable : 주소 중 일부분을 변수값처럼 사용
<li><a href="/example/ex3/1">/example/ex3/1</a></li>
<li><a href="/example/ex3/2">/example/ex3/2</a></li>
<li><a href="/example/ex3/3">/example/ex3/3</a></li>
@GetMapping("ex3/{path}")
public String pathVariableTest(@PathVariable("path") int path) {
// controller에서 해야하는 로직이 동일한 경우에
// example/ex3/1, example/ex3/2, example/ex3/3 ...
// 주소 중 {path} 부분의 값을 가져와서 매개변수로 저장
// 이 매개변수 값을 controller 단의 메서드에서
// 사용할 수 있도록 해줌 (이 값을 Service -> DAO -> DB)
// + Request scope에 자동 세팅됨
// 변수명=값 => 변수명은 {변수명}이 변수명이 됨
// 즉, forward한 view에서 path를 사용할 수 있다는 의미
return "example/testResult";
}
th:if=${조건식}
- 조건식이 true인 경우에만 해당 속성이 작성된 요소를
화면에 출력
th:unless=${조건식}
- 조건식이 false인 경우에만 해당 속성이 작성된 요소를
화면에 출력
<h3 th:if="${std}">std 있음!!!</h3>
<h3 th:unless="${std}">std 없음!!!</h3>
타임리프 조건문 [2] - th:switch / th:case
<th:block th:switch="${num}">
<h3 th:case="100">100 이다</h3>
<h3 th:case="200">200 이다</h3>
<h3 th:case="300">300 이다</h3>
<!-- th:case="*" == default는 나머지의 경우와 같다 -->
<h3 th:case="*">나머지...</h3>
</th:block>
- 타임리프 속성 (th:)에
삼항 연산자(조건식 ? 참 : 거짓) 작성 가능
[작성법]
값 ?: 값이 없을 때
- 삼항 연산자에서 조건식 자리에 값(변수)만 작성
( == , != 등의 연산자 사용 X)
- 왼쪽 값이 존재하면 해당 값을 출력, 없으면 오른쪽 값이 출력
- 왼쪽 값이 없을 경우 타임리프 코드를 해석하지 않는 연산자에서
- 타임리프 코드 해석 X
-> 일반 HTML 태그로 동작
-> HTML 태그 사이 내용이 화면에 출력
- script 태그에 작성하는 속성
- 타임리프 문법으로 출력된 내용/값을 JS에 알맞은 타입으로 변환
<h4 class="deco" th:classappend="${num1 gt 10000} ? green : red">
th:classappend 테스트 중...
</h4>

객체가 null인지 판단 후, null이 아닌 경우에 수행하는 것
<h4 th:text="${member?.memberNo}">회원번호</h4>
- 시작 부터 끝 까지 번호로만 이루어진 숫자 배열 생성
ex) ${#numbers.sequence(1, 5)} => [1, 2, 3, 4, 5]
[왜 사용할까?]
- 타임리프 반복문 th:each는 향상된 for문 형태로
일반 for문의 동작(시작~끝까지 몇 씩 증가하면 반복)을 못하기 때문에
이를 해결하기 위해서 사용
<li th:each="i : ${#numbers.sequence(11, 20, 2)}" th:text="|테스트 ${i}|">
테스트 번호
</li>
<!-- fragment : 조각
html 요소를 다른 html 파일에서 재사용 가능하게 함
-->
<div th:fragment="header">
<ul>
<li>공지사항</li>
<li>자유게시판</li>
<li>질문게시판</li>
<li>FAQ</li>
<li>1:1문의</li>
</ul>
</div>
<th:block th:replace="~{fragments/header::header}"></th:block>
<div th:fragment="footer1">
<ul>
<li>고객센터</li>
<li>오시는길</li>
<li>이용약관</li>
</ul>
</div>
<h1 th:fragment="footer2">타임리프 fragment 확인 중</h1>
<th:block th:replace="~{fragments/header}"></th:block>
<th:block th:replace="~{fragments/footer :: footer2}"></th:block>



⇒ STS4는 XML 파일 생성 마법사가 없기 때문에 MarketPlace를 이용해서
Eclipse XML Editors and Tools 설치 필요!!


(아래 내용을 차례대로 추가)
⇒ src/main/resources’폴더에 mybatis-config.xml 파일 생성


<?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>
<!-- Java -> DB로 INSERT,UPDATE 시 Java의 null 값을 DB의 NULL로 인식하도록 설정 -->
<setting name="jdbcTypeForNull" value="NULL" />
<!-- DB의 UnderScore (_) 표기법 <-> Java의 Camel 표기법 두 표기법이 서로 변환 될 수 있도록 매핑하여
Java 필드명(memberId)과 DB 컬럼명(MEMBER_ID)가 서로 연결되게 함 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
</configuration>
⇒ 위 내용을 mybatis-config.xml 내부에 작성하기





⇒ src/main/resources에 만들기

Download~ 체크하고 apply하기
#오라클 DB 연결 정보
spring.datasource.hikari.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.hikari.jdbc-url=jdbc:oracle:thin:@IP주소:포트번호:DB이름
09_DB 연결하기 4
spring.datasource.hikari.username=계정명
spring.datasource.hikari.password=비밀번호
# HikariCP Connection Pool Properties
#풀이 연결을 사용할 수 있을 때까지 대기하는 최대 시간(ms)을 지정
spring.datasource.hikari.connection-timeout=30000
#풀의 최대 연결 수 설정
spring.datasource.hikari.maximum-pool-size=5
#연결이 풀에서 유휴 상태로 있을 수 있는 최대 시간(ms)을 지정
spring.datasource.hikari.idle-timeout=600000
#연결 풀의 이름을 지정
spring.datasource.hikari.pool-name=MyHikariCP
#자동 커밋 끄기
spring.datasource.hikari.auto-commit=false
⇒ 클래스를 만들어준다

package edu.kh.todo.common.config;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
/*
* @Configuration
* - 스프링 설정용 클래스임을 명시 (스프링이 해당 클래스 설정 정보로 인식하고 사용)
* + 객체로 생성해서 내부 코드를 서버 실행 시 모두 바로 실행
*
* @PropertySource : properties 파일의 내용을 이용하겠다는 어노테이션
* 다른 properties도 추가하고 싶으면 어노테이션을 계속 추가
* */
@Configuration
//@PropertySource : properties 파일의 내용을 이용하겠다는 어노테이션
//다른 properties도 추가하고 싶으면 어노테이션을 계속 추가
@PropertySource("classpath:/config.properties")
// classpath : src/main/resources
public class DBConfig {
// 필드
@Autowired // (DI, 의존성 주입)
private ApplicationContext applicationContext;
// application scope 객체 : 즉, 현재 프로젝트 그 자체를 나타내는 객체
// -> 현재 프로젝트의 전반적인 DB 설정과, Bean 관리에 접근할 수 있도록 해주는 객체
// -> 스프링이 관리하고 있는 ApplicationContext 객체를 의존성 주입받는다.
// @Bean
// - 개발자가 수동으로 bean을 등록하는 어노테이션
// - @Bean 어노테이션이 작성된 메서드에서 반환된 객체는
// Spring Container가 관리함(IOC)
// 메서드
////////////////////////////// HikariCP 설정 //////////////////////////////
@Bean
// @ConfigurationProperties(prefix = "spring.datasource.hikari")
// properties 파일의 내용을 이용해서 생성되는 bean을 설정하는 어노테이션
// prefix를 지정하여 spring.datasource.hikari으로 시작하는 설정을 모두 적용
@ConfigurationProperties(prefix = "spring.datasource.hikari")
// hikariConfig에 모두 접두사에 해당하는 것들을 적용시키겠다는 의미
public HikariConfig hikariConfig() {
// -> config.properties 파일에서 읽어온
// spring.datasource.hikari로 시작하는 모든 값이
// 자동으로 HikariConfig라는 객체의 알맞은 필드에 세팅이 되어
// 객체화 됨 -> Bean으로 등록까지
return new HikariConfig();
}
@Bean
public DataSource dataSource(HikariConfig config) {
// 매개변수 HikariConfig config
// -> 등록된 Bean 중 HikariConfig 타입의 Bean을 바인딩
// -> DataSource 객체를 생성하는데 이용된다.
DataSource dataSource = new HikariDataSource(config);
// DataSource :
// 애플리케이션이 데이터베이스에 연결할 때 사용하는 설정 객체임
// 1) DB 연결 정보 제공(url, username, password)
// 2) Connection pool 관리 (Connection 생성/생명주기 관리)
// 3) 트랜잭션 관리
return dataSource;
}
//////////////////////////// Mybatis 설정 추가 ////////////////////////////
// Mybatis : Java 애플리케이션에서 SQL을 더 쉽게 사용할 수 있도록 도와주는
// 영속성 프레임워크(Persistence Framework)는 애플리케이션의 데이터를
// 데이터베이스와 같은 저장소에 영구적으로 저장하고,
// 이를 쉽게 CRUD 할 수 있도록 도와주는 프레임워크
//SqlSessionFactory : SqlSession을 만드는 객체
@Bean
public SqlSessionFactory sessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
// 세팅1. 매퍼 파일이 모여있는 경로 지정
sessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:/mappers/**.xml"));
// 세팅2. 별칭을 지정해야하는 DTO가 모여있는 패키지 지정
// -> 해당 패키지에 있는 모든 클래스가 클래스명으로 별칭이 지정됨
sessionFactoryBean.setTypeAliasesPackage("edu.kh.todo");
// -> edu.kh.todo 세팅시 패키지 하위에 있는 모든 클래스가
// 클래스명으로 별칭이 지정됨.
// -> ex) edu.kh.todo.model.dto.Todo 클래스가 있다면 -> Todo가 별칭으로 등록됌
// 세팅3. 마이바티스 설정 파일 경로 지정
sessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis-config.xml"));
// SqlSession 객체 반환
return sessionFactoryBean.getObject();
}
// SqlSessionTemplate : 기본 SQL 실행 + 트랜잭션 처리
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sessionFactory) {
return new SqlSessionTemplate(sessionFactory);
}
// DataSourceTransactionManager : 트랜잭션 매니저
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}