node.js
브라우저가 없어도 단독으로 테스트 가능
npm
노드 패키지를 관리해주는 툴 → 패키지들이 서로 의존되어 있어 하나의 문제가 발생하면 다른 것까지 가능하지 않을 수도
vscode 확장기능 설치(Auto Rename Tag/HTML CSS Support/Font Awesome Auto-complete & Preview/vscode-icons
package.json 설정참고
{
"name": "html0116",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1",
"start": "nodemon app"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"colors": "^1.4.0",
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^2.0.20"
}
}
info.txt
npm init --yes
npm i express
:Restful API를 지원하는 프레임워크
npm i nodemon --save-dev
:--save-dev 옵션을 붙이면 로컬에서만 사용함
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>index페이지</title>
</head>
<body>
<h3>index페이지</h3>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src=""
crossorigin="anonymous"
></script>
<title>TerrGYM</title>
</head>
<body>
<h2>TerrGYM</h2>
<ul>
<li>스쿼트</li>
<li>런지</li>
<li>레풀다운</li>
<li><i class="fa-solid fa-trash"></i></li>
<li><i class="fas fa-plus"></li>
</ul>
</body>
</html>
let colors = require("colors");
console.log("hello".green); // outputs green text
console.log("i like cake and pies".underline.red); // outputs red underlined text
console.log("inverse the color".inverse); // inverses the color
console.log("OMG Rainbows!".rainbow); // rainbow
console.log("Run the trap".trap); // Drops the bass
console.log(colors.rainbow('OMG Rainbows!')); // rainbow
console.log(colors.green('OMG Rainbows!')); // rainbow
console.log(colors.red('OMG Rainbows!')); // rainbow
function add(a, b) {
return a + b;
}
console.log(add(1, 2));
console.log(add(2, 3));
console.log(add(5, 7));
console.log(add(1, 5));
JAVA → JFrame사용, 브라우저에서 동작 안 함(native app)
웹 프로그래밍(html, css, js → 정적페이지 처리)
동적페이지 처리 → JAVA(HTTP 프로토콜을 지원하는 api가 없음) → Server에서 돌아가는 JAVA 필요함 → Applet(JFrame과 거의 같음) → 서버에서 돌아가는 애플릿 Server+Applet → Servlet 서블릿이 만들어짐(HTTP 프로토콜, Resful API 지원하게 됨) → 단점: out.print(”<html><head><body></body></head></html>”) 이렇게 줄줄이 써야 함 → JSP 등장(Java Server Page, 서버에서 돌아가는 자바) → 시니어, 주니어 개발자 갭차이가 많음 → Spring F/W발표(갭을 줄이기 위해 프레임워크 제시), 일본은 Struts1,2 쓰기도 → 우리나라는 전자정부프레임워크(200개), 자바공화국 시작(자바,스프링중요+오라클,리액트도 알면 좋음) → 프레임워크를 통해서 MVC패턴 주입받음 → 순수한 자바로 이루어진 MVC 미리 소개!
BookManager.java에 main메소드가 있음
사용자가 선택한 정보를 넘기는 방법 → 파라미터
String gubun = “bookMgr” or “boardMgr”
조회|수정|삭제|입력 → BookController로 연결
게시판 → BoardController로 연결
이와 같은 역할을 맡을 클래스 설계 → FrontController
package dev_java.bookMVC;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// 개발 방법론에서 디자인 패턴 중 MVC패턴을 알아보자
// M: 모델 계층(XXXLogic + XXXDao.java) -> 서비스계층(비즈니스 로직, 업무 계층)
// XXXDao가 있고 없고는 MVC패턴에 영향이 없다
// 다만 오라클서버와 연계에 반복되는 코드를 줄여주고 오픈소스나 라이브러리
// (iBatis, MyBatis-반자동, Hibernate-완전자동, SQL문이 없음)를 조립하기위한
// 요구사항으로 만들어 사용하는 클래스이다.
// 클래스 쪼개기(생성자) -> POJO(pure) -> Spring(maven) -> Spring boot(Gradle)-완결편
// V: 뷰 계층
// C: 컨트롤 계층
// 프레임워크를 왜 원하는가? - 실력차이를 줄여야함
// 틀이 정해짐 -> 클래스, 메소드 선언 되어있음(단 파라미터 타입, 개수는 결정해야함)
// 개발자는 비즈니스 로직에만 집중할 수 있음
//
public class BookManager extends JFrame implements ActionListener {
JButton jbtn_sel = new JButton("조회"); // SELECT문
JButton jbtn_ins = new JButton("입력"); // INSERT문
JButton jbtn_upd = new JButton("수정"); // UPDATE문
JButton jbtn_del = new JButton("삭제"); // DELETE문
JButton jbtn_board = new JButton("게시판");
JPanel jp_north = new JPanel();
String gubun = "bookMgr"; // 도서 CRUD면 bookMgr, 게시판 CRUD면 boardMgr
public BookManager() {
// initDisplay(); -> 주로 속지(JPanel, JScrollPane)로 사용되는 페이지일때 생성자 안에서 메소드 부름
// 요청에따른 페이지 갱신처리, 화면갱신, 화면 초기화
// 그러나 스레드 구현시에는 이슈가 발생하니까 주의해야함
// 문법에러 - 고치기 쉬움
// 논리에러 - 트러블슈팅 어렵다(NullPointerException), 예외상황과 관계있음 -> 500번에러
}
public void initDisplay() {
// 이벤트 소스와 이벤트 처리클래스 매핑하기
jbtn_sel.addActionListener(this);
jbtn_ins.addActionListener(this);
jbtn_upd.addActionListener(this);
jbtn_del.addActionListener(this);
jbtn_board.addActionListener(this);
// 화면에 추가
jp_north.add(jbtn_sel);
jp_north.add(jbtn_ins);
jp_north.add(jbtn_upd);
jp_north.add(jbtn_del);
jp_north.add(jbtn_board);
this.add("North", jp_north);
this.setTitle("도서관리 시스템 Ver.1.0");
this.setLocation(100, 100);
this.setSize(500, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
BookManager bManager = new BookManager();
// 메인에 initDisplay() -> 메인스레드와 Runnable을 통해서 구현하는 스레드를 분리할 수 있는 경우에 사용
// 메인스레드와 자기자신이run 구현체 클래스 역할을 병행하는 컨셉일 때
// 이렇게 안하면 지연발생(화면이 안뜨거나 소켓 accept가 발생안함, 그냥 죽은코드)
bManager.initDisplay();
// 리팩토링 -결과의 변경 없이 코드의 구조를 재조정(가독성, 유지보수성을 목표로함)
}
// Override(재정의) 하는 이유
// 장치마다(아이폰, 갤럭시, 아이패드) 결정되지 않았으니까
@Override
public void actionPerformed(ActionEvent e) { // 콜백함수
// 입력|수정|삭제|조회버튼이 클릭되면 이벤트를 JVM이 감지하고
// 감지되면 JVM이 actionPerformed 메소드를 알아서 호출해줌
Object obj = e.getSource();
BookController bookController = null;
BoardController boardController = null;
// 게시판 버튼을 눌렀을 때
if (obj == jbtn_board) {
System.out.println("게시판");
gubun = "boardMgr";
// 게시판 CRUD로 연결
if ("boardMgr".equals(gubun)) {
boardController = (BoardController) FrontController.getController(gubun);
System.out.println("게시판관리 선택 => " + boardController);
// 게시판 컨트롤러가 결정되면 다시 디폴트값으로 초기화
gubun = "bookMgr";
}
}
// 도서 CRUD로 연결
else if ("bookMgr".equals(gubun)) {
bookController = (BookController) FrontController.getController(gubun);
System.out.println("도서관리 선택 => " + bookController);
// if문은 무조건 조건을 따진다
// else if문은 앞 조건을 수렴하면 뒤에 있는 코드는 실행기회를 갖지 않는다
// 조회버튼을 눌렀을 때
if (obj == jbtn_sel) {
System.out.println("조회");
bookController.getBookList(gubun, gubun);
}
// 입력버튼을 눌렀을 때
else if (obj == jbtn_ins) {
System.out.println("입력");
bookController.bookInsert(null);
}
// 수정버튼을 눌렀을 때
else if (obj == jbtn_upd) {
System.out.println("수정");
bookController.bookUpdate(null);
}
// 삭제(탈퇴)버튼을 눌렀을 때
else if (obj == jbtn_del) {
System.out.println("삭제");
bookController.bookDelete(null);
}
}
}
}
package dev_java.bookMVC;
public class FrontController {
// 리턴타입을 Object로 한 이유 -> 사용자의 선택에따라 BookController 혹은 BoardController 연결해줘야하니까
public static Object getController(String gubun) {
// FrontController obj = null; // 상속관계로 처리했다면 이렇게 처리
Object obj = null; // extends, implements 없이 할 경우
if ("bookMgr".equals(gubun)) {
obj = new BookController();
} else if ("boardMgr".equals(gubun)) {
obj = new BoardController();
}
return obj;
}
}
package dev_java.bookMVC;
// 인터페이스는 추상메소드만 가질 수 있다
// 일반메소드, 생성자, 일반 전역변수 불가!
public interface Controller { // 인터페이스를 사용할 경우
public abstract FrontController geController(String gubun);
}
package dev_java.bookMVC;
import java.util.List;
import java.util.Map;
// public class BookController extends FrontController{ //상속받은 경우
// public class BookController implements Controller { // 인터페이스를 implements한 경우
public class BookController {
// BookLogic bookLogic = new BookLogic();
// 원래는 BookLogic 클래스를 객체주입해야하지만, 업무적인 depth가 얕아서
// 로직클래스에서 선택, 결정에따른 추가적인 프로세스가 전혀 없는 상태임
// 따라서 컨트롤러 클래스와 Dao 클래스 사이의 연결만 담당하니까 의미없음
BookDao bookDao = new BookDao();
// 조회
public List<Map<String, Object>> getBookList(String cols, String keyword) {
System.out.println("도서목록 조회");
List<Map<String, Object>> bList = null;
bList = bookDao.getBookList(cols, keyword);
return bList;
}
// 입력
public int bookInsert(BookVO bkVO) {
System.out.println("도서정보 등록");
int result = 0;
result = bookDao.bookInsert(bkVO);
return result;
}
// 수정
public int bookUpdate(BookVO bkVO) {
System.out.println("도서정보 수정");
int result = 0;
result = bookDao.bookUpdate(bkVO);
return result;
}
// 쿼리문을 보고 리턴 타입과 파라미터 타입 및 개수를 결정하는데 참고
// 삭제
// DELETE FROM book WHERE bk_no = 5;
// 리턴 타입 int - 1: 삭제성공 / 0: 삭제실패
// 파라미터 타입 int - 도서번호
public int bookDelete(BookVO bk_no) {
System.out.println("도서정보 삭제");
int result = 0;
result = bookDao.bookDelete(bk_no);
return result;
}
}
/*
* SQL 응용
* JAVA와 오라클 연동(연계)하기
* JDBC API(원시적) - MyBatis(반자동), 여기에 집중! - Hibernate(완전자동), 초보자에겐 독이다
*/
package dev_java.bookMVC;
import lombok.Data;
@Data
public class BookVO {
private int bk_no;
private String bk_title;
private int bk_price;
private String bk_date;
private String bk_publish;
private String bk_info;
private String bk_author;
}
package dev_java.bookMVC;
import java.util.List;
import java.util.Map;
public class BookDao {
/**
* 도서 목록 조회
* SELECT bk_no, bk_title FROM book
* WHERE bk_title(?) = ?
* WHERE bk_author(?) = ?
* WHERE bk_info(?) = ?
*
* @param cols - 컬럼명 bk_title or bk_author or bk_info
* @param keyword - 텍스트필드에 사용자가 입력한 값
* @return - 검색결과는 n개의 로우 List<Map<>>
* 조인이 필수적인 경우에는 반드시 List<Map<>> 형태가 유리하고
* 그렇지 않은 경우라면 List<XXXVO> 형태와 별 차이가 없다
* 단 조회결과로 얻은 정보를 자바코드에서 연산을 해야하는 경우라면
* 제네릭 타입으로 Map보다는 XXXVO가 유리하다
* Map이면 리턴값이 무조건 Object이다 -> ClassCastingException주의
* int i = Integer.parseInt(pMap.get("bk_no").toString());
* int i = xxxVO.getBkno();
*/
public List<Map<String, Object>> getBookList(String cols, String keyword) {
System.out.println("getBookList호출");
return null;
}
/**
* 도서 정보 입력
*
* @param bkVO - 입력요청으로 입력받은 값
* @return - 1: 입력성공 / 0: 입력실패
*/
public int bookInsert(BookVO bkVO) {
int result = 0;
System.out.println("bookInsert호출(사용자가 선택한 도서정보-주소번지) => " + bkVO);
return result;
}
/**
* 도서 정보 수정
*
* @param bkVO - 수정요청으로 입력받은 값
* @return - 1: 수정성공 / 0: 수정실패
*/
public int bookUpdate(BookVO bkVO) {
int result = 0;
// 롬복 어노테이션 @Data를 사용했기에 getter / setter 메소드는 없지만 사용가능함
// 단 VO타입이므로 전역변수에 담긴 값을 출력하려면 getter 메소드 호출함
// 전역변수는 캡슐화로인해 직접 접근 불가하고 위변조로 인한 피해로부터 보호하기 위해
// 접근제한자는 반드시 private로 할 것
System.out.println("bookUpdate호출(사용자가 선택한 도서정보-주소번지) => " + bkVO);
return result;
}
/**
* 도서 정보 삭제
*
* @param bk_no - 도서번호
* @return - 1: 삭제성공 / 0: 삭제실패
*/
public int bookDelete(BookVO bk_no) {
int result = 0;
System.out.println("bookDelete호출(사용자가 선택한 도서번호) => " + bk_no);
return result;
}
}
package dev_java.bookMVC;
public class BookLogic {
}
package dev_java.bookMVC;
// public class BoardController extends FrontController{ //상속받은 경우
// public class BoardController implements Controller { // 인터페이스를 implements한 경우
public class BoardController {
}
package dev_java.bookMVC;
import lombok.Data;
@Data
public class Book_BoardVO {
private int b_no;
private int mem_no;
private String b_title;
private String b_content;
private int b_hit;
}
package dev_java.bookMVC;
public class BoardDao {
}
package dev_java.bookMVC;
public class BoardLogic {
}
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day38 (0) | 2023.01.18 |
---|---|
국비 지원 개발자 과정_Day37 (0) | 2023.01.17 |
국비 지원 개발자 과정_Day35 (0) | 2023.01.13 |
국비 지원 개발자 과정_Day34 (0) | 2023.01.12 |
국비 지원 개발자 과정_Day33 (0) | 2023.01.11 |
댓글