JdbcTemplate, Mapper 이용
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
package com.example.demo.JdbcTemplate;
import java.util.Objects;
public class Customer {
private long id;
private String name;
private String email;
public Customer(String name, String email) {
this.name = name;
this.email = email;
}
public Customer(long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id &&
Objects.equals(name, customer.name) &&
Objects.equals(email, customer.email);
}
@Override
public int hashCode() {
return Objects.hash(id, name, email);
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
package com.example.demo.JdbcTemplate;
import java.util.List;
public interface CustomerRepository {
List<Customer> findAll();
Customer findById(long id);
Customer save(Customer customer);
}
package com.example.demo.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
// JdbcTemplate과 RowMapper(람다 표현식을 사용)를 사용
@Repository
public class JdbcCustomerRepository implements CustomerRepository {
private static final String ALL_QUERY = "select id, name, email from customer";
private static final String BY_ID_QUERY = "select id, name, email from customer where id = ?";
private static final String INSERT_QUERY = "insert into customer (name, email) values(?,?)";
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@PostConstruct
private void postConstruct() {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public List<Customer> findAll() {
return jdbcTemplate.query(ALL_QUERY, (rs, rowNum) -> toCustomer(rs));
}
@Override
public Customer findById(long id) {
return jdbcTemplate.queryForObject(BY_ID_QUERY, (rs, rowNum) -> toCustomer(rs), id);
}
@Override
public Customer save(Customer customer) {
var keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(INSERT_QUERY, new String[]{"ID"});
ps.setString(1, customer.getName());
ps.setString(2, customer.getEmail());
return ps;
},keyHolder);
//return keyHolder.getKey().longValue();
return new Customer(keyHolder.getKey().longValue(), customer.getName(), customer.getEmail());
}
private Customer toCustomer(ResultSet rs) throws SQLException{
var id = rs.getLong(1);
var name = rs.getString(2);
var email = rs.getString(3);
return new Customer(id, name, email);
}
}
package com.example.demo.JdbcTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class JdbcTemplateRun implements ApplicationRunner {
private final CustomerRepository customerRepository;
public JdbcTemplateRun(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@Override
public void run(ApplicationArguments args) throws Exception {
customerRepository.findAll().forEach(customer -> {log.info("{}",customer);});
Customer customer = customerRepository.save(new Customer("123","456@naver.com"));
log.info("{}",customer.toString());
}
}
테스트 클래스
package com.example.demo;
import com.example.demo.JdbcTemplate.Customer;
import com.example.demo.JdbcTemplate.CustomerRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class JdbcCustomerRespositoryTest {
@Autowired
private CustomerRepository customerRepository;
@Test
public void insertNewCustomer(){
assertThat(customerRepository.findAll().isEmpty());
Customer customer = customerRepository.save(new Customer( "T. Testing", "t.testing@test123.tst"));
assertThat(customer.getId()).isGreaterThan(-1L);
assertThat(customer.getName()).isEqualTo("T. Testing");
assertThat(customer.getEmail()).isEqualTo("t.testing@test123.tst");
assertThat(customerRepository.findById(customer.getId())).isEqualTo(customer);
}
}
JPA
#spring.jpa.database= JPA를 적용할 대상데이터베이스, 기본값 자동탐지
#spring.jpa.database-platform= JPA를 적용할 데이터베이스 이름, 기본값 자동탐지
#spring.jpa.generate-ddl= 시작시 스키마를 초기화할것인지 여부, 기본값 false
spring.jpa.show-sql=true
#SQL구문을 로그에 표시할 것인지 여부, 기본값 fasle
#spring.jpa.open-in-view= OpenEntityManagerInViewInterceptor를 등록할지 여부, EntityManager를 요청 처리 스레드에 바인딩, 기본값 true
#spring.jpa.hibernate.ddl-auto= hibernate.hbm2ddl.auto 속성을 설정, 기본값 none, 내장 데이터베이스인 경우 create-drop으로 설정
#spring.jpa.hibernate.use-new-id-generator-mappings= hibernate.id.new_generator_mappings 속성을 설정, 명시적으로 설정되지 않은 경우 기본값 true
#spring.jpa.hibernate.naming.implicit-strategy= 논리적인 네이밍 룰을 처리하는 전략 클래스의 전체 경로, 기본값 org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
#spring.jpa.hibernate.naming.physical-strategy= 물리적인 네이밍 룰을 처리하는 전략 클래스의 전체경로, 기본값 org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
#spring.jpa.mapping-resources= 자바 클래스 대신 XML 형식의 엔티티 매핑 파일을 지정, JPA가 정의된 orm.xml 같은 파일을 말한다
#spring.jpa.properties.*= JPA 제공자 관련 설정 항목을 추가
# ex) spring.jpa.properties.hibernate.jdb.fetch_size = 250
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
spring.jpa.show-sql=true
#SQL구문을 로그에 표시할 것인지 여부, 기본값 fasle
logging.level.org.hibernate.type=trace
# 바인딩값까지 표현하는방법
package com.example.demo.JdbcTemplate;
import lombok.Builder;
import javax.persistence.*;
import java.util.Objects;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String email;
public Customer() {
// this(null,null);
this.builder().name(null).email(null).build();
}
@Builder
public Customer(String name, String email) {
this.name = name;
this.email = email;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id &&
Objects.equals(name, customer.name) &&
Objects.equals(email, customer.email);
}
@Override
public int hashCode() {
return Objects.hash(id, name, email);
}
}
package com.example.demo.JdbcTemplate;
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
Customer findByName(String name);
}
package com.example.demo.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
// Jpa
public class JpaCustomerRepository {
@Autowired
private CustomerRepository customerRepository;
public List<Customer> findAll() {
return (List<Customer>) customerRepository.findAll();
}
public Customer findById(String name) {
return customerRepository.findByName(name);
}
public Customer save(Customer customer) {
customerRepository.save(customer);
return customer;
}
}
package com.example.demo.JdbcTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class JpaRun implements ApplicationRunner {
private final CustomerRepository customerRepository;
public JpaRun(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@Override
public void run(ApplicationArguments args) throws Exception {
customerRepository.findAll().forEach(customer -> {log.info("{}",customer);});
customerRepository.findByName("John Doe").toString();
customerRepository.save(Customer.builder().name("123").email("456@naver.com").build()).toString();
}
}
package com.example.demo;
import com.example.demo.JdbcTemplate.Customer;
import com.example.demo.JdbcTemplate.CustomerRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class JpaCustomerRespositoryTest {
@Autowired
private CustomerRepository customerRepository;
@Test
public void insertNewCustomer(){
List<Customer> customerFindall = (List<Customer>) customerRepository.findAll();
assertThat(customerFindall).isNotNull();
Customer customerSave = customerRepository.save(new Customer( "T. Testing", "t.testing@test123.tst"));
assertThat(customerSave.getId()).isGreaterThan(-1L);
assertThat(customerSave.getName()).isEqualTo("T. Testing");
assertThat(customerSave.getEmail()).isEqualTo("t.testing@test123.tst");
assertThat(customerRepository.findByName(customerSave.getName())).isEqualTo(customerSave);
}
}
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 | :: Spring Boot :: (v2.2.4.RELEASE) ... Hibernate: select customer0_.id as id1_0_, customer0_.email as email2_0_, customer0_.name as name3_0_ from customer customer0_ 2020-02-14 17:38:50.615 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [1] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([email2_0_] : [VARCHAR]) - [marten.deinum@conspect.nl] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name3_0_] : [VARCHAR]) - [Marten Deinum] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [2] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([email2_0_] : [VARCHAR]) - [jlong@pivotal.com] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name3_0_] : [VARCHAR]) - [Josh Long] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [3] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([email2_0_] : [VARCHAR]) - [John.doe@island.io] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name3_0_] : [VARCHAR]) - [John Doe] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [4] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([email2_0_] : [VARCHAR]) - [jane.doe@island.io] 2020-02-14 17:38:50.616 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name3_0_] : [VARCHAR]) - [Jane Doe] 2020-02-14 17:38:50.619 INFO 13700 --- [ restartedMain] com.example.demo.JdbcTemplate.JpaRun : Customer{id=1, name='Marten Deinum', email='marten.deinum@conspect.nl'} 2020-02-14 17:38:50.620 INFO 13700 --- [ restartedMain] com.example.demo.JdbcTemplate.JpaRun : Customer{id=2, name='Josh Long', email='jlong@pivotal.com'} 2020-02-14 17:38:50.620 INFO 13700 --- [ restartedMain] com.example.demo.JdbcTemplate.JpaRun : Customer{id=3, name='John Doe', email='John.doe@island.io'} 2020-02-14 17:38:50.620 INFO 13700 --- [ restartedMain] com.example.demo.JdbcTemplate.JpaRun : Customer{id=4, name='Jane Doe', email='jane.doe@island.io'} Hibernate: select customer0_.id as id1_0_, customer0_.email as email2_0_, customer0_.name as name3_0_ from customer customer0_ where customer0_.name=? 2020-02-14 17:38:50.636 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [John Doe] 2020-02-14 17:38:50.637 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([id1_0_] : [BIGINT]) - [3] 2020-02-14 17:38:50.637 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([email2_0_] : [VARCHAR]) - [John.doe@island.io] 2020-02-14 17:38:50.638 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name3_0_] : [VARCHAR]) - [John Doe] Hibernate: insert into customer (email, name) values (?, ?) 2020-02-14 17:38:50.642 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [456@naver.com] 2020-02-14 17:38:50.642 TRACE 13700 --- [ restartedMain] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [123] 2020-02-14 17:38:50.798 INFO 13700 --- [ restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged | cs |
1) 도메인에 hashcode와 equlas를 안넣으면 아래와같은 에러뜸
1 2 3 4 5 6 7 8 | org.opentest4j.AssertionFailedError: Expecting: <"Customer{id=6, name='T. Testing', email='t.testing@test123.tst'} (Customer@43c20142)"> to be equal to: <"Customer{id=6, name='T. Testing', email='t.testing@test123.tst'} (Customer@229c4d34)"> but was not. Expected :Customer{id=6, name='T. Testing', email='t.testing@test123.tst'} Actual :Customer{id=6, name='T. Testing', email='t.testing@test123.tst'} | cs |
TestEntityManagerTest : http://wonwoo.ml/index.php/post/1926
Unable to Find @SpringBootConfiguration with @DataJpaTest : https://www.baeldung.com/spring-boot-unable-to-find-springbootconfiguration-with-datajpatest
Testing in Spring Boot : https://www.baeldung.com/spring-boot-testing
pring Data JPA and Null Parameters : https://www.baeldung.com/spring-data-jpa-null-parameters
메모리데이터베이스를 제외하는 방법 : https://stackoverflow.com/questions/46154146/how-to-integration-test-repository-in-spring-boot
package com.example.demo;
import com.example.demo.JdbcTemplate.Customer;
import com.example.demo.JdbcTemplate.CustomerRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class TestEntityManagerTest {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private TestEntityManager testEntityManager;
@Test
@DisplayName("findAllCustomer")
public void findAllCustomer(){
Customer customer = Customer.builder().name("123").email("456@naver.com").build();
Customer customerSave = testEntityManager.persist(customer);
testEntityManager.flush();
assertThat(customerRepository.findAll()).hasSize(5);
assertThat(customerSave.getName()).isEqualTo("123");
assertThat(customerSave.getEmail()).isEqualTo("456@naver.com");
assertThat(customerRepository.findByName(customerSave.getName())).isEqualTo(customerSave);
}
}
SessionFactory
https://www.baeldung.com/hibernate-4-spring
https://www.theserverside.com/tip/How-to-get-the-Hibernate-Session-from-the-JPA-20-EntityManager
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
#SQL구문을 로그에 표시할 것인지 여부, 기본값 fasle
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
logging.level.org.hibernate.type=trace
# 바인딩값까지 표현하는방법
package com.example.demo.JdbcTemplate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.transaction.Transactional;
import java.util.List;
// Jpa
@Transactional
public class JpaCustomerRepository {
@Autowired
SessionFactory sessionFactory;
protected Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
public List<Customer> findAll() {
return getCurrentSession().createQuery("SELECT c FROM Customer c", Customer.class).getResultList();
}
public Customer findById(String name) {
return getCurrentSession().find(Customer.class,name);
}
public Customer save(Customer customer) {
getCurrentSession().persist(customer);
return customer;
}
}
반응형
'WEB > 스프링 부트 2' 카테고리의 다른 글
JMS, ActiveMQ (0) | 2020.02.15 |
---|---|
JavaMail (0) | 2020.02.14 |
MySQL 연결 / 스프링 schema.sql, data.sql / Flyway (0) | 2020.02.13 |
내장데이터베이스 Derby (0) | 2020.02.13 |
Spring Security Method SpEL (0) | 2020.02.13 |