IT/Spring

[안드로이드 앱 서버 만들기] 3. MariaDB와 연동 그리고 JPA로 CRUD 메소드 만들기

김 정 환 2021. 7. 6. 16:06
반응형
게시된 내용은 작성자가 공부한 내용을 정리하여 기록하였습니다. 일부 빠지거나 부족한 부분이 있을 수 있습니다. 최대한 편집 없이 기록하였습니다.

출처 블로그

 

 

사용 도구 : STS 4 (Spring Tools Suite), AWS EC2, MariaDB, Windows


1. 라이브러리 추가

DB 연동을 위한 라이브러리를 추가 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
dependencies {
 
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
 
   // DB 연동 라이브러리
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    compile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.4.0'
    compile group: 'com.zaxxer', name: 'HikariCP', version: '3.3.0'
 
}
cs

 

 

 


2. 설정 추가

application.yml에 설정을 추가 하겠습니다.

들여쓰기에 유의해 주세요.

아래 ec2주소rds-mariadb.ch4ipdxuds1.ap-northeast-2.rds.amazonaws.com 이런 식으로 생겼습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server:
  port: 3232
 
spring:
  data:
    maria:
      jdbc-url: jdbc:mariadb://[ec2주소]:3306/[DB이름]?useUnicode=yes&characterEncoding=UTF-8
      driver-class-name: org.mariadb.jdbc.Driver
      username: [유저이름]
      password: [비밀번호]
  jpa:
    properties:
      hibernate:
        #show_sql: true
        format_sql: true
        temp:
          use_jdbc_metadata_defaults: false
    generate-ddl: true
 
cs

 

 

DBConfig 파일을 생성하겠습니다. configuration 패키지를 만들고 DBConfig 파일을 생성합니다. 그리고 아래 코드를 작성합니다.

TODO 부분은 각자의 패키지에 맞게 수정해주세요.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
 
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
 
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = "com.example.demo.repository"// TODO Repository 패키지 지정
        transactionManagerRef = "mariaDB_transactionManager",
        entityManagerFactoryRef = "mariaDB_entityManagerFactory"
)
public class DBConfig {
    @Primary
    @Bean(name = "maria_dataSource")
    @ConfigurationProperties("spring.data.maria")
    public DataSource mariaDataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }
 
    @Primary
    @Bean(name = "mariaDB_entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("maria_dataSource") DataSource dataSource) {
        Map<StringString> map = new HashMap<>();
        map.put("hibernate.ejb.naming_strategy""org.hibernate.cfg.ImprovedNamingStrategy");
        map.put("hibernate.dialect""org.hibernate.dialect.MySQL5InnoDBDialect");
        return builder.dataSource(dataSource)
                .packages("com.example.demo.model"// TODO Model 패키지 지정
                .properties(map)
                .build();
    }
 
    @Primary
    @Bean(name = "mariaDB_transactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("mariaDB_entityManagerFactory") EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
 
}
 
cs

 

 

 


3. Repository 인터페이스 작성

기존 Member 객체에 애노테이션을 추가해서 테이블을 정의합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "member")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long id;
    private String name;
    private int age;
    private String address;
    @CreationTimestamp
    private Date createdAt;
 
    public Member(String name, int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
}
 
cs

 

 

MemberRepository 인터페이스를 만들겠습니다. JpaRepository를 상속받기 때문에 JpaRepository에 있는 기본적인 메소드는 그대로 사용할 수 있습니다. 여기에서 기본적인 메소드를 보실 수 있습니다.

 

 

 


4. 테스트

간단하게 Insert로 테스트해보겠습니다. MemberController에서 Insert 메소드를 작성해봅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/member")
@RestController
public class MemberController {
 
    @Autowired
    private MemberRepository memberRepository;
    
    @PostMapping("/insert"// CREATE
    public Member insert(){
        return memberRepository.save(
                new Member("김정환"28"영동")
        );
    }
}
 
cs

 

아래와 같이 JSON 형태로 반환된 것을 볼 수 있습니다. DB에 오류가 발생할 수도 있습니다. 인코딩을 한 번 살펴보시기 바랍니다. Charset을 utf8mb4로 지정하시면 해결될 수 있습니다.

 

 

 


5. CRUD 메소드 작성

프로젝트와 DB가 연동된 것을 확인했습니다. 이제 CRUD 메소드를 작성하겠습니다.

 

CRUD란, Create, Read, Update, Delete를 의미합니다. HTTP에서 GET, POST, PUT, DELETE가 각각 CRUD의 역할입니다.

 

아래 코드를 작성합니다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@RequestMapping("/member")
@RestController
public class MemberController {
 
    @Autowired
    private MemberRepository memberRepository;
 
    @PostMapping("/insert"// CREATE
    public Member insert(@RequestBody Map<StringString> map){
        return memberRepository.save(
                new Member(map.get("name"), intParser(map.get("age")), map.get("address"))
        );
    }
 
    @GetMapping("/select"// READ
    public List<Member> selectAll(){
        return memberRepository.findAll();
    }
 
    @GetMapping("/select/{id}"// READ
    public Member selectOne(@PathVariable("id"long id){
        return memberRepository.findById(id).orElse(null);
    }
 
    @PostMapping("/update/{id}"// UPDATE
    public Member updateOne(@PathVariable("id"long id, @RequestBody Map<StringString> map){
        System.out.println(id);
        System.out.println(map);
        Member member = memberRepository.findById(id).orElse(null);
        member.setName(map.get("name"));
        member.setAge(intParser(map.get("age")));
        member.setAddress(map.get("address"));
        return memberRepository.save(member);
    }
 
    @PostMapping("/delete/{id}"// DELETE
    public String deleteOne(@PathVariable("id"long id){
        memberRepository.deleteById(id);
        return "삭제 완료";
    }
 
    int intParser(String age){
        try{
            return Integer.parseInt(age);
        } catch(ClassCastException e){
            e.printStackTrace();
            return 0;
        }
    }
}
 
cs

 

 

 


6. POSTMAN을 이용해서 CRUD 메소드 테스트

메소드 테스트를 하기 위해서 Postman을 주로 쓴다고 해서 사용해보았습니다.

 

Insert 테스트

 

Select 테스트

 

Update 테스트

민경보가 양창석으로 바뀌었습니다.

바뀐 내용 조회

 

Delete 테스트

 

 

 


여기까지 Rest API 생성 완료하였습니다.

반응형