Spring Boot JPA를 통해 Tibero6와 연동하기

2023. 10. 28. 11:39·Tibero DB (Tmax AI Bigdata Academy)

벌써 교내에서 진행하는 TABA 수업의 운체, AI, DB, Tibero 시험들이 모두 끝났다..

이제 팀별 프로젝트만을 남겨두고 있는데, 백엔드를 공부하고 있기때문에 Spring Boot와

이번 프로젝트에서 DB를 평소에 사용하던 MySQL이 아닌 Tibero6를 사용해보고 싶어 미리 기록해두려고 한다.

(이러고 스프링이랑 티베로 안쓰면 ㅠㅠ)

 

 

참고

Tibero6를 윈도우나 리눅스 환경에서 설치했다고 가정하고

연동했던 과정을 기록했습니다.

 

Window 환경에서 Tibero6 설치

https://codecollector.tistory.com/1613

 

(Tibero) - Window에 설치 및 연결해보기

🍳머리말 local환경에서 Tibero6과 TiberoStudio2를 설치하고 연결해보는 설명글입니다. 📕 Tibero6 📔 installer download 설치 가능한 license가 있다고 가정하고 spring boot library에 넣을 tibero6을 설치합니다.

codecollector.tistory.com

Linux(Ubuntu) 환경에서 Tibero6 설치

https://kjungw1025.tistory.com/4

 

티베로 데이터베이스 설치하기 Tibero install in Ubuntu(WSL)

교내에서 TmaxTibero와 진행하는 교육 프로그램인 TABA(Tmax AI Bigdata Academy)를 들으면서 드디어 Tibero를 설치하는 실습을 진행하게 되었다. https://www.tmaxtibero.com/product/productView.do?prod_cd=tibero 티맥스티베

kjungw1025.tistory.com

 

 

tibero6-jdbc.jar file 확인

우선 JDBC(Java Database Connectivity)란 Java 기반 애플리케이션의 데이터를 데이터베이스에 저장 및 업데이트 또는 java에서 사용할 수 있도록 하는 API이다.

Tibero에서는 Tibero DB와 연결을 도와주기 위해 JDBC API를 제공하는데, 이를 tbJDBC(Tibero의 Java Database Connectivity)라고 부른다.

Tibero6를 설치하면서 제공되는 드라이버 파일은 아래 경로에 위치한다.

 

Window

C:\TmaxData\tibero6\client\lib\jar

Linux

/tibero6/client/lib/jar

 

위 사진처럼 경로에 들어가면 tibero6-jdbc.jar과 tibero6-jdbc-14.jar파일이 존재한다.

Tibero 6 Online Manual을 확인해보면,  JDK 버전이 1.4인 경우에는 tibero6-jdbc-14.jar 파일을 사용하고

JDK 6 이상에서 드라이버 파일은 tibero6-jdbc.jar 파일을 사용하면 된다고 설명하고 있다.

나의 경우 JDK 17이 설치되어있기 때문에 tibero6-jdbc.jar 파일을 사용할 예정이다. 

# 터미널에서 jdk 버전 확인
java --version

 

 

 

Spring Boot JPA

프로젝트 생성

Spring Initializr를 사용해 프로젝트를 생성했다.

https://start.spring.io/

 

tibero6-jdbc.jar 추가

위에서 확인한 tibero6-jdbc.jar 파일을, 생성한 스프링부트 폴더안의 src 폴더와 같은 level에

별도의 libs 폴더를 만들어 libs 폴더안에 넣어준다.

 

build.gradle 설정

build.gradle안의 dependencies에 추가한 jar의 경로를 넣어 build해준다.

plugins {
	id 'java'
	id 'org.springframework.boot' version '2.7.17'
	id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'taba'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation files('libs/tibero6-jdbc.jar')
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

 

application.yml 설정

spring:
  datasource:
    driver-class-name: com.tmax.tibero.jdbc.TbDriver
    url: jdbc:tibero:thin:@127.0.0.1:8629:tibero
    username: sys
    password: tibero

  jpa:
  	# 문법 정의 : tibero는 oracle 문법을 사용하므로
    database-platform: org.hibernate.dialect.Oracle10gDialect
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: true
        show_sql: true
        highlight_sql: true
        default_batch_fetch_size: 200

 

Entity 작성

Tibero6 연동을 확인하기 위해 위 사진처럼 패키지들을 만들어 수행하고자 한다.

domain 패키지 안에 Member.java 생성

package taba.tibero6jpa.user.domain;

import lombok.*;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity
@Table(name="member")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    @NotNull
    @Column(length = 20)
    private String name;

    @NotNull
    private String phone;

    @Builder
    private Member(@NotNull String name,
                   @NotNull String phone) {
        this.name = name;
        this.phone = phone;
    }
}

 

DTO 작성

package taba.tibero6jpa.user.domain;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

import javax.validation.constraints.NotBlank;

@Getter @Setter
@RequiredArgsConstructor
public class RequestMemberDto {
    @NotBlank
    private String name;
    @NotBlank
    private String phone;
}

 

Repository 작성

package taba.tibero6jpa.user.repository;

import org.springframework.stereotype.Repository;
import taba.tibero6jpa.user.domain.Member;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

@Repository
public class MemberRepository {
    @PersistenceContext // JPA가 제공하는 표준 어노테이션
    private EntityManager em; // Spring이 Entity manager를 만들어서 주입하게 해줌

    public void save(Member member) {
        em.persist(member);
    }

    public List<Member> findAll() {
        List<Member> result = em.createQuery("select m from Member m", Member.class)
                .getResultList();
        return result;
    }

    public List<Member> findByName(String name) {
        return em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList();
    }
}

 

Service 작성

package taba.tibero6jpa.user.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import taba.tibero6jpa.user.domain.Member;
import taba.tibero6jpa.user.domain.RequestMemberDto;
import taba.tibero6jpa.user.repository.MemberRepository;

import java.util.List;

@Service
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;

    @Transactional
    public Long join(RequestMemberDto dto) {
        validateDuplicateMember(dto);

        Member member = Member.builder()
                .name(dto.getName())
                .phone(dto.getPhone())
                .build();
        memberRepository.save(member);

        return member.getId();
    }

    private void validateDuplicateMember(RequestMemberDto dto) {
        List<Member> findMembers = memberRepository.findByName(dto.getName());
        if (!findMembers.isEmpty()) {
            throw new IllegalStateException("이미 존재하는 회원입니다.");
        }
    }

    @Transactional(readOnly = true)
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    @Transactional(readOnly = true)
    public List<Member> findByName(String name) {
        return memberRepository.findByName(name);
    }
}

 

실행 및 테이블 생성 확인

application을 실행하면 터미널상에 아래와 같이 테이블이 생성된 것을 log로 확인할 수 있다.

그렇다면 Tibero6 DB에도 테이블이 잘 생성되었을까? 확인해보자!

다음과 같이 성공적으로 테이블이 생성된 것을 확인할 수 있다. 

 

Thymeleaf 템플릿 엔진을 통해 로컬 환경에서 웹 띄워보기

사실 위에서 끝내도 되긴하지만,

간단하게 Thymeleaf를 통해 뷰 템플릿을 작성하고

컨트롤러로 전달하는 데이터를 이용하여 동적으로 웹 화면을 보여주는 것까지 하고 마무리하려고 한다.

 

controller

package taba.tibero6jpa.user.controller;

import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import taba.tibero6jpa.user.domain.Member;
import taba.tibero6jpa.user.domain.RequestMemberDto;
import taba.tibero6jpa.user.service.MemberService;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class MemberController {
    private final MemberService memberService;

    @GetMapping("/members/new")
    public String createForm(Model model) {
        model.addAttribute("memberForm", new RequestMemberDto());
        return "members/createMemberForm";
    }

    @PostMapping("/members/new")
    public String create(@Valid RequestMemberDto dto, BindingResult result) {
        if (result.hasErrors()) {
            return "members/createMemberForm";
        }
        memberService.join(dto);
        return "redirect:/";
    }

    @GetMapping("/members")
    public String list(Model model) {
        List<Member> members = memberService.findMembers();
        model.addAttribute("members", members);
        return "members/memberList";
    }
}

 

HTML 작성

resources > static > templates에 아래 html들을 작성하자

createMember.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymleaf.org">
    <body>
        <div>
            <form action="/members/new" method="post">
                <div>
                    <label for="name">이름</label>
                    <input type="text" id="name" name="name" placeholder="이름을 입력하세요.">

                    <label for="phone">전화번호</label>
                    <input type="text" id="phone" name="phone" placeholder="전화번호를 입력하세요.">
                </div>
            </form>
        </div>
    </body>
</html>

memberList.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
    <body>
        <div>
            <div>
                <table>
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>이름</th>
                            <th>전화번호</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr th:each="member : ${members}">
                            <td th:text="${member.id}"></td>
                            <td th:text="${member.name}"></td>
                            <td th:text="${member.phone}"></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </body>
</html>

 

로컬 환경에서 확인하기

처음 /members에 들어가면 현재 Member 테이블에 값들이 비어있기 때문에 아래와 같이 나온다.

/members/new에 들어가서 값을 insert해주자

입력 버튼을 누르면 /members로 리다이렉트 했기 때문에 아래와 같이 값이 잘 적용된 것을 확인할 수 있다.

터미널에서도 아래와 같이 query문이 잘 동작하는 것을 확인할 수 있다.

사용자가 input tag에 값을 넣고 입력 버튼을 누르면, Hibernate의 시퀀스 전략으로 nextval이 호출되면서

name, phone값과 함께 Insert되고,

/members 페이지로 가면서 Member 테이블에 존재하는 값들 전부를 select하는 과정이다.

 Tibero6 DB에도 값이 문제 없이 Insert된 것을 확인할 수 있다.

 

 

'Tibero DB (Tmax AI Bigdata Academy)' 카테고리의 다른 글

Tmax AI Bigdata Academy 4기를 마치며  (0) 2023.12.19
Spring Boot JPA와 Tibero6 연동 간 발생했던 에러들 정리  (0) 2023.11.11
tbstudio 실행 및 기능 살펴보기  (0) 2023.10.22
pyodbc를 이용하여 Tibero DB에 대한 query문 작성하기  (0) 2023.10.17
Ubuntu 환경에서 ODBC를 통해 Tibero와 Python 연동하기  (2) 2023.10.16
'Tibero DB (Tmax AI Bigdata Academy)' 카테고리의 다른 글
  • Tmax AI Bigdata Academy 4기를 마치며
  • Spring Boot JPA와 Tibero6 연동 간 발생했던 에러들 정리
  • tbstudio 실행 및 기능 살펴보기
  • pyodbc를 이용하여 Tibero DB에 대한 query문 작성하기
개발이조아용
개발이조아용
IT 개발에서 배운 성장의 기록을 작성합니다.
  • 개발이조아용
    계속 하다 보면?!
    개발이조아용
  • 전체
    오늘
    어제
    • 분류 전체보기 (67)
      • Tibero DB (Tmax AI Bigdata .. (7)
      • Git (2)
      • CI CD (2)
      • Redis (3)
      • SpringBoot (16)
      • SQL 문제 풀이 (8)
      • Apache Kafka (8)
        • 오류 해결 (3)
        • 개념 정리 (4)
        • 보안 (1)
      • Nginx (3)
      • SW마에스트로 (3)
      • Kubernetes (4)
      • AWS (5)
      • gRPC (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Kafka 개념
    SQL
    Git
    SpringBoot
    sql 문제
    redis script
    redis
    소프트웨어 마에스트로
    SASL 인증
    nginx
    leetcode
    Kafka SASL
    Kafka 오류
    grpc
    K8S
    Redis 개념
    KAFKA
    MSA
    DynamoDB 연동
    Tibero
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
개발이조아용
Spring Boot JPA를 통해 Tibero6와 연동하기
상단으로

티스토리툴바