[59호]실시간 미세먼지 농도 데이터를 이용한 휴대용 마스크 착용 경보기
2019 ICT 융합 프로젝트 공모전 참가상
실시간 미세먼지 농도 데이터를 이용한
휴대용 마스크 착용 경보기
글 | 한국산업기술대학교 정승식, 숭실대학교 정지은, 박우상
1. 심사평
칩센 주기적으로 스마트폰과 데이터 통신을 하여야 하고, 미세먼지 정보 센터의 기준치와 비교하여 어떠한 결과를 도출해내는 방식이라면 굳이 별도의 장치를 보유하여야 하는 이유가 무엇인지 잘 모르겠습니다. 내 위치의 실시간 미세 먼지를 알수는 없으나, 이미 스마트폰을 통해 지역별 미세먼지 농도를 확인할수 있는데, 굳이 별도의 장치를 이용하여 마스크 착용 여부를 판단하는 것은 실효성이 많아 보이지는 않아 보입니다.
뉴티씨 미세먼지는 정말 우리나라에 재앙수준으로 늘어나 있습니다. 세계 100개의 미세먼지 문제도시 중에 40개 정도가 대한민국에 있다고 하니 얼마나 심각한지 알 수 있습니다. 중국은 베이징 1개 정도만 들어있다고 하죠. 미세먼지를 현실에서 바로바로 측정하여 결과를 알 수 있다면 참 좋을 것 같습니다. 많은 사람들이 만약 그것이 있다면, 하나정도는 구매하지 않을까 싶네요. 소형화하여 상품화 한다면 참 좋은 상품이 될 것 같습니다.
위드로봇 다양한 상황에 대한 결과 분석이 아쉽습니다.
펌테크 수집된 미세먼지 데이터를 서버로 전송 후 화면에 표시하는 기술 구현 방식은 우수했다고 생각합니다. 학부과정의 학생이 구현하기에 적정한 난이도를 가진 작품이라고 생각합니다.
2. 개요와 목표
요즘 우리나라에서 파란 하늘을 보는 것이 매우 드물다. 그것의 제일 큰 원인은 바로 미세먼지이며 역대 최악의 고농도 미세먼지로 인해 우리나라 대기 질 순위는 180개국 중에 173위로 매우 저조한 등수이고 그로 인해 호흡기 질환 등 건강 악화에 대한 우려가 커지고 있다. 미국 환경보호청(EPA)에 의하면 고농도 미세먼지 지역에 거주하는 사람은 유방암에 걸릴 확률이 높고, 호흡기로 침투한 먼지 때문에 심장마비, 동맥경화 등 심혈관 질환 발병 위험률도 높아진다고 한다. 그러므로 외부활동 시 미세먼지 흡입을 줄이기 위해 마스크 착용이 필수적으로 여겨지는 상황이다.
하지만 한국갤럽의 미세먼지 관련 인식 설문조사 결과에 따르면, 미세먼지 나쁨 예보일 때 ‘마스크를 착용하지 않는 편’ 응답은 45%로 집계됐다. 절반에 가까운 사람이 아직 건강상태의 심각성을 인식하지 못한 채 마스크 착용을 꺼리는 상황이다. 우리는 이러한 상황에서 미세먼지에 대한 경각심을 주고자 ‘미세먼지 어디까지 마셔봤니?’라는 작품을 만들었다.
작품을 만들면서 우리는 미세먼지 마스크 착용 권장뿐만 아니라 이미 미세먼지 마스크를 착용하는 사람들에게도 도움이 되는 정보를 더 주는 것을 목표로 하였다. 인터넷상에서 지역의 농도를 평균 내어 보여주는 것과 실제로 내가 있는 공간의 농도는 다를 수 있다. 예를 들어 인터넷에서 알려주는 값이 ‘보통’ 수준이라 마스크 착용을 하지 않고 있는데 실제로 내가 있는 곳 주변에 공장, 공사 등의 이유로 농도가 ‘나쁨’ 수준일 수 있다. 그렇게 되면 고농도 미세먼지를 그대로 들이마시는 정보 전달의 오류가 생긴다. 따라서 이를 방지하기 위해 휴대가 가능한 경보기가 있다면 더 좋을 것으로 생각했다. 더불어 이 작품을 통해 미세먼지 해결방안을 개발하는 사람들에게 실제 현장의 미세먼지 농도 데이터를 알고 유용하게 사용하여 실질적이고 더 좋은 대책을 마련하는 데 도움이 될 것이라고 생각한다.
3. 작품 설명
3.1. 주요 동작 및 특징
3.1.1. 작품 디자인
가방이나 허리춤에 매달 수 있는 열쇠고리 형태의 휴대용 경보기 형태이다.
3.1.2 미세먼지 측정 및 경보
전원을 공급하면 실시간으로 현재 나의 주변의 미세먼지 농도를 측정한다. 그리고 측정한 농도를 미세먼지 정보 센터에서 제공하는 기준치와 비교하여 ‘나쁨’수준(36~75μg/m³)이 측정되면 상단 LED의 초록 불빛으로, ‘매우 나쁨’수준(76~ μg/m³)이 측정되면 상단 LED의 빨간 불빛으로 주변 미세먼지 농도 상태를 색으로 알려준다. 뿐만 아니라 상단의 스위치를 누르면 센서에서 측정한 실시간 미세먼지 종류별(PM-2.5, PM-10) 농도를 LCD에서 5초간 확인 할 수 있게 하였다.
3.1.3. 실시간 미세먼지 농도 웹서버로 기록 및 수치 확인
경보기는 웹서버로 실시간으로 측정된 주변 미세먼지 농도 값을 보낸 다. 웹서버에서는 받은 수치를 저장하고 그래프화 하여 시간대별 미세먼지 농도 변화를 나타낸다, 이는 데이터를 필요로 하는 사람에게 유용하게 쓰일 수 있다. 그리고 마스크 착용 여부를 확인하여 데이터 축적에 반영함으로써, 사용자가 얼마만큼의 미세먼지를 마셨는지, 또한 흡연했을 시 미세먼지 흡입량과 비교하여 미세먼지의 위험성을 실감할 수 있도록 한다.
3.2. 전체 시스템 특징
3.2.1. 구성 hardware
Wemos D1 mini, PMS 7003 미세먼지 센서, LED, Tact switch, 16×2 LCD with I2C comm module
3.2.2. 구성 software
Apache 8.0, mySQL, Microsoft Azure, ino
미세먼지 흡입량은 다음에 의한 공식으로 인해 산출되었다.
일반 남성의 분당 흡입량 : 6L -> 초당 흡입량: 0.1L, 15초당 1회씩 로깅하므로 1회 로깅당 흡입량 : 1.5L, 최신 데이터로부터 24시간 전까지의 기록을 모두 더한 값 Xug/L * 1.5 = 하루 동안의 흡입량
이 때 기록을 더할 때, 마스크를 쓰고 있었다면(mask 버튼이 눌러진 상태라면) kf94기준 94%의 미세먼지를 걸러주므로 0.06을 곱한 상태로 더한다.
3.2.3. 전체적인 구성도
3.3. 개발환경(개발언어, Tool, 사용 시스템)
3.3.1. 아두이노 기술 구현
Tool: visual micro(Arduino extension for visual studio)
언어: cpp
미세먼지 센서 감지, led 발광 로직, wifi 데이터 전송, lcd 발광 로직
3.3.2. 웹서버 제작 및 DB구축
Tool: Microsoft Azure, mySQL, Apache Tomcat
언어: HTML, javascript, SQL, JSTL, java, jsp
4. 단계별 제작과정
4.1. 웹서버 제작
· Azure 가상머신 구축
· Apache 8.0 설치
· mySQL 설치
· DB 제작
Microsoft Azure를 이용해 가상머신을 구축하고, Apache를 설치하고 mySQL을 이용해 DB를 구축하였다. 홈페이지는 bootstrap을 이용하여 작성하고, jsp를 이용하여 서버와 연동시켰으며 그래프는 Google Chart를 이용하여 구현하였다.
4.2. 아두이노 센서 동작 및 전체적인 알고리즘 작성
미세먼지 센서 제작(센서, LED, 스위치 연결 및 pin mapping)
· 미세먼지 센서를 동작시키는 코드를 작성
· 미세먼지의 값을 측정하여 웹서버로 전송하는 코드를 작성
· 미세먼지의 값을 기준치에 맞춰 LED가 발광하는 코드를 작성
· 스위치의 작동여부를 인터럽트로 받아와 LCD를 작동시키는 코드를 작성
5. 소스코드
5.1 아두이노
#include <Wire.h>//i2c 통신을 위한 헤더
#include <LiquidCrystal_I2C.h>//lcd를 사용하기 위한 헤더
#include <ESP8266HTTPClient.h>//http로 전송하기 위한 헤더
#include <ESP8266WiFi.h>//wifi 연결을 위한 헤더
volatile bool intFlag = 0;
int pm25 = 0, pm10 = 0, pm1 = 0; //센서로부터 byte 형태로 전송되는 데이터를 int 형태로 받아 사용
char* ssid = “********”;
char* password = “*********”; //wifi 접속하기 위해 쓰는 ssid와 password
String host = “http://52.141.33.28/import?”; //웹서버로 주소의 형태를 통해 데이터를 전송하기 위한 주소
//——————-PINS———————//
int green = D0, red = D6;
int SerialRX = D5;
int tactSwitch = D7; //esp8266의 pin
//———————————————-//
LiquidCrystal_I2C lcd(0×27, 16, 2); //i2c 객체를 활성화
void setup()
{
WiFi.mode(WIFI_STA); //client mode 사용
WiFi.disconnect();
Serial.begin(9600); //hardware serial 사용
attachI nterrupt(tactSwitch, riseFlag, RISING); // tact switch 를 위한 pin interrupt 설정
pinMode(green, OUTPUT);
pinMode(red, OUTPUT);
digitalWrite(green, LOW);
digitalWrite(red, LOW); //기본적으로 led를 low로 설정
if (connectWiFi()) //wifi 연결 과정, 연결이 되지 않을 시 종료
{
return;
}
lcd.begin();
lcd.clear();
lcd.noBacklight(); // lcd를 끄고, 화면의 글씨를 지워 초기화함
}
void loop()
{
PMdetect(); // 미세먼지 값을 측정
blink(); // 미세먼지 값에 따라 led 색상 조정
showLCD(); // 스위치를 누를 경우 lcd 화면을 보여줌
log(); // wifi를 통해 웹서버로 데이터 전송
}
void blink() // 환경부 기준에 따라 ‘좋음’ 일 경우 led 끄고, ‘보통’일 경우 초록색, ‘나쁨’일 경우 빨간색 led를 발광
{
struct led {
bool red;
bool green;
};
led sel[4] = { {0,0},{0,1},{1,0},{1,0} };
int state25 = 0, state10 = 0;
if (pm25 > 35) state25++;
if (pm25 > 75)state25++;
if (pm10 > 30)state10++;
if (pm10 > 80)state10++;
int result = state25 | state10;
digitalWrite(red, sel[result].red);
digitalWrite(green, sel[result].green);
}
void PMdetect() //pms7003 미세먼지 센서로부터 값을 얻어냄
{
int chksum = 0; //체크섬 변수
unsigned char pms[32] = { 0, }; //미세먼지 데이터 저장용 배열
if (Serial.available() >= 32) { // pms7003은 총 32byte의 데이터를 전송, 이것보다 적은 데이터를 받았을 경우 함수를 실행하지 않음
for (int j = 0; j < 32; j++) {
pms[j] = Serial.read();
if (j < 30)
chksum += pms[j];
}
if (pms[30] != (unsigned char)(chksum >> 8)
|| pms[31] != (unsigned char)(chksum)) {//체크섬을 통해 제대로 된 데이터를 전송받았는지 체크, 체크섬 값이 다를 경우 에러로 판정
Serial.flush();
return;
}
if (pms[0] != 0×42 || pms[1] != 0x4d) //전송된 데이터의 첫 번째와 두 번째의 값은 고정, 이 값이 변경되었을 경우 에러로 판정
{
Serial.flush();
return;
}
pm1 = (pms[10] << 8) | pms[11];
pm25 = (pms[12] << 8) | pms[13];
pm10 = (pms[14] << 8) | pms[15]; //bit shift를 통해 2개의 byte 데이터를 하나의 int 데이터로 합침
}
}
int connectWiFi()//wifi에 접속하기 위한 함수
{
int count = 0;
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
if (count++ == 10) {
return 1;
}
}
return 0;
}
void riseFlag() { intFlag = 1; } //인터럽트 서비스 루틴, 인터럽트 플래그를 활성화
void lowFlag() { intFlag = 0; } //다시 인터럽트 플래그를 내림
void log()
{
static unsigned long logtime = 0; //millis() 함수를 이용해 원하는 시간에만 데이터 전송, 현재는 15초
if (millis() – logtime > 5000)
{
logtime = millis(); //데이터를 전송할 경우 타이머를 최신화함
HTTPClient httpClient;
Serial.println(“pm25=” + String(pm25));
httpClient.begin(host + “pm1=” + String(pm1) + “&pm25=” + String(pm25) + “&pm10=” + String(pm10)); //주소를 입력하는 형식을 이용해 데이터를 전송
}
}
void showLCD() //lcd를 밝혀주는 함수
{
#define ON true
#define OFF false
static unsigned long lcdtime = 0;//lcd 발광 시간을 비교하기 위한 함수
static bool lcdstate = OFF;
if (intFlag == 1) //인터럽트 플래그가 활성화 되어있을 시
{
lcd.clear();
lcd.backlight();
lcdtime = millis(); //lcd 발광 시간을 계산, 이 시간부터 5초간 지속
lcd.print(“PM2.5:” + String(pm25) + “ug/m3”); //lcd에 PM25의 값을 print
lcd.setCursor(0, 1); //커서를 한칸 내림
lcd.print(“PM10:” + String(pm10) + “ug/m3”); //lcd에 PM10의 값을 print
lcd.backlight(); //lcd의 백라이트 활성화
lcdstate = ON; //lcd의 상태를 ‘켜짐’으로 바꿈
lowFlag(); //인터럽트 플래그는 내려줌
}
else if (lcdstate && (millis() – lcdtime > 5000)) //lcd가 ‘켜짐’ 상태고 현재 시간이 lcdtime으로부터 5초 이상 지났을 시
{
lcd.clear(); //lcd 글자 지움
lcd.noBacklight(); //lcd 백라이트 비활성화
lcdstate = OFF; //lcd의 상태를 ‘꺼짐’으로 바꿈
}
}
5.2. 홈페이지 코드
<%@ page language=”java” contentType=”text/html; charset=UTF-8”
pageEncoding=”UTF-8”%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
<!DOCTYPE html>
<html>
<head>
<meta charset=”UTF-8”>
<link rel=”stylesheet” href=”https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css” integrity=”sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T” crossorigin=”anonymous”>
<link rel=”shortcut icon” href=”/resources/title.png”>
<title>Hello, Particular Matter!</title>
</head>
<body>
<div class=”container”>
<div class=”row mt-3”>
<div class=”col-12 text-center”>
<h2>Hello, Particular Matter!</h2>
</div>
</div>
<div class=”row mt-3”>
<div class=”col-12”>
<div class=”card text-center” style=”min-width: 270px;”>
<div class=”card-body” id=”card-pmnotice”>
<h5 class=”card-title” id=”card-pmnotice-title”>${currentTime}</h5>
<div class=”mb-3” id=”card-pmnotice-pm”>
<p class=”card-text” id=”card-pmnotice-pm-pm1”>PM1.0 = ${pm1}ug/㎥</p>
<p class=”card-text” id=”card-pmnotice-pm-pm25”>PM2.5 = ${pm25}ug/㎥</p>
<p class=”card-text” id=”card-pmnotice-pm-pm10”>PM10 = ${pm10}ug/㎥</p>
</div>
<p>${message}</p>
<button class=”btn btn-primary” id=”btn-update”>Update information</button>
<button class=”btn btn-success” id=”btn-graph”>I want to see a graph!</button>
</div>
</div>
</div>
</div>
<div class=”row mt-4”>
<div class=”col-12”>
<c:choose>
<c:when test=”${flgMask == 0}”>
<button type=”button” class=”btn btn-primary btn-lg btn-block btn-controlmask” id=”1”>Wear a Mask!</button>
</c:when>
<c:when test=”${flgMask == 1}”>
<button type=”button” class=”btn btn-danger btn-lg btn-block btn-controlmask” id=”0”>Remove a Mask!</button>
</c:when>
</c:choose>
</div>
</div>
</div>
<script src=”https://code.jquery.com/jquery-3.3.1.slim.min.js” integrity=”sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo” crossorigin=”anonymous”></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js” integrity=”sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1” crossorigin=”anonymous”></script>
<script src=”https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js” integrity=”sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM” crossorigin=”anonymous”></script>
<script type=”text/javascript”>
var protocol = location.protocol;
var port = location.port;
var host = location.hostname;
$(document).on(‘click’, ‘.btn-controlmask’, function() {
$(this).prop(‘disabled’, true);
location.href = protocol + “//” + host + “:” + port + “/mask?flgMask=” + $(this).attr(‘id’);
});
$(document).on(‘click’, ‘#btn-update’, function() {
$(this).prop(‘disabled’, true);
location.href = protocol + “//” + host + “:” + port + “/”;
});
$(document).on(‘click’, ‘#btn-graph’, function() {
$(this).prop(‘disabled’, true);
location.href = protocol + “//” + host + “:” + port + “/graph”;
});
</script>
</body>
</html>
그래프 페이지 코드
<%@ page language=”java” contentType=”text/html; charset=UTF-8”
pageEncoding=”UTF-8”%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
<!DOCTYPE html>
<html>
<head>
<meta charset=”UTF-8”>
<link rel=”stylesheet” href=”https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css” integrity=”sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T” crossorigin=”anonymous”>
</head>
<body>
<div id=”curve_chart” style=”width: 100vw; height: 600px;”></div>
<div class=”container”>
<div class=”row mt-2 mb-5”>
<div class=”col-12 text-center”>
<div class=”alert alert-danger”>
${message}
</div>
<button class=”btn btn-success” id=”btn-home”>Go back to home!</button>
</div>
</div>
</div>
<script src=”https://code.jquery.com/jquery-3.3.1.slim.min.js” integrity=”sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo” crossorigin=”anonymous”></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js” integrity=”sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1” crossorigin=”anonymous”></script>
<script src=”https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js” integrity=”sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM” crossorigin=”anonymous”></script>
<script type=”text/javascript” src=”https://www.gstatic.com/charts/loader.js”></script>
<script type=”text/javascript”>
var protocol = location.protocol;
var port = location.port;
var host = location.hostname;
$(document).on(‘click’, ‘#btn-home’, function() {
$(this).prop(‘disabled’, true);
location.href = protocol + “//” + host + “:” + port + “/”;
});
google.charts.load(‘current’, {packages: [‘corechart’]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
// Define the chart to be drawn.
var data = new google.visualization.DataTable();
data.addColumn(‘date’, ‘time’);
data.addColumn(‘number’, ‘pm1.0’);
data.addColumn(‘number’, ‘pm2.5’);
data.addColumn(‘number’, ‘pm10’);
data.addRows(${graphData});
var options = {
title: ‘Particulate Matter Density’,
curveType: ‘function’,
legend: { position: ‘bottom’ }
};
// Instantiate and draw the chart.
var chart = new google.visualization.LineChart(document.getElementById(‘curve_chart’));
chart.draw(data,options);
}
</script>
</body>
</html>
5.3. bean 코드
package bean;
import java.math.BigDecimal;
public class HomeBean {
private BigDecimal dc_pm1;
private BigDecimal dc_pm25;
private BigDecimal dc_pm10;
private String st_update;
private String flg_mask;
public BigDecimal getDc_pm1() {
return dc_pm1;
}
public void setDc_pm1(BigDecimal dc_pm1) {
this.dc_pm1 = dc_pm1;
}
public BigDecimal getDc_pm25() {
return dc_pm25;
}
public void setDc_pm25(BigDecimal dc_pm25) {
this.dc_pm25 = dc_pm25;
}
public BigDecimal getDc_pm10() {
return dc_pm10;
}
public void setDc_pm10(BigDecimal dc_pm10) {
this.dc_pm10 = dc_pm10;
}
public String getSt_update() {
return st_update;
}
public void setSt_update(String st_update) {
this.st_update = st_update;
}
public String getFlg_mask() {
return flg_mask;
}
public void setFlg_mask(String flg_mask) {
this.flg_mask = flg_mask;
}
}
5.4. Controller 코드
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.GraphService;
@WebServlet(“/graph”)
public class GraphController extends HttpServlet {
private static final long serialVersionUID = 1L;
GraphService gs = new GraphService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// get info
if (!gs.getDataforGraph(req)) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// forward
req.getServletContext().getRequestDispatcher(“/WEB-INF/template/graph.jsp”).forward(req, resp);
}
}
5.5. DAO(Data Access Object) 코드
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import bean.GraphBean;
public class GraphDao extends SQLExecuter {
public List<GraphBean> getDataforGraphDao() {
String sql =
“SELECT “ +
“ dc_pm1, dc_pm25, dc_pm10, dt_update, flg_mask “ +
“FROM “ +
“ h_particular_matter “ +
“WHERE dt_update > NOW() – INTERVAL 1 DAY “ +
“ORDER BY “ +
“ dt_update “;
List<GraphBean> lgb = executeSelect(sql);
if (lgb == null) {
System.out.println(“GraphDao.getDataforGraphDao: 1. Fail to get data”);
return null;
}
return lgb;
}
@Override
public List<GraphBean> executeSelect(String sql) {
try {
Class.forName(connector);
Connection conn =
DriverManager.getConnection(connectionStr);
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(sql);
List<GraphBean> lgb = new ArrayList<GraphBean>();
while ( rset.next() ) {
GraphBean gb = new GraphBean();
gb.setDc_pm1(rset.getBigDecimal(“dc_pm1”));
gb.setDc_pm25(rset.getBigDecimal(“dc_pm25”));
gb.setDc_pm10(rset.getBigDecimal(“dc_pm10”));
gb.setDt_update(rset.getTimestamp(“dt_update”));
gb.setFlg_mask(rset.getString(“flg_mask”));
lgb.add(gb);
}
rset.close();
stmt.close();
conn.close();
return lgb;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
}