JavaScript는 HTML 안에 코드를 쓸 수 있고, js 파일로 따로 빼서 작성할 수 있다. 보통 내용이 많은 경우 js 파일로 따로 빼서 작성하는 것이 코드 가독성이 좋아 선호되지만, 간단한 문법 같은 경우는 HTML 안에서 묶어 작성하기도 한다. HTML 안에 사용하는 방법은 다음과 같다.
<body>
<scrip>
document.write("Hello")
</scrpt>
</body>
// 보통 바디 태그 끝나기 전에 사용
따로 뺀 js 파일을 HTML에서 연결해 주는 방법은 다음과 같다.
<body>
<scrip src="./myScript.js"></scrpt>
</body>
// 보통 바디 태그 끝나기 전에 사용
javascript는 하나의 명령어가 끝날 때마다 세미콜론으로 표시한다. 하지만 javascript는 유연한 언어라서 세미콜론이 없이 들여쓰기만 있어도 하나의 명령어로 인식하지만, 습관을 들이는 것이 좋다. javascript의 주석은 //를 사용해서 덧붙일 수 있다. 여러 줄의 주석은 / ~~ / 를 통해 작성할 수 있다.
Javascript에서 데이터들을 담고 있는 변수로 var 타입을 지원한다. 최신 문법인 ES6에서는 let이나 const를 사용해 주기도 한다.
String, boolean, int 등 자료형이 있는데 javascrip는 인터프리터 언어라서 타입을 미리 지정해 주지 않아도 된다.
var name = '엄준식';
document.write(typeof(name));
// String
6개의 숫자를 임의로 추첨하기 전에 먼저 하나의 숫자를 뽑는다고 생각해 보자. javascript에서 0이상 1미만의 실수인 float형을 하나 뽑는 라이브러리는 Math.random();
이다. 이때 공의 범위가 1~45 이기 때문에 45를 곱한 뒤 1을 더해 주고 소수점을 버리도록 int형으로 형변환을 시켜 주면 조건에 맞는 공 추첨이 가능해진다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>로또 번호 추첨기 1</title>
</head>
<body>
<h1>로또 번호 추첨기 1</h1>
<script>
var ball_one = parseInt(Math.random() * 45 + 1);
document.write(ball_one);
</script>
</body>
</html>
공을 여섯 개 만들어야 하는데, 이를 수도 없이 많이 만들면 변수가 무수히 많아진다. 이는 효율적인 자료 관리가 어려워진다. 따라서 자료형을 묶어서 사용하는 배열을 이용한다. 배열은 var lotto = [1, 2, 3, 4, 5, 60]; 와 같이 대괄호를 사용하여 선언할 수 있다. 배열을 통해 로또 번호를 생성하고 배열에 도로 저장하는 방법은 다음과 같다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>로또 번호 추첨기 1</title>
</head>
<body>
<h1>로또 번호 추첨기 1</h1>
<script>
var lotto = [];
for (let i = 0; i < 6; i++) {
lotto.push(parseInt(Math.random() * 45 + 1));
}
</script>
</body>
</html>
이때 만약 lotto 안에 중복되지 않는 값이라면 push하도록 조건문을 활용해 바꿀 수 있다. 그 코드는 다음과 같다. 이때 ===
코드는 값, 타입까지 모두 같은지 검사하는 것이다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>로또 번호 추첨기 1</title>
</head>
<body>
<h1>로또 번호 추첨기 1</h1>
<script>
var lotto = [];
for (let i = 0; i < 6; i++) {
var ball = parseInt(Math.random() * 45 + 1);
if (lotto.indexOf(ball) === -1) {
lotto.push(ball);
}
}
</script>
</body>
</html>
마지막에 넣을 요소가 중복되는 값이라면 총 다섯 개의 공만 lotto에 있게 된다. 따라서 여섯 번 반복하는 게 아니라 공이 여섯 개가 될 때까지 반복해야 한다. 이를 while문으로 구현할 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>로또 번호 추첨기 1</title>
</head>
<body>
<h1>로또 번호 추첨기 1</h1>
<script>
var lotto = [];
while(lotto.length < 6) {
var ball = parseInt(Math.random() * 45 + 1);
if (lotto.indexOf(ball) === -1) {
lotto.push(ball);
}
}
</script>
</body>
</html>
이를 오름차순 방식으로 정렬할 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>로또 번호 추첨기 1</title>
</head>
<body>
<h1>로또 번호 추첨기 1</h1>
<script>
var lotto = [];
while (lotto.length < 6) {
var ball = parseInt(Math.random() * 45 + 1);
if (lotto.indexOf(ball) == -1) {
lotto.push(ball);
}
}
lotto.sort((a, b) => a - b);
document.write(lotto);
</script>
</body>
</html>
DAO (Data Access Object)
DAO (Data Access Object)는 DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트이다.
JDBC를 이용한 작업의 일반적인 순서는 다음과 같다.
User라는 오브젝트를 주고받기 위해 User class를 새로 만들어 준다.
create table User
(
id varchar(45) not null,
name varchar(45) null,
password varchar(45) null,
constraint user_pk
primary key (id)
);
이후 domain package에서 User class와 getter, setter method를 만들어 준다.
package com.example.tobyspring3.domain;
public class User {
private String id;
private String name;
private String password;
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
}
UserDao Class를 만들어서 User table에 레코드를 하나 추가해 주는 코드를 작성한다. 마찬가지로 git hub에 코드를 올렸을 때 데이터를 보안해야 하기 때문에 주요 정보는 Envirionmental Variable로 지정하여 사용한다. UserDao class를 한 번 실행하면 run configuration이 생기는데, 이 안에서 다음과 같이 Environmental Variable을 설정할 수 있다.
DB_HOST: jdbc:mysql//<주소>:3306/<schema이름>
DB_HOST: 사용자 이름
DB_PASSWORD: 비밀번호
이때 jdbc는 DB 접속 프로토콜이고, mysql은 DB 종류, 3306은 포트 번호이다.
package com.example.tobyspring3.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import static java.lang.System.getenv;
public class UserDao {
public void add() throws ClassNotFoundException, SQLException {
Map<String, String> env = getenv();
String dbHost = env.get("DB_HOST");
String dbUser = env.get("DB_USER");
String dbPassword = env.get("DB_PASSWORD");
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(
dbHost, dbUser, dbPassword
);
PreparedStatement pstmt = conn.prepareStatement("insert into User(id, name, password) values(?, ?, ?)");
pstmt.setString(1, "1");
pstmt.setString(2, "kyeongrok");
pstmt.setString(3, "12345678");
pstmt.executeUpdate();
pstmt.close();
conn.close();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
UserDao userDao = new UserDao();
userDao.add();
}
}
value 하나하나를 직접 입력하는 방식이 아닌, 앞서 만든 User class를 사용해서 parameter로 넘겨 INSERT하는 방법은 다음과 같다.
package com.example.tobyspring3.dao;
import com.example.tobyspring3.domain.User;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import static java.lang.System.getenv;
public class UserDao {
public void add(User user) throws ClassNotFoundException, SQLException {
Map<String, String> env = getenv();
String dbHost = env.get("DB_HOST");
String dbUser = env.get("DB_USER");
String dbPassword = env.get("DB_PASSWORD");
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(
dbHost, dbUser, dbPassword
);
PreparedStatement pstmt = conn.prepareStatement("insert into User(id, name, password) values(?, ?, ?)");
pstmt.setString(1, user.getId());
pstmt.setString(2, user.getName());
pstmt.setString(3, user.getPassword());
pstmt.executeUpdate();
pstmt.close();
conn.close();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
UserDao userDao = new UserDao();
User user = new User();
user.setId("2");
user.setName("huisu");
user.setPassword("2459810");
userDao.add(user);
}
}
내가 원하는 id 값을 가진 User 객체를 가져오는 코드는 다음과 같다. Insertion 작업과 다르게 DB로부터 조회한 결과가 있기 때문에 ResultSet에 값을 받아서 객체로 저장해 주는 작업이 따로 필요하다.
public User get(String id) throws ClassNotFoundException, SQLException {
Map<String, String> env = getenv();
String dbHost = env.get("DB_HOST");
String dbUser = env.get("DB_USER");
String dbPassword = env.get("DB_PASSWORD");
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(
dbHost, dbUser, dbPassword
);
PreparedStatement pstmt = conn.prepareStatement("select id, name, password from User where id = ?");
pstmt.setString(1, id);
ResultSet rs = pstmt.executeQuery(); // 내가 요청한 결과값이 rs에 담아옴
rs.next();
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
// 안 닫아 주면 계속 연결돼 있음 -> 연결만 늘어나서 서비스 장애가 생길 수 있음
pstmt.close();
conn.close();
rs.close();
return user;
}
insert와 delete 모두에서 연결이 생성되는 부분이 겹치는 것을 확인할 수 있다. 따라서 연결만 생성하는 부분을 따로 빼서 method로 처리해 주면 다음과 같은 코드가 완성된다.
package com.example.tobyspring3.dao;
import com.example.tobyspring3.domain.User;
import java.sql.*;
import java.util.Map;
import static java.lang.System.getenv;
import static java.lang.System.setOut;
public class UserDao {
public Connection getConnection() throws ClassNotFoundException, SQLException {
Map<String, String> env = getenv();
String dbHost = env.get("DB_HOST");
String dbUser = env.get("DB_USER");
String dbPassword = env.get("DB_PASSWORD");
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(
dbHost, dbUser, dbPassword
);
return conn;
}
public void add(User user) throws ClassNotFoundException, SQLException {
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement("insert into User(id, name, password) values(?, ?, ?)");
pstmt.setString(1, user.getId());
pstmt.setString(2, user.getName());
pstmt.setString(3, user.getPassword());
pstmt.executeUpdate();
pstmt.close();
conn.close();
}
public User get(String id) throws ClassNotFoundException, SQLException {
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement("select id, name, password from User where id = ?");
pstmt.setString(1, id);
ResultSet rs = pstmt.executeQuery(); // 내가 요청한 결과값이 rs에 담아옴
rs.next();
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
// 안 닫아 주면 계속 연결돼 있음 -> 연결만 늘어나서 서비스 장애가 생길 수 있음
pstmt.close();
conn.close();
rs.close();
return user;
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
UserDao userDao = new UserDao();
User user = new User();
user.setId("2");
user.setName("huisu");
user.setPassword("2459810");
User selectuser = userDao.get("1");
System.out.println(selectuser.getId());;
System.out.println(selectuser.getName());
System.out.println(selectuser.getPassword());
}