๐Ÿž ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

  • ๐Ÿ–ฅPJT๋ช…: Enjoy Trip Project

  • ๐Ÿšถโ€โ™‚๏ธ๋‹จ๊ณ„: DB PJT

  • ๐Ÿ“…์ง„ํ–‰์ผ์ž: 2024.04.12

  • ๐Ÿ‘ฉโ€๐Ÿ’ปํŒ€์›: ๊น€์ง€์›, ์‹ ๋ฏผ๊ฒฝ

  • ํ”„๋กœ์ ํŠธ ์„ค๋ช…

    • ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ถ„์„ํ•˜๊ณ  DB ๋ชจ๋ธ๋ง์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • DB ๋ชจ๋ธ๋ง ๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ํ…Œ์ด๋ธ”๋กœ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • EnjoyTrip ํ”„๋กœ์ ํŠธ์˜ DB ์˜์—ญ์˜ ์—ญํ• ์„ ์ดํ•ดํ•˜๊ณ , DAO ํด๋ž˜์Šค์™€ DB ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๋™ํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•˜์—ฌ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

โš™๊ธฐ๋Šฅ

  • ์ง€์—ญ๋ณ„, ์ปจํ…์ธ ๋ณ„ ๊ด€๊ด‘์ง€ ์ •๋ณด Table์„ ์„ค๊ณ„ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” DAO ํด๋ž˜์Šค ๊ตฌํ˜„.
  • ํšŒ์›์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” Table ์„ค๊ณ„ ๋ฐ DAO ํด๋ž˜์Šค ๊ตฌํ˜„.
  • ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•˜์—ฌ ๊ฒŒ์‹œํŒ ์ •๋ ฌ ์„œ๋น„์Šค ๊ตฌํ˜„.
  • ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ด์šฉํ•˜์—ฌ ๊ด€๊ด‘์ง€ ์ตœ๋‹จ ๊ฒฝ๋กœ ์ถ”์ฒœ ์„œ๋น„์Šค ๊ตฌํ˜„.

โœ” ER Diagram

โœ” DDL sql ํŒŒ์ผ

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- -----------------------------------------------------
-- Schema excuseMe
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema excuseMe
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `excuseMe` DEFAULT CHARACTER SET utf8 ;
USE `excuseMe` ;

-- -----------------------------------------------------
-- Table `excuseMe`.`user`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `excuseMe`.`user` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `user_id` VARCHAR(16) NOT NULL,
  `password` VARCHAR(20) NOT NULL,
  `email` VARCHAR(45) NOT NULL,
  `phone` VARCHAR(45) NOT NULL,
  `role` ENUM("user", "admin") NOT NULL,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC) VISIBLE)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `excuseMe`.`board`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `excuseMe`.`board` (
  `user_id` INT NOT NULL,
  `id` INT NOT NULL AUTO_INCREMENT,
  `created_date` TIMESTAMP NOT NULL,
  `view` INT NOT NULL,
  `like` INT NOT NULL,
  `title` VARCHAR(100) NOT NULL,
  `contents` TEXT NOT NULL,
  INDEX `user_id_idx` (`user_id` ASC) VISIBLE,
  PRIMARY KEY (`id`),
  CONSTRAINT `board_user_id`
    FOREIGN KEY (`user_id`)
    REFERENCES `excuseMe`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `excuseMe`.`comment`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `excuseMe`.`comment` (
  `post_id` INT NOT NULL,
  `user_id` INT NOT NULL,
  `id` INT NOT NULL AUTO_INCREMENT,
  `created_date` TIMESTAMP NOT NULL,
  `like` INT NOT NULL,
  `contents` TEXT NOT NULL,
  INDEX `post_id_idx` (`post_id` ASC) VISIBLE,
  PRIMARY KEY (`id`),
  INDEX `user_id_idx` (`user_id` ASC) VISIBLE,
  CONSTRAINT `commnet_user_id`
    FOREIGN KEY (`user_id`)
    REFERENCES `excuseMe`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `comment_post_id`
    FOREIGN KEY (`post_id`)
    REFERENCES `excuseMe`.`board` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `excuseMe`.`tour`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `excuseMe`.`tour` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(100) NOT NULL,
  `addr` VARCHAR(200) NOT NULL,
  `tel` VARCHAR(200) NOT NULL,
  `img` VARCHAR(2083) NOT NULL,
  `type` VARCHAR(8) NOT NULL,
  `map_x` FLOAT NOT NULL,
  `map_y` FLOAT NOT NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `excuseMe`.`tour_like`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `excuseMe`.`tour_like` (
  `tour_id` INT NOT NULL,
  `user_id` INT NOT NULL,
  INDEX `use_id_idx` (`user_id` ASC) VISIBLE,
  CONSTRAINT `like_tour_id`
    FOREIGN KEY (`tour_id`)
    REFERENCES `excuseMe`.`tour` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `like_use_id`
    FOREIGN KEY (`user_id`)
    REFERENCES `excuseMe`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `excuseMe`.`tour_route`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `excuseMe`.`tour_route` (
  `user_id` INT NOT NULL,
  `id` INT NOT NULL AUTO_INCREMENT,
  `len` INT NOT NULL,
  `list` TEXT NOT NULL,
  INDEX `user_id_idx` (`user_id` ASC) VISIBLE,
  PRIMARY KEY (`id`),
  CONSTRAINT `route_user_id`
    FOREIGN KEY (`user_id`)
    REFERENCES `excuseMe`.`user` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

โœ” ๊ด€๊ด‘์ง€ ์ •๋ณด ํฌ๋กค๋ง


package com.ssafy.trip.db;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.ssafy.dbUtil.DButil;

public class UpdateTripDB {
    public static void main(String[] args) throws IOException {
        StringBuilder urlBuilder = new StringBuilder("https://apis.data.go.kr/B551011/KorService1/areaBasedList1"); /*URL*/
        urlBuilder.append("?" + URLEncoder.encode("serviceKey","UTF-8") + "=nFhFOGxQE8IEkx4ZLuIMOGL9XEg%2Bzhxc2%2BK3Bl%2FfF8woFKQSXtW9KybG%2Bg8F593hJXGLw9USKI9vEzbnX6np7w%3D%3D"); /*Service Key*/
        urlBuilder.append("&" + URLEncoder.encode("numOfRows","UTF-8") + "=" + URLEncoder.encode("1000", "UTF-8")); /*ํ•œ ํŽ˜์ด์ง€ ๊ฒฐ๊ณผ ์ˆ˜*/
        urlBuilder.append("&" + URLEncoder.encode("MobileOS","UTF-8") + "=" + URLEncoder.encode("ETC", "UTF-8")); 
        urlBuilder.append("&" + URLEncoder.encode("MobileApp","UTF-8") + "=" + URLEncoder.encode("AppTest", "UTF-8"));
        urlBuilder.append("&" + URLEncoder.encode("_type","UTF-8") + "=" + URLEncoder.encode("xml", "UTF-8"));
        
        for(int pageNum = 1; pageNum<=52;pageNum++) {
			StringBuilder urlTmp = new StringBuilder(urlBuilder.toString());
			urlTmp.append("&" + URLEncoder.encode("pageNo","UTF-8") + "=" + URLEncoder.encode(Integer.toString(pageNum), "UTF-8")); /*ํŽ˜์ด์ง€๋ฒˆํ˜ธ*/
		
	        URL url = new URL(urlTmp.toString());
	        System.out.println(urlTmp.toString());
	        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
	        conn.setRequestMethod("GET");
	        conn.setRequestProperty("Content-type", "application/json");
	        System.out.println("Response code: " + conn.getResponseCode());
	        BufferedReader rd;
	        if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
	            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	        } else {
	            rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
	        }
	        StringBuilder sb = new StringBuilder();
	        String line;
	        while ((line = rd.readLine()) != null) {
	            sb.append(line);
	        }
	        rd.close();
	        conn.disconnect();
	        System.out.println(sb.toString());
	        
	       Connection sqlConn = null;
	       PreparedStatement pstmt = null;
	       System.out.println(urlTmp.toString());
	        try {
	        	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				DocumentBuilder builder = factory.newDocumentBuilder();
				Document document = builder.parse(new InputSource(new StringReader(sb.toString())));
				NodeList nodeList = document.getElementsByTagName("item");
				sqlConn = DButil.getInstance().getConnection();
				StringBuilder sql = new StringBuilder();
				sql.append("insert into tour (name,addr,tel,img,type,map_x,map_y) \n");
				sql.append("values (?,?,?,?,?,?,?)");
				pstmt = sqlConn.prepareStatement(sql.toString());
				int len = nodeList.getLength();
				for(int i=0;i<len;i++) {
					Node node = nodeList.item(i);
					if(node.getNodeType()==Node.ELEMENT_NODE) {
						Element element = (Element) node;
						System.out.println("---------------------------------------------");
						System.out.println();
						System.out.println("๊ด€๊ด‘์ง€ : " + element.getElementsByTagName("title").item(0).getTextContent());
						System.out.println("๊ด€๊ด‘์ง€ ์žฅ์†Œ 1 : " + element.getElementsByTagName("addr1").item(0).getTextContent());
						System.out.println("๊ด€๊ด‘์ง€ ์žฅ์†Œ 2 : " + element.getElementsByTagName("contenttypeid").item(0).getTextContent());
						System.out.println("์ „ํ™”๋ฒˆํ˜ธ : " + element.getElementsByTagName("tel").item(0).getTextContent());
						System.out.println("์ด๋ฏธ์ง€ : " + element.getElementsByTagName("firstimage").item(0).getTextContent());
						pstmt.setString(1,element.getElementsByTagName("title").item(0).getTextContent());
						pstmt.setString(2,element.getElementsByTagName("addr1").item(0).getTextContent());
						pstmt.setString(3,element.getElementsByTagName("tel").item(0).getTextContent());
						pstmt.setString(4,element.getElementsByTagName("firstimage").item(0).getTextContent());
						pstmt.setString(5,element.getElementsByTagName("contenttypeid").item(0).getTextContent());
						pstmt.setString(6,element.getElementsByTagName("mapx").item(0).getTextContent());
						pstmt.setString(7,element.getElementsByTagName("mapy").item(0).getTextContent());
						pstmt.executeUpdate();
					}
				}
				
				
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch(SAXException e) {
				e.printStackTrace();
			} catch (SQLException e) {
				e.printStackTrace();
			}
        
        }
    }
}

โœ” meber table ์„ค๊ณ„ ๋ฐ DAO ํด๋ž˜์Šค ๊ตฌํ˜„

โœ” tour table ์„ค๊ณ„ ๋ฐ DAO ํด๋ž˜์Šค ๊ตฌํ˜„

โœ” ํ€ต ์ •๋ ฌ (Quick sort)๋ฅผ ์ด์šฉํ•œ ๊ฒŒ์‹œํŒ ์ •๋ ฌ ์„œ๋น„์Šค ๊ตฌํ˜„

  • ๊ฒŒ์‹œ๋ฌผ ์ตœ์‹ ์ˆœ, ์กฐํšŒ์ˆœ์œผ๋กœ ์กฐํšŒ

  • ์ตœ์‹ ์ˆœ (latest)

  1. compareByLatest() : ๋น„๊ตํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ตœ์‹ ์ˆœ์œผ๋กœ ์ •๋ ฌ
  2. quickSort() : ํ€ต ์ •๋ ฌ ํ•จ์ˆ˜ ์ƒ์„ฑ
  3. sortByLatest() : '์ตœ์‹ ์ˆœ'์„ ์„ ํƒํ•  ๊ฒฝ์šฐ, 1๋ฒˆ ์‹คํ–‰, 2๋ฒˆ ์‹คํ–‰ํ•˜์—ฌ ๊ฒŒ์‹œํŒ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๊ฐฑ์‹ 
  • ์กฐํšŒ์ˆœ (popular)
  1. comparePopular() : ๋น„๊ตํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์กฐํšŒ์ˆœ์œผ๋กœ ์ •๋ ฌ
  2. quickSort() : ํ€ต ์ •๋ ฌ ํ•จ์ˆ˜ ์ƒ์„ฑ
  3. sortByPopular() : '์กฐํšŒ์ˆœ'์„ ์„ ํƒํ•  ๊ฒฝ์šฐ, 1๋ฒˆ ์‹คํ–‰, 2๋ฒˆ ์‹คํ–‰ํ•˜์—ฌ ๊ฒŒ์‹œํŒ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๊ฐฑ์‹ 

โœ” ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ด์šฉํ•œ ๊ด€๊ด‘์ง€ ์ตœ๋‹จ ๊ฒฝ๋กœ ์ถ”์ฒœ ์„œ๋น„์Šค ๊ตฌํ˜„

  • ๋‚˜๋งŒ์˜ ์—ฌํ–‰ ๊ณ„ํš ๊ธฐ๋Šฅ์—์„œ ๋ฐฉ๋ฌธํ•˜๊ณ ์ž ํ•˜๋Š” ๊ด€๊ด‘์ง€๋“ค์— ๋Œ€ํ•œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•ด์คŒ
  1. ๊ธฐ์กด ๋ฐฉ๋ฌธํ•œ ์ง€์ ์— ๋Œ€ํ•œ ์ด ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•ด์ฃผ๋Š” ํ•จ์ˆ˜ ์‚ญ์ œ
  2. stores ๋ฐฐ์—ด์„ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์„ค์ •
  3. ์œ ์ €๊ฐ€ ๊ด€๊ด‘์ง€๋ฅผ ์„ ํƒํ•  ๋•Œ๋งˆ๋‹ค stores์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ  stores์— ์ด๋ฏธ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ด€๊ด‘์ง€๋ฉด ๋ฐฐ์—ด์—์„œ ์‚ญ์ œ
  4. ์œ ์ €๊ฐ€ ๊ด€๊ด‘์ง€๋ฅผ ์„ ํƒํ•  ๋•Œ๋งˆ๋‹ค findShortestPath()๋ฅผ ํ†ตํ•ด ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•จ --- findShortestPath()๋Š” ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ†ตํ•ด ๊ณผ๋ถ€ํ™”๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ ์ž dp๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€์Œ
  5. ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์œ„๋„, ๊ฒฝ๋„ ๊ธฐ์ค€์œผ๋กœ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด calculateDistance() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•จ
  6. findShortestPath()๋Š” ์ตœ๋‹จ๊ฒฝ๋กœ ๊ด€๊ด‘์ง€์™€ ์ด์ „ ๊ด€๊ด‘์ง€์™€์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•จ
  7. ๋ฐ˜ํ™˜๋œ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ์ง€๋„ ์™ผ์ชฝ ์ƒ๋‹จ์— ์œ„์น˜ํ•œ clickedPlacesList๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ ํ•ญ๋ชฉ์œผ๋กœ ์ถ”๊ฐ€ํ•จ
  8. ์ด์ „ ๊ด€๊ด‘์ง€์™€ ๊ฑฐ๋ฆฌ๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์„ ํ™œ์šฉํ•˜์—ฌ ์ด ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๊ณ  clickedPlacesList ul ๋‚ด๋ถ€์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•จ
  9. ์œ ์ €๊ฐ€ ๊ด€๊ด‘์ง€๋ฅผ ์„ ํƒํ•  ๋•Œ๋งˆ๋‹ค 3~8๋ฒˆ์„ ๋ฐ˜๋ณต