Javalin 프레임워크에 PostgreSQL 붙여보기

 



지난번 글(https://gauryan.blogspot.com/2024/09/javalin.html)에 이어서, Javalin 프레임워크에 PostgreSQL 을 붙여서 동작시켜보자. 우선, scoop 을 이용해서 PostgreSQL을 설치해준다. scoop install postgresql 을 실행한다.



pg_ctl start 를 입력해서 PostgreSQL을 기동합니다.


psql -U postgres 를 입력해서 PostgreSQL에 관리자로 로그인합니다.


다음처럼 새로운 사용자 계정을 생성합니다. 사용자 이름과 비밀번호는 원하는 것으로 설정하면 되겠습니다.


그리고, Database 를 생성합니다. 데이터베이스 이름은 test_db 로 하였고, 소유주는 test_user 로 하였습니다.


\q 로 PostgreSQL에서 빠져나와서 새로 새성한 사용자로 로그인해봅니다.


새로운 테스트용 테이블도 생성해봅니다.


CREATE TABLE TB_ADMIN

(

    ADMIN_NO Serial NOT NULL,

    LOGIN_ID Varchar(20) NOT NULL UNIQUE,

    PASSWD Varchar(20) NOT NULL,

    NICK Varchar(20) NOT NULL,

    EMAIL Varchar(40),

    PRIMARY KEY (ADMIN_NO)

) Without Oids;


테스트용 데이터도 넣어봅시다.


INSERT INTO TB_ADMIN(LOGIN_ID, PASSWD, NICK, EMAIL)

VALUES('honggildong', 'ajtwlddl', 'HONG', 'hgd@gmail.com');

 

INSERT INTO TB_ADMIN(LOGIN_ID, PASSWD, NICK, EMAIL)

VALUES('jangnara', 'dlQmsdl', 'JANG', 'jnr@gmail.com');


데이터가 잘 들어갔는지 확인해봅니다.

PROCEDURE 와 FUNCTION을 각각 만들어보겠습니다.


CREATE OR REPLACE PROCEDURE public.SP_L_ADMIN(out1 refcursor)

LANGUAGE plpgsql

AS $procedure$

BEGIN

OPEN out1 FOR

SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN;

END;

$procedure$

;


CREATE OR REPLACE FUNCTION public.FN_L_ADMIN(out1 refcursor)

RETURNS SETOF refcursor

LANGUAGE plpgsql

AS $function$

BEGIN

OPEN out1 FOR

SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN;

RETURN NEXT out1;

END;

$function$

;


그리고, SP_L_ADMIN 와 FN_L_ADMIN을 호출해서 TB_ADMIN 의 내용을 조회해 보겠습니다.

여기까지 해서, Database 쪽은 준비가 되었습니다. 이제, Javalin 에서 DB 연결부터 조회하는 것까지 해봅시다.

우선, build.gradle 파일을 열어서 다음을 추가해줍니다. HikariCP 는 Connection Pool 모듈이고, 다른 하나는 PostgreSQL JDBC 드라이버 입니다.


    implementation("com.zaxxer:HikariCP:5.1.0")

    implementation("org.postgresql:postgresql:42.7.4")


config.properties 파일에는 아래 내용을 추가해줍니다. DB연결을 위한 설정사항들입니다.


TEST_DB_CONFIG__JDBC_URL = jdbc:postgresql://localhost:5432/test_db

TEST_DB_CONFIG__USERNAME = test_user

TEST_DB_CONFIG__PASSWORD = test123

TEST_DB_CONFIG__DRIVER_CLASS_NAME = org.postgresql.Driver

TEST_DB_CONFIG__MINIMUM_IDLE = 10

TEST_DB_CONFIG__MAXIMUM_POOL_SIZE = 10


japi 폴더 아래에 model 이라는 폴더를 만들고, 그 안에 PgsqlTest.java 파일을 생성합니다.


PgsqlTest.java 의 내용은 다음과 같다.


package japi.model;


import com.zaxxer.hikari.HikariConfig;

import com.zaxxer.hikari.HikariDataSource;


import java.sql.*;


import japi.util.Common;


public class PgsqlTest {

    private static HikariConfig config = new HikariConfig();

    private static HikariDataSource ds;


    static {

        config.setJdbcUrl(Common.getProperties("TEST_DB_CONFIG__JDBC_URL"));

        config.setUsername(Common.getProperties("TEST_DB_CONFIG__USERNAME"));

        config.setPassword(Common.getProperties("TEST_DB_CONFIG__PASSWORD"));

        config.setDriverClassName(Common.getProperties("TEST_DB_CONFIG__DRIVER_CLASS_NAME"));

        config.setMinimumIdle(Integer.parseInt(Common.getProperties("TEST_DB_CONFIG__MINIMUM_IDLE")));

        config.setMaximumPoolSize(Integer.parseInt(Common.getProperties("TEST_DB_CONFIG__MAXIMUM_POOL_SIZE")));

        config.addDataSourceProperty("cachePrepStmts", "true");

        config.addDataSourceProperty("prepStmtCacheSize", "250");

        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

        ds = new HikariDataSource(config);

    }


    public static Connection getConnection() throws SQLException {

        return ds.getConnection();

    }


    public static String getAdminList() {

        String result = "";

        Connection conn = null;

        Statement stmt = null;


        try {

            conn = getConnection();

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN");

            while (rs.next()) {

                String admin_no = rs.getString("admin_no");

                String login_id = rs.getString("login_id");

                String passwd = rs.getString("passwd");

                String nick = rs.getString("nick");

                String email = rs.getString("email");

                result += "(" + admin_no + "," + login_id + "," + passwd + "," + nick + "," + email + ") ";

            }

            rs.close();

            stmt.close();

            conn.close();

        } catch (Exception e) {

            e.printStackTrace();

        }


        return result;

    }

}


TestController.java 를 다음처럼 수정한다.


package japi.controller;


import japi.model.PgsqlTest;

import io.javalin.http.Context;


public class TestController {

    // /test/request

    public static void request(Context ctx) {

        String admin_list = "";

        admin_list = PgsqlTest.getAdminList();

        System.out.println(admin_list);

        ctx.result(admin_list);

    }

}


그리고, 웹브라우저에서 http://localhost:8080/test/request 를 요청하면 아래와 같이 DB에서 가져온 데이터를 볼 수 있습니다.


이 데이터를 JSON 으로 변환해주면 더 좋겠지요? ^^ 문자열로 일일이 만들어줄 수도 있겠지만, 일단 폼이 안나고 지저분하거든요. 괜찮은 JSON 라이브러리를 이용해서 해봅시다.


build.gradle 에 다음을 추가해줍니다.


implementation("com.googlecode.json-simple:json-simple:1.1.1")


PgsqlTest.java 에 JSONArray 와 JSONObject 를 import 해주고


import org.json.simple.JSONArray;

import org.json.simple.JSONObject;


getAdminList() 함수를 이렇게 수정해줍니다.


    @SuppressWarnings("unchecked")

    public static String getAdminList() {

        String result = "";

        Connection conn = null;

        Statement stmt = null;


        try {

            conn = getConnection();

            stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN");

            JSONArray json_array = new JSONArray();

            while (rs.next()) {

                JSONObject row = new JSONObject();

                String admin_no = rs.getString("admin_no");

                String login_id = rs.getString("login_id");

                String passwd   = rs.getString("passwd");

                String nick     = rs.getString("nick");

                String email    = rs.getString("email");

                row.put("admin_no", admin_no);

                row.put("login_id", login_id);

                row.put("passwd", passwd);

                row.put("nick", nick);

                row.put("email", email);


                json_array.add(row);

            }

            result = json_array.toJSONString();

            rs.close();

            stmt.close();

            conn.close();

        } catch (Exception e) {

            e.printStackTrace();

        }


        return result;

    }


이 상태에서 웹브라우저에서 호출해보면... 짜잔...~!!! JSON 형태로 데이터가 출력됩니다.


이제, SQL 을 직접 작성해서 호출방법을 알아보았고, 아까 만들어놓은 스토어드 프로시저를 호출해서 출력 것도 해봅시다.


    @SuppressWarnings("unchecked")

    public static String getAdminList() {

        String result = "";

        Connection conn = null;

        Statement stmt1 = null;

        Statement stmt2 = null;


        try {

            conn = getConnection();

            conn.setAutoCommit(false);


            stmt1 = conn.createStatement();

            stmt1.execute("CALL SP_L_ADMIN('out1')");

            stmt2 = conn.createStatement();

            ResultSet rs = stmt2.executeQuery("FETCH ALL FROM out1");

            JSONArray json_array = new JSONArray();

            while (rs.next()) {

                JSONObject row = new JSONObject();

                String admin_no = rs.getString("admin_no");

                String login_id = rs.getString("login_id");

                String passwd   = rs.getString("passwd");

                String nick     = rs.getString("nick");

                String email    = rs.getString("email");

                row.put("admin_no", admin_no);

                row.put("login_id", login_id);

                row.put("passwd", passwd);

                row.put("nick", nick);

                row.put("email", email);


                json_array.add(row);

            }

            result = json_array.toJSONString();


            conn.commit();

            rs.close();

            stmt1.close();

            stmt2.close();

            conn.close();

        } catch (Exception e) {

            e.printStackTrace();

        }


이번에도 웹브라우저에서 http://localhost:8080/test/request 를 요청하면, JSON 으로 결과를 볼 수 있을 것이다.


아직 해야할 것들이 좀 있지만, 이정도면 어느정도 틀은 갖추어진 것이다. 여기에서 필요할 것들을 덧붙여서 실제 운영에서 사용할 수 있는 서비스로 만들기를 바란다.


댓글

이 블로그의 인기 게시물

야마하 디지털 피아노 YDP-140

테이블위로 마우스 커서 이동시 색깔 변경하기

피아노 연습