일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 우테코
- JPA
- 자바
- CircuitBreaker
- 서블릿
- Spring Batch
- 의존성
- MSA
- 우아한테크코스
- 프로그래머스
- 프리코스
- HTTP
- yml
- 우아한세미나
- 코드리뷰
- mock
- 미션
- AWS
- REDIS
- 스프링 부트
- AOP
- 세션
- 백준
- Level2
- Paging
- 트랜잭션
- 레벨2
- Docker
- 스프링부트
- JUnit5
Archives
- Today
- Total
늘
[Spring] JDBC 와 JDBC Template 이용해보기 본문
728x90
JPA만 사용하다가 오랜만에 JDBC를 공부해보려고 한다. 어느 정도 JDBC의 작동원리를 알아야 나중에 JPA를 더 깊이 공부할 때도 도움이 될 것 같다고 생각되기 때문이다. 기본적인 사용법을 알아두면 나중에 쓰일 수(?)도 있으니...
JDBC는 JPA와 다르게 db에 날리는 쿼리를 직접 작성해야하는 단점이 있다. 대신 복잡한 쿼리를 작성할때는 직접 쿼리를 작성하므로 jpa보다 좋다.
JDBC
package com.example.demo.controller;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@RequestMapping(value="step1", method = RequestMethod.GET)
public List<SailorsDto> getSailorss() throws SQLException
{
List<SailorsDto> sailorsInfoList = new ArrayList<>();
try(Connection conn = DriverManager.getConnection("jdbc:mariadb://localhost:3306/jdbc", "giron", "pass")){
try(Statement stmt = conn.createStatement()){
try(ResultSet rs = stmt.executeQuery("SELECT S.rating, AVG(S.age) AS average\n"
+ "FROM Sailors S\n"
+ "WHERE S.age >= 18\n"
+ "GROUP BY S.rating\n"
+ "HAVING 1<(SELECT COUNT(*)\n"
+ "FROM Sailors S2\n"
+ "WHERE S.rating = S2.rating);")){
while(rs.next()) {
String rating = rs.getString("rating");
String average = rs.getString("average");
sailorsInfoList.add(new SailorsDto(Integer.parseInt(rating), Double.parseDouble(average)));
}
}
}
}
return sailorsInfoList;
}
}
마리아디비 커넥터를 사용해 localhost:3306번 포트를 통해 접근하고 jdbc라는 데이터베이스에 접근한다. giron과 pass는 데이터베이스 아이디와 비밀번호이다!
Saliros Dto
package com.example.demo.controller;
public class SailorsDto {
public Integer rating;
public Double age;
public SailorsDto() {
}
public SailorsDto(Integer rating, Double age) {
super();
this.rating = rating;
this.age = age;
}
@Override
public String toString() {
return "Sailors [rating=" + rating + ", age=" + age + "]";
}
}
마리아디비 jdbc connector를 이용하여 db로부터 쿼리를 날릴 수 있다.
이번엔 JDBC template을 이용하여 더욱 간편하게 코드를 작성해보겠다.
JDBC Template
[User Entity]
@Getter
@Setter
public class User {
private Long id;
private String name;
}
[UserRepository]
public interface UserRepository {
User save(User user);
Optional<User> findById(Long id);
Optional<User> findByName(String name);
List<User> findAll();
}
[JdbcTemplateUserRepository]
public class JdbcTemplateUserRepository implements UserRepository {
private final JdbcTemplate jdbcTemplate;
@Autowired
public JdbcTemplateUserRepository(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public User save(User user) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("user").usingGeneratedKeyColumns("id"); //파라미터 바인딩
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", user.getName()); // 실행 & db 에서 생성된 key 받아오기
Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
user.setId(key.longValue());
return user;
}
@Override
public Optional<User> findById(Long id) {
List<User> result = jdbcTemplate.query("select * from user where id = ?", userRowMapper(), id);
return result.stream().findAny();
}
@Override
public Optional<User> findByName(String name) {
List<User> result = jdbcTemplate.query("select * from user where id= ?", userRowMapper(), name);
return result.stream().findAny();
}
@Override
public List<User> findAll() {
return jdbcTemplate.query("select * from user", userRowMapper());
}
private RowMapper<User> userRowMapper() {
return (res, rowNum) -> {
User user = new User();
user.setId(res.getLong("id"));
user.setName(res.getString("name"));
return user;
};
}
}
기본 Config
@Configuration
public class SpringConfig {
private final DataSource dataSource;
public SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public UserService userService() {
return new UserService(userRepository());
}
//Bean 주입
@Bean
public UserRepository userRepository() {
return new JdbcTemplateUserRepository(dataSource);
}
}
기본적인 사용법
jdbcTemplate.query("쿼리문", RowMapper<?>, 바인딩할 파라미터 값)
여기서 RowMapper는 결과값을 매핑하는 용도라고 보면 되고
바인딩할 파라미터는 순서대로 쿼리문의 ? 에 대응되어 값이 들어가게 된다.
Insert의 경우가 약간 특이한데
쿼리문을 따로 생성할 필요는 없고
SimpleJdbcInsert 를 생성하여 파라미터를 바인딩하여 사용하면 된다.
일반적으로는 jdbcTemplate.execute() 를 호출하면 쿼리가 날아간다.
Reference
728x90
'백앤드 개발일지 > 스프링부트' 카테고리의 다른 글
[Spring Batch] 배치 애플리케이션 경험하기 (0) | 2021.08.31 |
---|---|
[JPA] 자바 ORM 표준 JPA프로그래밍 읽고 정리 (0) | 2021.08.24 |
Servlet과 Controller(feat. Serializable) (0) | 2021.07.22 |
[JPA] 양방향 매핑 OneToOne Lazy 이슈 (0) | 2021.07.19 |
스프링 프레임워크 (0) | 2021.07.02 |
Comments