<!DOCTYPE html>
<html>
<head> // head
<meta charset="UTF-8"> // 한글 입력
<title>김멋사의 이력서</title> // 제목
<link rel="stylesheet" href="codelion.css"> // CSS 적용
</head>
<body> // body
<div class="mainbox"> // div
<div class="title-box">
<h1>김멋사</h1>
<p class="name-text">HTML/CSS 개발자</p>
</div>
<section> // section = div = article
<h2>ABOUT ME</h2>
<p class="about-me-text">
Lorem ipsum dolor sit amet, ...
</p>
</section>
<section>
<h2>EXPERIENCE</h2>
<div class="float-wrap">
<p class="title-text">Awesome Programming Company</p>
<p class="year-text">2020 - Now</p>
</div>
<p class="desc-text">Front-End Web Developer</p>
<p class="desc-subtext">HTML/CSS, JS, React</p>
...
</section>
...
<footer> // footer
<p>Copyright CODE LION All rights reserved. </p>
</footer>
</body>
</html>
@import url('https://fonts.googleapis.com/css?family=Montserrat:
100,200,300,400,500,600,700,800&display=swap'); // font 적용 url
* { // 전체 코드 폰트 적용
font-family: 'Montserrat';
}
body {
min-width: fit-content; // 최소 너비
}
...
.mainbox {
width: 610px; // mainbox 너비
padding: 30px; // 안쪽 여백
margin: 30px; // 바깥쪽 여백
margin-right: auto; // auto : 값 자동 설정
margin-left: auto;
border: 1px solid #ebebeb; // 테두리
box-shadow: 0 1px 20px 0 rgba(0, 0, 0, 0.1); // 그림자 적용
(가로, 세로, 흐림 반경, 확산 거리, 투명도)
}
.title-box {
text-align: right; // 텍스트 정렬 : 오른쪽
}
.float-wrap {
overflow: hidden; // 밖으로 넘치는 컨텐츠 숨김
}
.title-text {
font-size:11px; // 폰트 크기
font-weight: bold; // 폰트 굵기
color: #282828; // 폰트 색깔
float: left; // 겹치지 않게 배치 : 왼쪽
}
그래들(Gradle)은 빌드 도구이며 라이브러리 관리도구
프로그램을 개발자가 아닌 일반 사용자가 사용할 수 있는 상태로 만드는 것을 '빌드'
라고 한다. (자바에서는 .jar 파일로 만드는 것)
라이브러리를 쉽게 추가 할 수 있고 추가한 라이브러리가 빠짐없이 .jar 파일로 빌드 할 수 있게 관리 해준다. 메이븐(Maven)이라는 도구도 있다.
프로그램은 JDBC(Java Database Connectivity)를 사용하여 MySQL 데이터베이스에 연결한다.
com.mysql.cj.jdbc.Driver
클래스는 MySQL 드라이버를 로드하기 위해 Class.forName()
메서드를 사용
DriverManager.getConnection()
메서드를 사용하여 데이터베이스에 연결
localhost
는 데이터베이스 서버의 호스트 이름
test-db1
은 연결할 데이터베이스의 이름
"root"
와 "12345678"
은 데이터베이스에 액세스하기 위한 사용자 이름과 비밀번호
연결이 성공하면 Connection
객체인 con을 사용하여 Statement
객체를 만든다.
st.executeQuery()
메서드를 사용하여 "SHOW DATABASES"
SQL 쿼리를 실행하고, 그 결과로 ResultSet
객체를 얻음
while
루프를 사용하여 결과 집합에서 각 행을 반복하고, rs.getString(1)
을 사용하여 첫 번째 열의 값을 가져옴
이 값을 System.out.println()
을 사용하여 콘솔에 출력
main()
메서드에서는 ConnectChecker
클래스의 인스턴스를 만들고 check()
메서드를 호출하여 프로그램을 실행한다.
Statement st = con.createStatement();
con이라는 Connection
객체를 사용하여 SQL 문을 실행하는 Statement
객체를 생성 (SQL 쿼리를 데이터베이스로 전송하는 데 사용)
ResultSet rs = st.executeQuery("SHOW DATABASES");
st라는 Statement
객체를 사용하여 "SHOW DATABASES"
라는 SQL 쿼리를 실행하고 그 결과를 ResultSet
객체에 저장
executeQuery()
메서드는 주로 SELECT 문과 같은 SQL 문에서 사용되며, MySQL 서버에 있는 모든 데이터베이스의 리스트를 반환
ResultSet
은 일종의 테이블로, 데이터베이스 쿼리의 결과를 나타냄
next()
메서드를 호출하여 각 행을 순서대로 검색할 수 있다.
각 행의 특정 열 값을 가져오려면 getString(), getInt()
등의 메서드를 사용할 수 있다.
이 경우 rs.getString(1)
은 첫 번째 열의 값을 문자열로 가져온다.
"SHOW DATABASES"
쿼리의 경우, 이 값은 데이터베이스의 이름이다.
SQL Injection 방지
Statement
는 SQL 쿼리에 파라미터를 문자열 결합을 통해 직접 삽입한다.
SQL Injection 공격에 취약할 수 있다.
PreparedStatement
는 파라미터를 안전하게 처리하여 SQL Injection 공격을 방지한다. 이는 데이터베이스에 안전하게 값을 삽입할 수 있다.
성능
Statement
는 SQL 쿼리를 실행할 때마다 쿼리를 컴파일하고 최적화해야 한다.
PreparedStatement
는 동일한 SQL 쿼리를 반복적으로 실행하는 경우에 더 효율적이다. (쿼리 계획을 재사용)
사용 편의성
Statement
를 사용하여 SQL 쿼리에 값을 삽입할 때는 개발자가 수동으로 문자열 결합을 관리해야한다.
PreparedStatement
는 SQL 쿼리에 파라미터를 쉽게 삽입할 수 있도록 ?
를 통한 placeholder
를 제공한다. (코드의 가독성과 유지 보수성을 향상시킴)
요약하자면, PreparedStatement
는 Statement
에 비해 여러 가지 이점을 제공하므로 대부분의 경우에 PreparedStatement
를 사용하는 것이 좋다.
그러나 SQL 쿼리를 한 번만 실행하고 별도의 파라미터가 없는 간단한 경우에는 Statement
를 사용해도 충분하다.
alt + insert
추가만 하고 새로고침 버튼을 누르지 않으면 다운로드를 받지 않는다.
import java.sql.*;
import java.util.Map;
import static java.lang.System.getenv;
public class ConnectionChecker {
public void select() throws SQLException, ClassNotFoundException { // select 메소드
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 con = DriverManager.getConnection(
dbHost,
dbUser,
dbPassword
);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users"); // users 테이블의 데이터 출력
rs = st.getResultSet();
while (rs.next()) {
String str = rs.getString(1); // 3
String str2 = rs.getString(2); // kyeongrok
String str3 = rs.getString(3); // 1234567
System.out.printf("%s %s %s\n", str, str2, str3);
}
}
public void check() throws SQLException, ClassNotFoundException { // DB 와 연동 확인
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 con = DriverManager.getConnection(
dbHost,
dbUser,
dbPassword
);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SHOW DATABASES");
rs = st.getResultSet();
while (rs.next()) {
String str = rs.getString(1);
System.out.println(str);
}
}
public void add() throws ClassNotFoundException, SQLException { // add 메소드
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 con = DriverManager.getConnection(
dbHost,
dbUser,
dbPassword
);
PreparedStatement pstmt = con.prepareStatement("insert into users(id, name, password) values(?, ?, ?)"); // users 테이블에 insert
pstmt.setString(1, "3");
pstmt.setString(2, "kyeongrok");
pstmt.setString(3, "1234567");
pstmt.executeUpdate();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
ConnectionChecker cc = new ConnectionChecker();
cc.check();
cc.add();
cc.select();
}
}
getenv()
자바의 System 클래스에 있는 정적 메서드로, 현재 실행되고 있는 프로세스의 환경 변수를 반환한다.
운영 체제에서 사용하는 이름이 부여된 값들의 집합. 대부분 시스템 설정 정보를 포함하고 있으며, 운영 체제와 다양한 애플리케이션들이 이 정보를 참조하여 실행 환경을 구성하거나 특정한 동작을 수행한다.
DB_HOST 라는 이름에 jdbc:mysql:// ~~~ 값이 들어있다.
DB_USER 는 user_name
…
https://school.programmers.co.kr/learn/courses/30/lessons/181936
16:15 ~ 16:45
class Solution {
public int solution(int number, int n, int m) {
int result = 0;
for (int i = 0; i < number; i++) {
if (number % n == 0 && number % m == 0) {
result = 1;
} else {
result = 0;
}
}
return result;
}
}
https://school.programmers.co.kr/learn/courses/30/lessons/181840
17:00 ~ 17:30
class Solution {
public int solution(int[] num_list, int n) {
int answer = 0;
for (int i = 0; i < num_list.length; i++) {
if (num_list[i] == n) answer = 1;
else answer = 0;
}
return answer;
}
}
이유는 else
문 때문에 1로 나올 답이 0으로 지나간다.
예를 들어 [1, 2, 3, 4, 5]
중에서 n = 3
이면
1 = 0
2 = 0
3 = 1
4 = 0
5 = 0
answer = 0 출력
class Solution {
public int solution(int[] num_list, int n) {
int answer = 0;
for (int i = 0; i < num_list.length; i++) {
if (num_list[i] == n) answer = 1;
}
return answer;
}
}
else
문만 제거하면 된다.
오전 수업은 이두희 대표님의 HTML/CSS 강의를 수강했다. 처음 코딩을 시작한게 HTML/CSS 였는데 오랜만에 수업을 다시 들어보니 문득 재미와 고통을 맛보던 그 때가 떠올랐다. 현재는 java와 DB를 배우고 있는데 다시 생각해보면 HTML/CSS는 아주아주아주 양반이었다. 옛 생각이 나던 재밌는 수업이었지만 내일은 한 번도 배운적 없는 JS를 수강해야한다. 오늘 오후 수업도 진도가 쉽지 않았는데 큰 걱정이 된다.
오후 DB 시간에 역시나 시작하자마자 에러를 맞이했다. 하지만 에러를 마주한다고 땀내던 처음과는 달리 오늘은 차분하게 에러들을 해결했다. 알고리즘은 정말 욕나오게 재미가 없는데 DB는 에러를 줄줄이 마주해도 욕나오게 재밌다. 내가 겪은 에러를 직접 해결하고나니 같은 상황의 수강생들에게 도움을 줄 수 있어 매우 뿌듯했다. 오늘은 이만하면 만족했다 내일도 JS 이겨내보자.