1. 프로젝트 구조 생성



- model 하위에 entity package를 생성하고 User 클래스를 만든다.

- repository package를 생성하고 하위에 UserRepository 인터페이스를 생성한다.

- test 패키지 하위에 repository package아래에 UserRepositoryTest라는 test클래스를 만든다.



2. user 테이블 생성


1
2
3
4
5
6
7
8
9
10
CREATE TABLE `test`.`user` (
  `id` BIGINT(20NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45NULL,
  `email` VARCHAR(45NULL DEFAULT NULL,
  `phone_number` VARCHAR(45NULL DEFAULT NULL,
  `reg_dt` VARCHAR(45NOT NULL,
  `reg_user` VARCHAR(45NOT NULL,
  `mod_dt` VARCHAR(45NULL DEFAULT NULL,
  `mod_user` VARCHAR(45NULL DEFAULT NULL,
  PRIMARY KEY (`id`));
cs


MySQL Tool (workbench, heidiSQL) 을 통해 test 데이터베이스에 user테이블을 생성한다.

생성할때 컬럼은 snake_case를 사용하여 각 단어와 단어 사이에  _언더바로 표시한다.



3. User 모델 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.test.model.entity;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.LocalDateTime;
 
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    private String phoneNumber;
    private LocalDateTime regDt;
    private String regUser;
    private LocalDateTime modDt;
    private String modUser;
}
cs



자바에선 user테이블의 컬럼명에 맞춰 

camel case를 사용하여 모델 User클래스를 만든다.



4. UserRepository 인터페이스 생성


1
2
3
4
5
6
7
8
9
10
package com.example.test.repository;
 
import com.example.test.model.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
 
@Repository
public interface UserRepository extends JpaRepository<User,Long> {
 
}
cs


JpaRepository를 상속받아 생성한다.



5. UserRepositoryTest 클래스 생성


5.1 create


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
package com.example.test.repository;
 
import com.example.test.TestApplicationTests;
import com.example.test.model.entity.User;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
 
import java.time.LocalDateTime;
 
public class UserRepositoryTest extends TestApplicationTests {
 
    @Autowired
    private UserRepository userRepository;
 
    @Test
    public void create(){
        User user = new User();
        user.setName("user1");
        user.setEmail("user1@gmail.com");
        user.setPhoneNumber("010-1111-2222");
        user.setRegDt(LocalDateTime.now());
        user.setRegUser("shlee0882");
 
        User newUser = userRepository.save(user);
        System.out.println(newUser);
    }
}
 
cs


User 모델을 객체로 가져와 값을 set하고 

DI (의존성주입)를 사용해 UserRepository로 만든 객체에 save한다.


Test를 실행하면 데이터가 잘 들어간것을 확인할 수 있다.




5.2 read


1
2
3
4
5
6
7
8
    @Test
    public void read(){
        Optional<User> user = userRepository.findById(1L);
 
        user.ifPresent(selectUser ->{
            System.out.println("user: "+selectUser);
        });
    }
cs


read 메소드를 run하면 

id는 모델에서 long으로 선언 되어 있으므로 L을 붙여 id가 1번인 데이터를 찾는다.

데이터를 찾아 user객체에 담아주고 출력한다.


출력결과


1
user: User(id=1, name=user1, email=user1@gmail.com, phoneNumber=010-1111-2222, regDt=2019-08-09T09:25:28.653, regUser=shlee0882, modDt=2019-08-09T09:27:51.381, modUser=shlee0882)
cs


5.3 update


1
2
3
4
5
6
7
8
9
10
11
12
13
    @Test
    public void update(){
        Optional<User> user = userRepository.findById(1L);
 
        user.ifPresent(selectUser ->{
            selectUser.setUserAccount("modUser1");
            selectUser.setEmail("modUser1@gmail.com");
            selectUser.setModDt(LocalDateTime.now());
            selectUser.setModUser("shlee0882");
            User newUser = userRepository.save(selectUser);
            System.out.println("user: "+newUser);
        });
    }
cs


update 메소드를 run하면

id가 1번인 데이터를 찾아 user객체에 담고

담은 user의 객체의 값을 새로 set해주고 save하면 

기존의 데이터가 있다면 update가 일어난다.


출력결과


1
user: User(id=1, name=modUser1, email=modUser1@gmail.com, phoneNumber=010-1111-2222, regDt=2019-08-09T09:25:28.653, regUser=shlee0882, modDt=2019-08-09T11:20:17.179, modUser=shlee0882)
cs


5.4 delete


1
2
3
4
5
6
7
8
9
10
11
12
13
    @Test
    public void delete(){
        Optional<User> user = userRepository.findById(1L);
 
        Assert.assertTrue(user.isPresent());    // true
        user.ifPresent(selectUser ->{
            userRepository.delete(selectUser);
        });
 
        Optional<User> deleteUser = userRepository.findById(1L);
 
        Assert.assertFalse(deleteUser.isPresent());    // false
    }
cs


delete메소드는 id를 찾아 있다면 true, 

데이터 삭제 후 id가 있는지 확인 후 없다면 false를 통과한다.



5.5 Transactional



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
    @Test
    @Transactional
    public void update(){
        Optional<User> user = userRepository.findById(1L);
 
        user.ifPresent(selectUser ->{
            selectUser.setName("modUser1");
            selectUser.setEmail("modUser1@gmail.com");
            selectUser.setModDt(LocalDateTime.now());
            selectUser.setModUser("shlee0882");
            User newUser = userRepository.save(selectUser);
            System.out.println("user: "+newUser);
        });
    }
 
    @Test
    @Transactional
    public void delete(){
        Optional<User> user = userRepository.findById(1L);
 
        Assert.assertTrue(user.isPresent());    // true
        user.ifPresent(selectUser ->{
            userRepository.delete(selectUser);
        });
 
        Optional<User> deleteUser = userRepository.findById(1L);
 
        Assert.assertFalse(deleteUser.isPresent());    // false
    }
cs


transactional 어노테이션을 넣으면

update와 delete 시 RollBack 되는것을 확인할 수 있다. 


1
Rolled back transaction for test: [DefaultTestContext@576dad90 testClass = UserRepositoryTest, testInstance = com.example.test.repository.UserRepositoryTest@97bd416, testMethod = delete@UserRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5baaa549 testClass = UserRepositoryTest, locations = '{}', classes = '{class com.example.test.TestApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@7097fbf1, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7ed6156f, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@2c5d456b, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6b04043b], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true]]
cs




+ Recent posts