Spring JDBC 사용
namedParameterJdbcTemplate
MySQL 연동하기
처음엔 Mybatis 를 사용하려고 했는데, jdbcTemplate 을 사용하려고 합니다.
이유는 여기 참고 하시고요~
이전에 추가했던 mybatis dependency를 빼야겠네요.
implementation 'org.springframework.boot:spring-boot-starter-jdbc' 추가
gradle refresh
1. DataBase 준비
테스트할 db가 없다면
https://dev.mysql.com/doc/index-other.html
위 사이트에서 Example Databases 중에 하나를 다운로드 받습니다.
다운로드 후 압축을 풀면 world.sql 파일이 있습니다.
스크립트 파일을 열어보면 world 라는 이름으로 database 를 생성하고 데이터를 입력하는 쿼리가 있습니다.
Workbench 등 mysql 쿼리를 실행할 수 있는 환경에서 실행합니다.
스키마가 생성되었네요.
db 접속 정보는 src/main/resources/application.yml 에 설정합니다.
2. model 생성
city table 이 컬럼수가 적고 테스트 하기 좋을거 같으니 city 테이블의 모델을 생성합니다.
경로는 com.bryan.hello.preword.info.model
City.java
package com.bryan.hello.preword.info.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class City {
private Integer id;
private String name;
private String countryCode;
private String district;
private Integer population;
}
3. Repository 생성
경로는 com.bryan.hello.preword.info.repository
CityRepository.java
package com.bryan.hello.preword.info.repository;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import com.bryan.hello.preword.info.model.City;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Repository
public class CityRepository {
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public CityRepository(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
public List<City> findList(){
String sql = "select * from city limit 1000";
log.debug("query : {}", sql);
RowMapper<City> cityMapper = (rs, rowNum) -> {
City city = new City();
city.setId(rs.getInt("ID"));
city.setName(rs.getString("Name"));
city.setCountryCode(rs.getString("contrycode"));
city.setDistrict(rs.getString("district"));
city.setPopulation(rs.getInt("population"));
return city;
};
return namedParameterJdbcTemplate.query(sql, new MapSqlParameterSource(), cityMapper);
}
}
여기서 미리 코드 정리 좀 해야겠습니다.
쿼리 부분
지금 쿼리는 너무 간단하지만, 좀 더 길어지고, 소스에서 비슷한 쿼리를 여기저기에서 사용할수도 있습니다.
그럼 관리하기가 힘들어지겠죠.
class 를 만들어서 Groovy 의 Multiline String 으로 선언합니다.
Goorvy 를 사용하기 위해서 build.gradle 의 plugins 와 dependencies 에 추가를 합니다.
plugins {
id 'org.springframework.boot' version '2.5.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'groovy' // 여기 추가
}
dependencies {
implementation('org.codehaus.groovy:groovy') // groovy 추가
}
이클립스에서 groovy script 를 작성하기 위해서 plugin 을 설치합니다.
설치 중에 logback m2e 때문에 확인 창이 나오는데, logback m2e 는 uninstall 되고 groovy m2e 가 설치되도록 update 에 체크하시면 됩니다. 이클립스 재시작 후 logback 은 다시 설치하겠냐고 물어보는데, 그때 다시 설치하면 됩니다.
4. SQL 관리 - Groovy 파일 생성
같은 repository package 아래에 sql 관련 groovy file 을 생성합니다.
CitySql.groovy
package com.bryan.hello.preword.info.repository;
class CitySql{
public static final String SELECT = """
SELECT ID, Name, CountryCode, District, Population FROM city LIMIT 1000;
""";
}
5. RowMapper 생성
그리고 RowMapper 도 공통적으로 사용할것 이므로 MapperClass 로 생성합니다.
RowMapper<City> cityMapper = (rs, rowNum) -> {
City city = new City();
city.setId(rs.getInt("ID"));
city.setName(rs.getString("Name"));
city.setCountryCode(rs.getString("contrycode"));
city.setDistrict(rs.getString("district"));
city.setPopulation(rs.getInt("population"));
return city;
};
CityRepository.java 에 있던 이 부분,
경로는 위와 같은 Repository package 안에
파일명은 CityRowMapper.java
package com.bryan.hello.preword.info.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.bryan.hello.preword.info.model.City;
public class CityRowMapper implements RowMapper<City> {
@Override
public City mapRow(ResultSet rs, int rowNum) throws SQLException {
City city = new City();
city.setId(rs.getInt("ID"));
city.setName(rs.getString("Name"));
city.setCountryCode(rs.getString("countrycode"));
city.setDistrict(rs.getString("district"));
city.setPopulation(rs.getInt("population"));
return city;
}
}
CityRepository.java 는 아래와 같이 바뀌겠네요.
package com.bryan.hello.preword.info.repository;
import java.util.List;
import org.springframework.jdbc.core.namedparam.EmptySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import com.bryan.hello.preword.info.model.City;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Repository
public class CityRepository {
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final CityRowMapper cityRowMapper;
public CityRepository(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
this.cityRowMapper = new CityRowMapper();
}
public List<City> findList(){
log.debug("findList query = {}", CitySql.SELECT);
return namedParameterJdbcTemplate.query(CitySql.SELECT
, EmptySqlParameterSource.INSTANCE
, this.cityRowMapper);
}
}
- 쿼리에 파라메터를 넘길 필요가 없으므로 EmptySqlParameterSource.INSTANCE 를 던집니다.
- 조회된 데이터의 한줄한줄을 cityRowMapper 를 통해 맵핑해 줍니다.
6. Service 에서 Repository 사용
이제 Service 에서 Repository 를 이용해 데이터를 조회해 보겠습니다.
InfoService.java 에서 repository 객체 선언하고, 생성자 주입을 한 다음에 getCityList() 를 사용하여 호출.
package com.bryan.hello.preword.info;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Service;
import com.bryan.hello.preword.info.model.Project;
import com.bryan.hello.preword.info.model.City;
import com.bryan.hello.preword.info.repository.CityRepository;
@Service
public class InfoService {
private final CityRepository cityRepository;
// spring 4.2 이상은 @Autowired 생략 가능
public InfoService(CityRepository cityRepository) {
this.cityRepository = cityRepository;
}
public Project getProjectInfo() {
Project project = new Project();
project.projectName = "preword";
project.author = "hello-bryan";
project.createdDate = new Date();
return project;
}
public List<City> getCityList() {
return this.cityRepository.findList();
}
}
마지막으로 Controller 에 service 호출 하는 부분을 추가합니다.
InfoController.java
@GetMapping("/cityList")
public Object cityList() {
log.debug("/cityList start");
List<City> cityList = infoService.getCityList();
return cityList;
}
실행
Spring Boot 서버 실행.
브라우저에서 localhost:8000/cityList 입력
Select 성공.
현재까지 파일 구조
다음에는 insert / update / delete 등을 만들어보겠습니다.
To Be Continue..
Spring Boot Tutorial 시리즈
- 2021.07.03 - [Java] - [SpringBoot] RestApi 만들기 (1) 프로젝트 생성
- 2021.07.03 - [Java] - [SpringBoot] RestApi 만들기 (2) JSON 형식 리턴
- 2021.07.04 - [Java] - [SpringBoot] RestApi 만들기 (3) Log (slf4j+logback)
- 2021.07.04 - [Java] - [SpringBoot] RestApi 만들기 (4) Service 생성 (의존성 주입)
- 2021.07.04 - [Java] - [SpringBoot] RestApi 만들기 (5.1) MySQL + JDBC Template. 1
- 2021.07.05 - [Java] - [SpringBoot] RestApi 만들기 (5.2) DBCP - HikariCP
- 2021.07.08 - [java] - [SpringBoot] RestApi 만들기 (5.3) jdbcTemplate - Select
- 2021.07.10 - [Java] - [SpringBoot] RestApi 만들기 (5.4) GetMapping, PostMapping
- 2021.07.10 - [Java] - [SpringBoot] RestApi 만들기 (5.5) jdbcTemplate - Insert, Update, Delete
- 2021.07.11 - [Java] - [SpringBoot] RestApi 만들기 (6) File Upload / Download / List
Spring Boot Tutorial 부록
- 2021.07.02 - [Java] - [eclipse] 이클립스 설치, STS(Spring Tools 4) 설치
- 2021.07.04 - [Java] - [SpringBoot] MyBatis 보다 Spring JDBC 를 사용해야 하는 이유
- 2021.06.19 - [Java] - [Spring-boot] 시작하기 전 알아야 할 것들
- 2021.06.19 - [Java] - [Spring-boot] 수동으로 설정 초기화
- 2021.07.04 - [Java] - Eclipse 에 groovy 설치 하기
- 2021.07.02 - [Java] - [eclipse] 이클립스 설치, STS(Spring Tools 4) 설치
- 2021.07.07 - [Java] - [SpringBoot] Controller 에 Route 적용 (RequestMapping)
'Java' 카테고리의 다른 글
[SpringBoot] Controller 에 Route 적용 (RequestMapping) (0) | 2021.07.07 |
---|---|
[SpringBoot] RestApi 만들기 (5.2) DBCP - HikariCP (0) | 2021.07.05 |
Eclipse 에 groovy 설치 하기 (0) | 2021.07.04 |
[SpringBoot] MyBatis 보다 Spring JDBC 를 사용해야 하는 이유 (0) | 2021.07.04 |
[SpringBoot] RestApi 만들기 (4) Service 생성 (의존성 주입) (4) | 2021.07.04 |
댓글