while문은 특정 조건이 주어지고, 참인 경우에만 구문을 반복. 거짓인 경우는 종료한다.
반복문은 반드시 : 을 붙여야 작동한다!!
1. for문
리스트에서 1~4번째를 호출해야한다. 리스트 → 호출 이니까 앞에만 -1 하여 [0:4]가 된다. 그러니까 range 범위를 아무 생각 없이 (0,4,)로 넣으면 된다고 생각할 수 있으나 리스트와 호출에서 생각하는 번호와 range 함수에서 범위는 개념이 다르다.물론, [0:4]가 0+1번째 ~ 4+1번째 전. 즉, :4]의 값은 들어가지 않기 때문에 (,4,)에서 4 이상이 나오면 정지시키는 range 함수에 의해 값이 포함되지 않기 때문에 그대로 (0,4,)를 넣으면 되는게 맞다. 단, 리스트의 index와 range 범위는 전혀 다른 개념이니 아래를 참고할 것.
sysout + 자동완성 : System.out.println(); 이 자동으로 타이핑 된다.
cf. Preferences -> Templates 검색 -> 여기 가면 다양한 자동완성 탬플릿이 있다. 만약 필요하다면 추가하고, 안 쓰는게 자꾸 자동완성 된다면 꺼버리자.
Command + Option + 'R' : 프로젝트나 클래스 이름 변경. (우클릭 -> Refactor -> Rename 과 같다.)
Command + Option + 'V' : 자바 파일 이동. (그냥 드래그 앤 드랍으로 다른 프로젝트로 옮기면 작동 안 한다.)
자료형 및 기본 문법
int, long : 정수 / Integer : 정수 (int는 단순 자료형으로 객체가 아니고, Integer는 클래스로 객체다.) float, double : 실수 String, char : 문자열, 문자 (전부 소문자로 시작하는데 문자열만 대문자로 시작한다. 문자열은 쌍따옴표, 문자는 따옴표) boolean : 참/거짓
자료형변수명 = 값;형태로 쓴다. i.e. intage = 25; 자료형 배열명[] = {값1,값2,값3...};형태로 쓴다. i.e. int score[] = {80,70,90,100,60,80,90,70}; 자료형 []배열명 = {값1,값2,값3...}; 형태도 가능하다. i.e. int[] score = {80,70,90,100,60,80,90,70};
new : 초기화, 인스턴스 생성, 포맷 -> 메모리 주소를 할당한다는거다. 사용하도록 하겠다.
ABC.split("K") : ABC라는 변수가 가진 문자열을문자열 "K"로분리해서 배열로 만든다.
ABC.replace("abc","def") : ABC라는 변수가 가진 문자열을에서"abc" 를 "def"로치환 한다.
ABC.split(K): ABC라는 변수가 가진문자열을K라는 변수가 가진 문자열로분리해서 배열로 만든다.
main() 메소드가 있는 클래스 : 실행 클래스. 해당 패키지 내에서 프론트엔드에 해당하는 부분.
main() 메소드가 없는 클래스 : 함수 클래스. 해당 패키지 내에서 백엔드에 해당하는 부분. public클래스명() : 클래스명을 메소드 이름으로 갖는 메소드 -> 생성자(초기값 설정). public void메소드명() : return이 없는 메소드. public int메소드명() : return 타입이 int인 메소드.
클래스명extends클래스명:클래스명을Super 클래스로 갖는클래스명(Sub 클래스) 클래스명 : Sub 클래스 클래스명 : Super 클래스
클래스명implements인터페이스명:인터페이스명을 규약을 통해 참조하는 클래스명
형변환
(int)123.456 (double)20
Integer.parseInt(ABC) : ABC를 숫자로 형변환. Integer.toString(123) : 123을 문자로 형변환. (Integer만 Double로 바꿔서 응용 가능하다.)
import java.util.Scanner;
publicclassscannerreview{
publicstaticvoidmain(String[] args){
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
System.out.print(line);
}
}
입력 : 학교 종이 땡땡땡
출력 : 학교 // 띄어쓰기가 나오면 종료되어 뒤에는 입력을 받지 못해서 그렇다.import java.util.Scanner;
publicclasshomework_revieew{
publicstaticvoidmain(String[] args){
Scanner scanner = new Scanner(System.in);
String word = scanner.next();
System.out.print(word);
}
}
입력 : 학교 종이 땡땡땡
출력 : 학교 종이 땡땡땡
import java.util.Random;
publicclassrandomreview{
publicstaticvoidmain(String[] args){
Random r = new Random();
int dice = r.nextInt(6);
System.out.println(dice + 1);
}
}
결과 :
6 미만의 수 0, 1, 2, 3, 4, 5가 실행할 때마다 랜덤으로 나온다.
따라서 +1을 해줬으니 1~6의 수가 랜덤으로 출력된다.
dataReader.open(); // DataReader를 연다.try {
MessageDigest digest = MessageDigest.getInstance("SHA-256"); // SHA 알고리즘 클래스 호출.byte[] hash = digest.digest(password.getBytes("UTF-8")); // 암호화 할 데이터를 "UTF-8"로 읽어 위에서 만든 알고리즘을 이용해 해쉬를 한다.
StringBuffer hexString = new StringBuffer(); // 문자열을 잠시 담기 위한 버퍼 호출.// 해쉬한 문자열을 16진수(hex)로 바꿔주는 로직.for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
// 이 위에는 password 변수가 담은 값을 SHA-256을 하는 과정이고, 실제 DB에 Insert 쿼리를 보내는건 아래 한 줄이다.
dataReader.insertData(name, id, hexString.toString()); // password 변수 대신 hexString.toString()을 넣어야 SHA-256 암호화 한 데이터를 보낸다.
} catch (Exception ex) {
thrownew RuntimeException(ex); // RuntimeException을 추가한다.
}
dataReader.close(); // DataReader를 닫는다.
CSS (.jsp 파일 head에 추가) (CSS 파일 위치 : 프로젝트 > src > main > sebapp > resources)
1) PreparedStatement와Statement는 query를 쓰는 위치가 다르다. 2)int result 는 쿼리의 실행 결과 return값이 없어도 되지만, ResultSetresultSet 는 쿼리의 실행 결과 return값이 반드시 필요하다. ResultSet은 쿼리의 실행 결과를 ResultSet이라는 객체로 받는다. 따라서, INSERT, UPDATE와 같은 return값이 없는 쿼리의 경우는 intresult 를 써야하고, SELECT와 같이 return값이 있는 쿼리의 경우는 ResultSetresultSet 를 써서 return값을 객체로 받아야 다시 HomeController에 return을 할 수 있다.
DataReader 메소드의 return 형태에 따른 차이
publicint 메소드(인풋 파라미터) throws SQLException {
String query =
PreparedStatement preparedStatement = this.connection.prepareStatement(query); // PreparedStatement를 이용해 접속 엔진을 연다.
preparedStatement.setString(1, 값);
preparedStatement.setString(2, 값);
int result = preparedStatement.executeUpdate(); // .executeQuery()의 return값은 boolean이라 int result에 담을 수 없다. 최종 return값인 result가 int형태기 때문에 .executeUpdate()로 쿼리를 보내야한다.
preparedStatement.close();
return result; // return값은 int 형태여야한다. (하지만 위 HomeController는 이 메소드를 호출한 다음 return값은 받지 않는다. 메소드는 return을 보내지만 HomeController에서 return값을 받지 않음.)
}
publicboolean 메소드(인풋 파라미터) throws SQLException {
boolean result = false;
String query =
PreparedStatement preparedStatement = this.connection.prepareStatement(query);
preparedStatement.setString(1, 값); // 1번째 물음표
preparedStatement.setString(2, 값); // 2번째 물음표
ResultSet resultSet = preparedStatement.executeQuery(); // ResultSet은 쿼리 결과를 그대로 받아온다.if (resultSet.next()) {
result = true; // ResultSet을 이용해 일치하면 return값인 result에 boolean 형태의 값을 넣너준다.
}
resultSet.close();
preparedStatement.close();
return result; // return값은 boolean 형태여야한다. (위 HomeController에서 return값을 받아 사용한다.)
}
파라미터에 String이 아닌 Int값을 넣고 싶다면 preparedStatement.setInt(1, 값);을 사용한다.
여러개를 조회할 때는 while로 조회하고, 하나만 선택할 때는 if로 조회한다.
setString 일 때는 if (resultSet.next())로 조회했지만, setInt 일 때는 while(resultSet.next())로 조회한다.(?? 확인 필요)
String query = "INSERT INTO " + this.dbTableName + " (name, id, pw, nclass, address, phone, created) values(?,?,?,?,?,?,?);";
String query = "SELECT * FROM " + this.dbTableName + " WHERE id=? AND pw=?;" ;
String query = "UPDATE " + this.dbTableName + " SET name=?, nclass=?, address=?, phone=?, modified=? WHERE id=?;";
String query = "DELETE FROM " + this.dbTableName + " WHERE " + " id=?; " ;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = dateFormat.format(System.currentTimeMillis());
<!-- form 태그는 type="submit" 버튼을 누르면 action을 실행한다. name은 각각 파라미터 이름이 되고, 입력된 값은 각 파라미터의 값이 된다. HomeController에서 HttpServletRequest가 .getParameter를 통해 파라미터와 값에 접근한다. --><formaction="/Users/signup_action"method = "post">
이름 <inputtype="text"name="name"placeholder="이름을 입력해주세요" /><br />
ID <inputtype="text"name="id"placeholder="아이디를 입력해주세요" /><br />
PW <inputtype="password"name="password"placeholder="패스워드를 입력해주세요" /><br /><br /><inputtype="submit"name=""value="회원가입" /></form>
jsp 파일과 html 파일 사용의 차이
jsp 파일을 만들 경우, 컨트롤러(서버)에 각 페이지의 jsp파일을 html 파일로 컴파일해서 보내주는 라우터를 만들어야한다. 따라서, home.jsp가 있다면 home.jsp를 html로 컴파일해서 보내주는 라우터가 하나 필요하다. 하지만 처음부터 html파일로 만들 경우 서버는 요청이 들어오면 자동으로 html파일을 보내주기 때문에 라우터가 필요 없다. 이후는 jsp, html 모두 동일하게 해당 페이지에서 요청하는 CRUD 기능 개수만큼 라우터를 만들어주면 된다. 예를 들어 home이라는 페이지가 있고, 그 페이지에서 CRUD 액션이 하나씩 있다면 필요한 라우터는 아래 표와 같다.
jsp
html
home.html 페이지 요청에 응답하는 라우터
@GetMapping("/home") public String home(Model model) { return "home"; }
라우터 필요 없음
C
@PostMapping("/home_action") public String homeInsert(Model model) { return response; }
@PostMapping("/home_action") public String homeInsert(Model model) { return response; }
R
@GetMapping("/home_action") public String homeSelect(Model model) { return response; }
@GetMapping("/home_action") public String homeSelect(Model model) { return response; }
U
@PutMapping("/home_action") public String homeUpdate(Model model) { return response; }
@PutMapping("/home_action") public String homeUpdate(Model model) { return response; }
D
@DeleteMapping("/home_action") public String homeDelete(Model model) { return response; }
@DeleteMapping("/home_action") public String homeDelete(Model model) { return response; }
CRUD의 return type은 response로 보낼 데이터에 따라 String, int, MashMap, ArrayList 등으로 적당히 바꿔 사용하면 된다. i.e. public HashMap<String, Object> homeSelect(Model model)
Playground에서 정지 버튼을 누르고 좌측 숫자 옆에 재생 버튼을 누르면 그 행까지만 실행한다. (Shfit + return과 동일) Shift + return을 반복해서 한줄씩 내려가며 디버깅하기 좋음.
자료형
Int : 정수 (기본적으로 Int만 써도 Int64로 설정된다. 그보다 작은 단위를 쓰려면 Int8, Int16, Int32 등으로 사용.)
UInt : 0 ~ 양의 정수. Int의 64비트 표현 범위가 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 인데 이걸 음수의 표현 범위를 전부 양수로 돌린다. 따라서 0부터 (9,223,372,036,854,775,807 + 9,223,372,036,854,775,808)까지 표현이 가능하다. 즉, 최대로 표현할 수 있는 양의 정수 크기는 Int일 때의 9,223,372,036,854,775,807 x 2 + 1 이다.
Float, Double : 실수 (Float은 32비트, Double은 64비트다. 단, Float도 Int 의 9,223,372,036,854,775,807 보다는 큰 수를 표현할 수 있다.)
Sring, Character : 문자
Bool : 참/거짓
var : 변수
let : 상수
\(변수 또는 계산식) : 문자열 내에 이런 형태가 있을 경우 문자가 아니라 변수나 계산식을 의미한다.
var helloString:String="Score"// 문자열이 들어갈 수 있다.var helloCharacter:Character="A"// 단일 문자만 들어갈 수 있다.print("\(helloString)\(helloCharacter)") // "Score + 공백 1칸 + A"var helloString1 ="Good"// 생략하면 스위프트가 알아서 판단함.var helloString2 = helloString1 +" morning"// 문자열끼리 더할 수 있다.print(helloString2)
print("\(helloString2) friends!") // \( )는 문자 안의 변수나 계산식이다.
결과 :
ScoreAGood morning
Good morning friends!
var itemCount1:Int=10// 정수로 선언.print(itemCount1)
var itemCount2 =10// 생략하면 스위프트가 알아서 판단함. 위와 같다.print(itemCount2)
var itemCount3:Double=10// 실수로 선언.print(itemCount3)
var itemCount4 =10.0// 생략하면 스위프트가 알아서 판단함. 위와 같다.print(itemCount4)
결과 :
101010.010.0
< 상수 >
letpi:Double =3.14 / 변하면 안 되는 상수(constant)를 선언할 때 사용한다. 아래 코드블럭 예를 참고.
var i =2// i = 2로 선언print(i)
i = i +2// i에 2가 더해져 4가 됨.print(i)
let j =2print(j)
j = j +3// 상수에 값을 더하라 해서 에러 발생!!
< 문자와 print()문, 기본 개행 >
파이썬의 print(" {} {} ".format(변수1,변수2)) 와 비슷하다. 문자열 내에 이 녀석이 있으면 문자가 아니라 변수나 계산식이다.
var helloString:String="Score"// 문자열이 들어갈 수 있다.var helloCharacter:Character="A"// 단일 문자만 들어갈 수 있다.print("\(helloString)\(helloCharacter)") // "Score + 공백 1칸 + A"var helloString1 ="Good"// 생략하면 스위프트가 알아서 판단함.var helloString2 = helloString1 +" morning"// 문자열끼리 더할 수 있다.print(helloString2)
print("\(helloString2) friends!") // \( )는 문자 안의 변수나 계산식이다.
결과 :
ScoreAGood morning
Good morning friends!
스위프트는 print()를 하면 라인 하나에 하나씩 출력되는 파이썬과 같다. 따라서 다음 프린트문 넘어가기 전에 \n을 하면 개행을 2번 한 것과 같은 결과가 나온다.
print("Hello world\n") // Hellow world를 찍어라. (기본적으로 파이썬처럼 한 줄에 하나의 명령이 들어가서 자동 개행된다.) (자바는 개행을 수동으로 해줘야 함.)print("Hello world\n") // Hellow world를 찍고 개행을 해라. (기본 개행에 \n개행을 한 번 더 해서 2번 개행된다.)print("\nHello world") // 개행을 하고 Hellow world를 찍어라.print("\tHello world") // 탭을 하고 Hellow world를 찍어라.print("\n\tHello world") // 개행을 한 다음 탭을 하고 Hello world를 찍어라.print("\(3+2)") // \( )에 의해 변수 또는 계산식이 된다.print("3+2") // "3+2"라는 문자로 인식.
결과 :
Hello world
Hello world
Hello world
Hello world
Hello world
53+2242
var intValue:Int=Int(123.75) // 형변환 없이 Int로 선언한 변수에 123.75를 입력하면 오류 발생.print(intValue)
var price:Int=100var totalPrice =Double(price) *1.1// 그냥 더하면 에러남. Double로 형변환 해야 계산됨.print(Int(totalPrice))
결과 :
123110
2. 숫자 → 문자의 형변환: 문자 변수 내에 숫자 변수를 넣기 위해선 형변환이 필요하다.
(주의!문자열 내에 \(변수 또는 계산식)을 삽입하는 것과 혼동하지 말자. 문자 + 문자에 문자가 아닌 다른 자료형이 들어가면 에러가 발생하기 때문에 형변환이 필요하다. 아래 코드블럭을 참고하자.)
var maskCount:Int=100var message:String="mask "+String(maskCount) +" remains"// 형변환 하지 않으면 에러 발생.print(message)
print("maks "+String(maskCount) +" remains") // 형변환 하지 않으면 에러 발생.print("maks \(maskCount)"+" remains")
print("maks \(maskCount) remains")
결과 :
mask 100 remains
maks 100 remains
maks 100 remains
maks 100 remains
pd.DataFrame(zip(ABC,DEF), columns=[' ',' ']) : ABC, DEF 리스트를 데이터프레임으로 만들기. (2개 이상의 리스트를 데이터프레임으로 만들려면 한 번에 zip()으로 묶어서 만들거나 각각 데이터프레임으로 만든 다음 pd.concat으로 합친다.)
ABC.columns = ['aaa','bbb','ccc'] : ABC 데이터프레임에 aaa,bbb,ccc를 각 컬럼헤더로 넣기. (컬럼헤더를 못 넣고 데이터프레임을 만들었을 경우.)
ABC.rename(columns = {'aa':'A','bb':'B'}):ABC 데이터프레임의 컬럼헤더를 aa,bb에서 A, B로 변경하기. 파이썬에는 inplace라는 옵션을 가지는 함수가 있다.inplace=False : 저장 안 함. inplace=True 저장함. rename 함수의 inplace 기본값은 False로 저장하려면 다시 변수에 넣어주거나 .rename({ },inplace=True) 옵션을 준다.
ABC.index = ['aaa','bbb','ccc']:ABC 데이터프레임에 aaa,bbb,ccc를 각 인덱스로 넣기. (로우헤더.)
pd.read_csv("../../../ABC.csv"):ABC.csv를 판다스로 불러오기. (한글 포함 파일 에러 발생시, encoding='ms949' 또는 'cp949' 옵션을 준다.)
pd.read_csv("../../../ABC{}.csv".format(i)) : ABCi.csv를 판다스로 불러오기. (ABC1, ABC2, ... 이렇게 파일이 있을 경우 반복문을 통해 불러올 수 있다. 단, 중간에 비는 번호가 있을 경우를 대비해 try except로 예외처리를 해줘야한다.)
ABC.to_csv("./filename.csv", index=False, encoding="UTF-8") : AB데이터프레임을 filename.csv 로 저장한다. (판다스가 자동으로 인덱스를 1열에 삽입하여 저장하기 때문에 일반적으로 , index+False옵션은 항상 주는 것이 좋다.) (내보낼 수 있는 옵션은 csv 외에도 clipboard, dict, excel, html, json, latex, markdown, numpy, pickle, records, sql,string 등 다양하다.) (파일 저장시 누적해서 저장되지 않는다. 파일을 덮어쓰기 한다.)
pd.read_sql_query("Query",engine):"Query"를 이용해 판다스로 불러올 수 있다. 접속은 engine을 이용한다. (테이블에서 원하는 것만 불러올 수 있다.)
pd.read_sql_table(table_name =ABC,con =engine): 테이블 이름이ABC인 것을engine을 이용해 판다스로 불러오기. (테이블 전체를 불러온다.)
ABC.to_sql(name ="Hello", con =engine,index = False): ABC 데이터프레임을engine을 이용해 DB에'Hello'라는 테이블 이름으로 저장한다.
d6tstack.utils.pd_topsql(df =ABC, uri ="engine 만들 때 사용하는 URL", table_name ="Hello"): ABC 데이터프레임을"engine 만들 때 사용하는 URL"을 이용해"Hello"라는 테이블 이름으로 저장한다.
os.path로 만든 디렉토리가 아닌 경우 디렉토리는 반드시 다음과 같이 정해져야한다 /Users/path (X) /Users/path/ (O) 이렇게 끝나야 검색이 된다. 혹시 안 될 경우 뒤에 / 를 붙여보자. 된다면 os.path를 이용해 / 가 안 붙어도 작동하게 만들어준다.
디렉토리 목록만 리스트로 추출
## 둘 중 아무거나 하나 사용# 입력 받은 디렉토리에서 디렉토리 목록만 리스트로 추출 (os.path.isfile)deffindDir(pwd):
directory = []
for eachDir in os.listdir(pwd):
if os.path.isfile(eachDir):
continue
directory.append(eachDir)
return directory
# 입력 받은 디렉토리에서 디렉토리 목록만 리스트로 추출 (os.path.isdir)deffindDir(pwd):
directory = []
for eachDir in os.listdir(pwd):
fullDir = os.path.join(pwd, eachDir)
if os.path.isdir(fullDir):
directory.append(eachDir)
return directory
디렉토리 목록을 전체 디렉토리 리스트로 추출
## 둘 중 아무거나 하나 사용# 입력 받은 디렉토리에서 디렉토리만 전체 디렉토리 리스트로 추출 (os.path.isfile)deffindFullDir(pwd):
directory = []
for eachDir in os.listdir(pwd):
if os.path.isfile(eachDir):
continue
directory.append(os.path.join(pwd, eachDir))
return directory
# 입력 받은 디렉토리에서 디렉토리만 전체 디렉토리 리스트로 추출 (os.path.isdir)deffindFullDir(pwd):
directory = []
for eachDir in os.listdir(pwd):
fullDir = os.path.join(pwd, eachDir)
if os.path.isdir(fullDir):
directory.append(fullDir)
return directory
파일 구별하기
파일 목록만 리스트로 추출
# 입력 받은 디렉토리에서 파일 목록만 리스트로 추출 (os.path.isfile)deffindFile(pwd):
file = []
for eachFile in os.listdir(pwd):
if os.path.isfile(eachFile):
file.append(eachFile)
return file
파일 목록을 전체 디렉토리 리스트로 추출
# 입력 받은 디렉토리에서 파일만 전체 디렉토리 리스트로 추출 (os.path.isfile)deffindFileFullDir(pwd):
directory = []
for eachFile in os.listdir(pwd):
if os.path.isfile(eachFile):
directory.append(os.path.join(pwd, eachFile))
return directory
for문에서 i는 단지 for문을 반복시키기 위해 변수를 준 것이고 그 i라는 변수의 범위는 range 함수에 의해 정해진다.
따라서 이를 혼동하지 않으려면 반드시 range 함수에 대한 이해가 필요하다.
사실 범위는 같게 읽어을 수도 있지만 index 개념이 아닌 단지 숫자 그 자체로 접근하는게 좋다.
range(start, stop[, step]) 구조로
range(a,b,c)는 'a에서 시작해 b에서 멈춰라. 등차는 c다.' 라는 범위를 정해주는 것이다.
즉, range(a,b,c) 는 'a부터 시작해서 cn + a >= b 면 멈춰라.' 와 같다.
이를 수식으로 표현하면 다음과 같다. a <= cn + a < b
출력되는 숫자의 범위 자체는 [a : b] 와 range(a, b, ) 가 같다. 또한 [a : b : c]는 range(a, b, c)와 같다.
a : start, b : stop, c : step 이라는 구조는 같지만 둘의 큰 차이는 다음과 같다.
1. [a : b]는 결과를 리스트로 반환하지만 range(a, b, )는 결과를 숫자로 반환한다. 따라서 range 함수는 결과 값을 for 문과 결합해 등차수열결과값의 범위를 지니는 변수로 사용할 수 있다.
2. [a : : c]는 가능한데 range(a, , c)는 불가능하다. 리스트 호출에서는 종료 지점을 설정하지 않고 a부터 마지막 리스트까지 c 간격으로 반환이 가능하지만, range 함수는 정지시키는 값이 반드시 필요하다. 따라서 [a : : c]는 range(a, len(listname), c)로 표현할 수 있다.