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 으로 결과를 볼 수 있을 것이다.
아직 해야할 것들이 좀 있지만, 이정도면 어느정도 틀은 갖추어진 것이다. 여기에서 필요할 것들을 덧붙여서 실제 운영에서 사용할 수 있는 서비스로 만들기를 바란다.
댓글
댓글 쓰기