반응형

Akka 솔직히 좀 개념이 좀 생소해서 어떨때에 어떻게 사용해야하는지 분간이 안가서 학습중이다.

 

Akka 정의

 

Akka는 오픈 소스 툴킷으로, JVM 상의 동시성과 분산 애플리케이션을 단순화하는 런타임이다. 

 

pom.xml


<dependency>
  <groupId>com.typesafe.akka</groupId>
  <artifactId>akka-actor-typed_2.13</artifactId>
  <version>2.6.14</version>
</dependency>
<dependency>
  <groupId>com.typesafe.akka</groupId>
  <artifactId>akka-actor-testkit-typed_2.13</artifactId>
  <version>2.6.14</version>
  <scope>test</scope>
</dependency>

 

AKKA 프로젝트 템플릿 다운로드

http://dev.lightbend.com/start/?group=akka&project=akka-quickstart-java   

 

AKKA 는 자바개발환경에서는 maven, gradle 로 실행 가능하고, 스칼라 사용시 SBT 로 빌드 후 사용 가능하다.

프로젝트를 받게되면

AkkaQuickstart 라는 java 파일이 있다.

//#actor-system
final ActorSystem<GreeterMain.SayHello> greeterMain = ActorSystem.create(GreeterMain.create(), "helloakka");
//#actor-system

//#main-send-messages
greeterMain.tell(new GreeterMain.SayHello("Charles"));
//#main-send-messages

ActorSystem 을 생성하고 

main 액터에 메시지를 보낸다.

 

GreeterMain

public class GreeterMain extends AbstractBehavior<GreeterMain.SayHello> {

    public static class SayHello {
        public final String name;
        public SayHello(String name) {
            this.name = name;
        }
    }

    private final ActorRef<Greeter.Greet> greeter;

    public static Behavior<SayHello> create() {
        return Behaviors.setup(GreeterMain::new);
    }

    private GreeterMain(ActorContext<SayHello> context) {
        super(context);
        //#create-actors
        greeter = context.spawn(Greeter.create(), "greeter");
        //#create-actors
    }

    @Override
    public Receive<SayHello> createReceive() {
        return newReceiveBuilder().onMessage(SayHello.class, this::onSayHello).build();
    }


	// 3개의 GreetoerBot 을 생성 후 Greeter 에게 메시지와 누구에게 메시지를 보낼지 대상을 전달한다.
    private Behavior<SayHello> onSayHello(SayHello command) {
        //#create-actors
        ActorRef<Greeter.Greeted> replyTo =
                getContext().spawn(GreeterBot.create(3), command.name);
        greeter.tell(new Greeter.Greet(command.name, replyTo));
        //#create-actors
        return this;
    }
}

AbstractBehavior 클래스를 상속받은 GreeterMain 에게 Charles 라는 메시지를 보내면 

AbstractBehavior 클래스의 createReceive 메소드에서 receive 받기로 한 메소드가 실행이 된다.

 

createReceive 에는 메시지 받는 타입과 메시지 받은 이후의 처리를 담당하는 handler 를 설정할 수 있다.

예제에서는 handler 가 onSayHello 메소드 이다.

 

onSayHello 의 메소드는 응답받을 3개의 GreeterBot 을 만든다.

그 후

ActorRef<Greeter.Greet> greeter

ActorRef 변수 greeter 에게 메시지와 메시지를 보낼 대상일 GreeterBot(ActorRef) 객체를 보낸다.

Greeter.class

public class Greeter extends AbstractBehavior<Greeter.Greet> {

  public static final class Greet {
    public final String whom;
    public final ActorRef<Greeted> replyTo;

    public Greet(String whom, ActorRef<Greeted> replyTo) {
      this.whom = whom;
      this.replyTo = replyTo;
    }
  }

  public static final class Greeted {
    public final String whom;
    public final ActorRef<Greet> from;

    public Greeted(String whom, ActorRef<Greet> from) {
      this.whom = whom;
      this.from = from;
    }

  public static Behavior<Greet> create() {
    return Behaviors.setup(Greeter::new);
  }

  private Greeter(ActorContext<Greet> context) {
    super(context);
  }

  @Override
  public Receive<Greet> createReceive() {
    return newReceiveBuilder().onMessage(Greet.class, this::onGreet).build();
  }
  
  // GreeterMain actorRef 가 tell 할 경우 실행된다.
  private Behavior<Greet> onGreet(Greet command) {
    getContext().getLog().info("Hello {}!", command.whom);
    //#greeter-send-message
    command.replyTo.tell(new Greeted(command.whom, getContext().getSelf()));
    //#greeter-send-message
    return this;
  }
}

 

여기서 또 AbstractBehavior 클래스를 상속받은 Greeter 가

createReceive 에서 연결된 Greet 타입으로 onGreet 메소드를 실행한다.

 

이번 onGreet 메소드에는 특이하게 GreeterMain 의 onSayHello 에서 보낸 GreeterBot(ActorRef)  가 있어서 

GreeterBot 이 tell 하도록 한다.

 

GreeterBot.class

public class GreeterBot extends AbstractBehavior<Greeter.Greeted> {

    public static Behavior<Greeter.Greeted> create(int max) {
        return Behaviors.setup(context -> new GreeterBot(context, max));
    }

    private final int max;
    private int greetingCounter;

    private GreeterBot(ActorContext<Greeter.Greeted> context, int max) {
        super(context);
        this.max = max;
    }

    @Override
    public Receive<Greeter.Greeted> createReceive() {
        return newReceiveBuilder().onMessage(Greeter.Greeted.class, this::onGreeted).build();
    }
	
    // Greeter actorRef 가 onGreet 할때 tell 시킨다.
    private Behavior<Greeter.Greeted> onGreeted(Greeter.Greeted message) {
        greetingCounter++;
        getContext().getLog().info("Greeting {} for {}", greetingCounter, message.whom);
        if (greetingCounter == max) {
            return Behaviors.stopped();
        } else {
            message.from.tell(new Greeter.Greet(message.whom, getContext().getSelf()));
            return this;
        }
    }
}

 

코드 요약 

GreeterMain 에게 tell 을 한 후 Main 에 생성 되어 있는 ActorRef(greeter) 에게 tell 을 하고, 응답을 ActoerRef(greeterBot) 이 응답한다.

 

실행   

 

akka 자바 공식문서

https://doc.akka.io/docs/akka/2.5/testing.html

반응형
반응형

 

KEYS

패턴에 일치하는 모든키를 반환한다. 시간복잡도는 O(N) 이지만 시간은 적게 걸린다. 레디스는 40밀리 초 이내에 백만개 데이터를 스캔 가능하다.

 

주의 : KEYS 명령어는 조심스럽게 사용해야 하는데, 대규모 데이터베이스에서 실행되면 성능이 저하 될 수 있다.

 

> KEYS 패턴

패턴 :

h?llo => hello, hallo, hxllo

h*llo => hllo, heeeeello, haaaaaallo

h[ae]lo => hello, hallo, hillo (X)

h[^e]llo => hallo, hillo, hello (x)

h[a-b]llo => hallo, hbllo 

* => like 검색과 같음

 

> MSET one 1 two 2 three 3 four 4

---
> KEYS *

one
two
three
four

---
> KEYS *o*

one 
two
four

---
> KEYS t??

two

 

DEL

키를 제거

> DEL one two

2

 

EXISTS

키가 있는 지 확인 

시간 복잡도 : O(1)

 

GET

> GET KEY

"키에 담긴 값"

 

 

참고문헌

http://wiki.pchero21.com/wiki/Redis_command  

https://realmojo.tistory.com/171  

반응형
반응형

 

node-sass 버젼과 node 버젼이 맞지 않을떄 빌드시 서버에서 다음과 같은 오류 가 낫다.

 

npm ERR! code 1
npm ERR! path ~~~~node_modules/node-sass
npm ERR! command failed
npm ERR! command sh -c node scripts/build.js

 

로컬에서는 npm start 로 실행시

Syntax Error: Error: Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (88)
과 같은 오류가 난다.

 

오류 원인은 node 버젼이 해당 Node-sass 버젼을 지원하지 않기 때문에 발생한다

 

 

노드 버젼이 호환하는 node-sass 버젼 표이다.

NodeJSSupported node-sass versionNode Module

 

Below is a quick guide for minimum and maximum support supported version of node-sass

nodejs node-sass version node module
Node 16 6.0+ 93
Node 15 5.0+ 88
Node 14 4.14+ 83
Node 13 4.13+, <5.0 79
Node 12 4.12+ 72
Node 11 4.10+, <5.0 67
Node 10 4.9+, <6.0 64
Node 8 4.5.3+, <5.0 57
Node <8 <5.0 <57

출처 : www.npmjs.com/package/node-sass  

 

예를 들어 node 15 버젼인 경우 node sass 는 5 버젼 밑에는 호환이 안된다.

 

nodejs 를 버젼에 맞게 설치하든지 node-sass 를 새로 설치하는 방법이 있다.

 

node-sass 삭제 후 새로 설치

# 4.14.x 구 버전 설치되어 있음
$ npm list | grep node-sass 
├── node-sass@4.14.1 

# node-sass 삭제 후 새로 설치
$ npm uninstall node-sass 
$ npm install --save node-sass 

# 5.0.0 최신버전 설치 확인
$ npm list | grep node-sass 
├── node-sass@5.0.0

 

node-sass 는 node 버젼에 의존적이라 node 버젼 업데이트시 node-sass 버젼도 확인해야 한다.

반응형

'프론트엔드 > NPM' 카테고리의 다른 글

[Node] Mac OS에서 NVM 설치 및 사용 명령어 정리  (0) 2024.01.15
반응형

 

firebase 가 클라이언트 사이드에서 구현하기 위한 severless db 로 많이 쓰이는데, 

나 같은 경우는 db 를 구축하기 일단 비용 및 인프라가 없어서 간단히 만들려고 firebase 를 서버에서 사용하기 위한 db 로 일단은 선택했다.

 

일정량 이하는 free 로 사용할 수 있다.

 

firebase 프로젝트 생성

대쉬보드에서 프로젝트 추가를 통해 프로젝트를 생성

console.firebase.google.com/

 

firestore Database 를 생성하자.

주의 할 것은 realtime database 와 firestore database 는 다르다.

다른 점으로는 과금 정책도 다르고, realtime 이 더 비싸다고 한다.

둘의 차이점은 아래 링크 문서에 있다.

firebase.google.com/docs/database/rtdb-vs-firestore?hl=ko

 

프로젝트 설정 에서 account 관련 키 파일을 다운받아야 한다.

프로젝트 개요 > 프로젝트 설정 > 서비스 계정 > Firebase Admin SDK 

에서 자바 를 클릭 후 

새 비공개 키 생성 으로 파일을 다운받자. 

다운 받으면 ~~~~.json 파일로 다운받아진다.

 

스프링 spring boot 코드 

pom.xml 라이브러리 다운

<dependency>
	<groupId>com.google.firebase</groupId>
	<artifactId>firebase-admin</artifactId>
	<version>6.11.0</version>
</dependency>

 

스프링 init 코드

@Service
public class FirebaseInitialize {

    @PostConstruct //has to be Run during the Start of
    public void initialize() {
        try {
            FileInputStream serviceAccount =
                    new FileInputStream("src/main/resources/serviceAccountKey.json");

            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                    .setDatabaseUrl("https://{{데이터베이스명}}.firebaseio.com")
                    .build();

            FirebaseApp.initializeApp(options);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}

 

위에서 다운받은 json 파일을 이름을 변경해주고 resources 하위 경로에 넣자.

databaseUrl 은 따로 나오는 곳은 없어 보였는데, 프로젝트 명 에 뒤에 .firebaseio.com 을 붙이면 된다.

데이터베이스명은 firestore 조회 화면에 바로 나온다.

 

데이터 샘플로 넣고 조회하기

@Slf4j
@Service
public class FirebaseService {

    public static final String COLLECTION_NAME = "user";

    public void insertUser() throws Exception {

        Firestore db = FirestoreClient.getFirestore();
        User user = new User();
        user.setId("4444");
        user.setName("4444");
        ApiFuture<WriteResult> apiFuture = db.collection(COLLECTION_NAME).document("user_4").set(user);

        log.info(apiFuture.get().getUpdateTime().toString());
    }


    public void selectUser() throws Exception {

        Firestore db = FirestoreClient.getFirestore();
        User user = null;
        ApiFuture<DocumentSnapshot> apiFuture = db.collection(COLLECTION_NAME).document("user_4").get();
        DocumentSnapshot documentSnapshot = apiFuture.get();
        if(documentSnapshot.exists()) {
            user = documentSnapshot.toObject(User.class);
            log.info(user.toString());
        }
    }
}

 

User 라는 pojo 클래스를 만들고 넣어줘도 되고 HashMap 으로 만들어서 넣어줘도 된다.

collection 과 document 라는 개념이 몽고db 와 흡사하다.

collection 이라는 개념은 db와 같고, 하위의 document 가 테이블 과 개념이 같다. 조금 다른 점이 있다면 document 가 하위로 계속 들어갈 수 있다.

사용 

    @Resource
    FirebaseService firebaseService;

    @Test
    public void 테스트() throws Exception {
        firebaseService.insertUser();
        firebaseService.selectUser();
    }

이 정도 코드는 사실 안남겨도 되는데, 혹시나.

 

결과 

 

나 같은 경우는 저 코드를 작성했는데 한참 동작하지 않아서 이것저것 삽질을 조금 했다.

나중에 시간이 지나고 되는걸 보면 database 를 생성하고 일정시간이 지나야 되는거 같긴 한데, 이건 확실치 않다.

혹시 안되는 사람은 2시간 정도 경과하고 한번 다시 해보도록

 

혹시나 권한 때문에 안되는 사람은 규칙(rule)을 확인하자.

production 모드로 한 사람은 규칙에서 test 모드로 변경하면 된다.

2021 년 6월 3일 까지는 read write 권한이 된다는 코드이다.

반응형
반응형

jpa 관련 어노테이션

  • @Column : 컬럼을 매핑한다.
  • @Enumerated : enum 타입을 매핑한다.
  • @Temporal : 날짜 타입 매핑한다.
  • @Lob : BLOB, CLOB 타입을 매핑한다.
  • @Transient : 해당 필드를 데이터 베이스에 매핑 시키지 않는다.
  • @Access : JPA가 엔티티 접근하는 방식을 지정한다.

@Column

name : 필드와 매핑할 테이블의 컬럼 이름
insertable : 엔티티 저장시 이 필드도 같이 저장한다. false로 설정하면 데이터베이스에 저장하지 않는다. 읽기 전용일때 사용한다.
updatable : 위와 동일한 하지만 수정일때 해당 된다.

@Column(insertable=false, updatable=false)
private String defaultField;

위와같이 하면 update 나 insert 가 안된다. update 만 안할 경우 updatable 만 false 로 하면 된다.

 

table : 지정한 필드를 다른 테이블에 맵핑할 수 있도록 합니다.

nullable(DDL) : null 값 허용 여부를 설정한다. false일 경우 DDL생성시 not null 제약조건이 된다.
unique(DDL) : 한 컬럼에 간단히 유니크 제약 조건을 걸 때 사용한다. 만약 두개 이상 걸고 싶다면 클래스 레벨에서 @Table.uniqueConstraints를 사용해야 한다.
columnDefinition(DDL) : 데이터베이스 컬럼 정보를 직접 줄 수 있다.
length : 문자 길이 제약 조건이다. String만 해당된다.
precision, scale(DDL) : BigDecimal 타입에서 사용한다.(BigInteger 가능) precision은 소수점을 포함한 전체 자리수이고, scale은 소수점 자릿수이다. double랑 float타입에는 적용 되지 않는다.

 

@Enumerated

value : EnumType.ORDINAL값은 enum 순서를 데이터 베이스에 저장한다. EnumType.STRING값은 enum 이름을 저장한다.

enum RoleType {
  ADMIN, USER
}

@Enumerated(EnumType.STRING)
private RoleType roleType;

m.setRoleType(RoleType.ADMIN) //ADMIN으로 저장된다.

보통은 STRING을 쓰는것을 권장한다.

 

@Temporal

날짜 타입(java.util.Date, java.util.Calendar)을 맵핑할 때 사용한다.

value :

TemporalType.DATE  날짜, 데이터베이스 date 타입과 매핑 (2016-04-19),

TemporalType.TIME 시간, 데이터베이스 time 타입과 매핑 (21:22:11)

TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑(2016-04-19 21:22:11)

 

@Lob

속성이 없다. 대신 매핑하는 필드 타입이 문자라면 CLOB으로 매핑하고 나머지는 다 BLOB으로 매핑하면 된다.
CLOB : String, char[], java.sql.CLOB
BLOB : byte[], java.sql.BLOB

 

@Transient

위와 같이 선언된 필드는 데이터베이스에 저장, 조회도 하지않는다. 임시로 값을 보관할 때 사용한다.

 

@Access

필드 접근 : AccessType.FIELD로 지정한다.필드에 직접 접근한다. private 권한이여도 접근할 수 있다.
프로퍼티 접근 : AccessType.PROPERTY로 지정한다. 접근자 getter로 접근한다.

@Entity
public class Member {

  @Id
  private String id;

  @Transient
  private String firstName;

  @Transient
  private String lastName;

  @Access(AccessType.PROPERTY)
  public String getFullName(){
    return this.firstName + this.lastName;
  }

  ...
}

@Id가 필드에 있으면 기본적으로 필드접근 방식을 사용한다.
만약 프로퍼티에 있으면 기본적으로 프로퍼티접근 방식을 사용한다.

위의 코드는 @Id가 필드에 있으므로 필드 접근 방식을 사용하고 getFullName만 프로퍼티를 사용한다. 그러면 회원이라는 엔티티의 FULLNAME 컬럼이 생성되고 firstName + lastName의 결과가 저장된다.

 

반응형
반응형

사이드프로젝트를 배포하기가 자금적으로나 서버를 새로 띄우기 여간 번거롭다.

그래서 무료로 배포할 수 있는 heroku 를 사용해봤다.

 

Heroku 사이트 : https://www.heroku.com/  

 

heroku cli 다운 받기

컴퓨터에서 heroku를 사용하기 위해서는 Heroku CLI(command line interface)를 설치해야 한다. 

heroku login

설치하게 되면 command 창에서 heroku 명령어가 사용가능해 진다.

 

로그인

먼저 터미널에서 heroku login 을 하자

heroku login

 

배포 앱 준비

배포할 앱이 있어야 한다.

샘플로 헤로쿠에서 git 저장소를 만들어놨다.

git clone https://github.com/heroku/java-getting-started
cd java-getting-started

java 서비스를 배포할떄 주의할 점은 application 소스코드 안에 pom.xml 이 존재 해야한다.

그리고 굳이 github 이 아니고 bitbucket 등 타 git 레포로 해도 된다.

 

앱 배포하기

$ heroku create

create 를 하면 헤로쿠 사이트에 임의의 이름을 가진 프로젝트가 생긴걸 확인할 수 있다.

$ git push heroku main

프로젝트가 생성됐으면 위 명령어로 git 으로 헤로쿠에 푸쉬를 하면 된다.

main 명령어가 동작하지 않으면

 

$ heroku git:remote -a 생성된프로젝트명

으로 git 을 헤로쿠에 연결시켜주자.

그리고

$ git push heroku master

으로 헤로쿠에 업로드를 하면 자동으로 빌드하고 배포 까지 된다.

 

해당 내용은 Deploy 탭에 명시된 내용이다. 

 

로그보기

헤로쿠로 로그도 볼 수 있다.

 

 

가이드

devcenter.heroku.com/articles/getting-started-with-java#deploy-the-app

 

 

 

반응형

'서비스평가 및 사용' 카테고리의 다른 글

Buy me a coffee 블로그로 후원받기  (0) 2020.05.26
Github gist 사용해보기  (0) 2020.05.22
정리잘 된 개발 블로그 정리  (1) 2020.05.15
반응형

주식을 하다보면 공시를 확인해야 하는데 매번 사이트를 들어가서 공시를 보기 여간 불편하기 때문에 

dart 에서 제공하는 api 를 사용해보자

 

 

전자공시시스템(DART ; Data Analysis, Retrieval and Transfer System)은 상장법인 등이 공시서류를 인터넷으로 제출하고, 투자자 등 이용자는 제출 즉시 인터넷을 통해 조회할 수 있도록 하는 종합적 기업공시 시스템이다.

 

오픈 API 를 신청하려면 아래 주소로 접속하자

opendart.fss.or.kr/intro/main.do

여기서 [인증키 신청]을 통해 접속할 수 있는 계정을 발급받고 더블어 인증키를 받자

[오픈API 이용현황] 메뉴를 들어가면 인증키가 바로 나온다.

 

 

DART 오픈 API 개발가이드 - drive.google.com/file/d/1nI6c5-fX-6TE357BWxYp7udf6BTED1U3/view

api 를 편히 쓰라고 python 은 라이브러리가 생겼다.

DART python 라이브러리 소스코드 - github.com/josw123/dart-fss  

dart python 라이브러리 문서 - dart-fss.readthedocs.io/en/latest/

해당 라이브러리 사용 하지 않아도 api 를 사용해도 된다.

나 같은 경우는 파이썬 잘 몰라서 스프링으로 하려고 한다.

 

python 코드 에서 api 콜 하는 부분 만 보고 직접 만들어주면 된다.

 

샘플 API 사용 예시

https://opendart.fss.or.kr/api/company.json?crtfc_key={발급받은API키}&corp_code=00126380

API 키를 발급 받았으면 다음처럼 사용 가능하다.

 

기업개황 API는 대표자명, 사업자등록번호 등의 기업의 기본 정보를 제공합니다. JSON 포멧 요청 URL은 https://opendart.fss.or.kr/api/company.json이고 다음 두 파라미터를 입력해야 한다.

  • crtfc_key: 발급받은 인증키
  • corp_code: 공시대상회사 고유번호
{
    "status": "000",
    "message": "정상",
    "corp_code": "00126380",
    "corp_name": "삼성전자(주)",
    "corp_name_eng": "SAMSUNG ELECTRONICS CO,.LTD",
    "stock_name": "삼성전자",
    "stock_code": "005930",
    ~~
    ~~
    ~~
    ~~
}

 

주의사항 

  • Open DART 및 DART 홈페이지의 경우 분당 100회 이상 요청시 서비스가 제한될 수 있음
  • 개인용은 일일 사용량은 10,000건으로 제한 되어 있습니다.

 

위 캡쳐본은 

DART 오픈 API 개발가이드 - drive.google.com/file/d/1nI6c5-fX-6TE357BWxYp7udf6BTED1U3/view

에 있는 내용입니다.

API 주소까지 다 있습니다.

반응형
반응형

외부에 물리db 를 생성하기 어려울떄가 있다.

나 같은 경우 사이드 프로젝트를 하고 싶은데 물리 db 를 생성하기 부담스러울때 간단히 내부 db 를 사용하고 싶어 인메모리 h2 를 사용한다.

 

h2 는 보통 프로덕션보다는 보통 test 용으로 사용한다.

왜냐면 휘발성이기 때문이다.

 

 

  • 디스크가 아닌 주 메모리에 모든 데이터를 보유하고 있는 데이터베이스입니다. 
  • 디스크 검색보다 자료 접근이 훨씬 빠른 것이 큰 장점입니다. 단점은 매체가 휘발성이기 때문에 DB 서버가 꺼지면 모든 데이터가 유실된다는 단점이 있습니다.
  • 스프링 부트에서 H2, HSQL 같은 인메모리, 디스크 기반 DB를 지원합니다.

 

라이브러리 추가

현재 spring boot 버젼 2.4.5

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

 

 

  • H2 데이터베이스 의존성을 추가하고 난 후, 설정 파일에 아무 설정이 되어 있지 않으면 스프링 부트는 자동적으로 H2 데이터베이스를 기본 데이터베이스로 선택한다
  • spring-boot-starter-jdbc 의존성을 추가하면 DataSource, JdbcTemplate을 별다른 설정없이 @Autowired 같은 빈 주입 어노테이션만 가지고도 쓸 수 있다.
@Component
public class H2Runner implements ApplicationRunner {

    @Autowired
    DataSource dataSource;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        try(Connection connection = dataSource.getConnection()){
            System.out.println(connection);
            String URL = connection.getMetaData().getURL();
            System.out.println(URL);
            String User = connection.getMetaData().getUserName();
            System.out.println(User);

            Statement statement = connection.createStatement();
            String sql = "CREATE TABLE USER(ID INTEGER NOT NULL, NAME VARCHAR(255), PRIMARY KEY (ID) )";
            statement.executeUpdate(sql);
        }

        jdbcTemplate.execute("INSERT INTO USER VALUES(1, 'testuser')");
    }
}

위의 코드 까지만 작성하면 h2 가 정상적으로 동작하는 지 확인 가능하다.

아래 기본 ddl sql 로드 방법을 사용하면 위의 자바 class 는 필요가 없다.

spring:
  h2:
    console:
      enabled: true
      path: /h2-console

 

다음과 같이 yml 에 설정하면 웹에서 sql 접근 가능

localhost:8080/h2-console   로 접근 가능

별도의 yml 로 디비 접속 설정을 안하면 

connection.getMetaData().getURL()  -> JDBC URL

connection.getMetaData().getUserName() -> User Name, 디폴트값 : sa

로 로그 찍은 값으로 접속 가능하다.

 

디폴트 값으로 하지 않고 yml 에서 설정하려면

datasource:
    url: jdbc:h2:mem:testdb
    username: sa

다음과 같이 작성하면 된다.

 

 

기본 ddl sql script 로드

기본적으로 jpa 와 h2 라이브러리 import 하는 거 만으로 schema.sql 과 data.sql 를 초기에 로딩 할 수 있다.

스키마 파일은 

schema.sql  로 명명 하고

resources > 하위에 schema.sql 을 두면 초기 구동 되면서 sql 문을 실행한다.

CREATE TABLE Employee
(
    id integer NOT NULL,
    firstName varchar(255) not null,
    lastName varchar(255) not null,
    email varchar(255),
    phoneNumber varchar(255),
    hireDate timestamp,
    salary integer,
    commissionPct integer,
    primary key(id)
);

data 삽입도 같이 data.sql 파일안에 insert 문을 넣어주면 된다.

 

별도로 해줘야 할 작업은 application.yml 파일에

spring:
  jpa:
    hibernate:
      ddl-auto: none

같이 ddl-auto 를 none 으로 설정해야 resources 하위의 sql 문을 실행한다.

 

지금 하는 sql 초기 구동시 로딩을 해주면 위에서 작성한 H2Runner.class 를 따로 생성하지 않아도 된다.

 

결과

 

최종 yml 파일

spring:
  h2:
    console:
      enabled: true
      path: /h2-console
  jpa:
    hibernate:
      ddl-auto: none
  datasource:
    url: jdbc:h2:mem:testdb
    username: sa

 

반응형

+ Recent posts