package my.spring.project;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class DB {
// DB 연결
public Connection connectDB(String id, String password, String url) throws ClassNotFoundException, SQLException {
// 1. 드라이버 로딩
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. DB 연결
Connection conn = DriverManager.getConnection(url, "root", "1234");
return conn;
}
// 전체 게시글 수 가져오기
public int getTotalRecord(String tableName, Connection conn) throws SQLException {
ResultSet countRs;
// 쿼리 실행 준비작업
String sql = "SELECT count(*) FROM " + tableName;
PreparedStatement pstmt = conn.prepareStatement(sql);
// 쿼리 실행
countRs = pstmt.executeQuery();
countRs.next();
//쿼리 결과
int total = countRs.getInt(1);
return total;
}
// 현재 페이지 게시물 정보 가져오기
public ArrayList<BoardVO> getRecordForPageNum(
Connection conn, int total, int pageNum, int amount) throws SQLException {
ResultSet boardRs;
// 페이지에 따른 게시물 정보 가져오기
// // 방법1
// String sql = "(SELECT @junho:=0);"
//
// // 방법1
//
// String sql = "select * \r\n"
// + " from(SELECT @junho:=@junho+1 rn, A.* FROM mytable A ) total \r\n"
// + "where rn > 0 and rn <= 290;"
// 방법2
String sql = "select * "
+ "from(SELECT @ROWNUM:=@ROWNUM+1 rn, A.* FROM mytable A, (SELECT @ROWNUM:=0) R order by rn desc) total "
+ "where rn > ? and rn <= ?;";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, total - (pageNum * amount));
pstmt.setInt(2, total - ((pageNum - 1) * amount));
boardRs = pstmt.executeQuery();
ArrayList<BoardVO> boardList = new ArrayList();
// 게시물 정보 가져오기
while(boardRs.next()) {
BoardVO dto = new BoardVO();
dto.setId(boardRs.getInt(1));
dto.setName(boardRs.getString(3));
dto.setPhone(boardRs.getString(4));
dto.setEmail(boardRs.getString(5));
dto.setAddress(boardRs.getString(6));
boardList.add(dto);
}
return boardList;
}
// DB 연결 끊기
public void closeConnect(Connection conn) throws SQLException {
conn.close();
}
}
package my.spring.project;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
@RequestMapping(value = "/paging", method = RequestMethod.GET)
public String home(Locale locale, Model model, HttpServletRequest request, HttpServletResponse response) throws ClassNotFoundException, SQLException {
int pageNum = 1; // default 현재 페이지
int amount = 10; // default 한 페이지에 보여줄 게시물 수
int paginationNum = 10; // default 페이지네이션 리스트 수
// pageNum, amount 파라미터 값 가져오기
if(request.getParameter("pageNum") != null && request.getParameter("amount") != null && request.getParameter("paginationNum") != null) {
pageNum = Integer.parseInt(request.getParameter("pageNum"));
amount = Integer.parseInt(request.getParameter("amount"));
paginationNum = Integer.parseInt(request.getParameter("paginationNum"));
}
// mysql 8.0 이용 중
// 연결할 db 정보
String drive = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/konan?useSSL=false&serverTimezone=Asia/Seoul";
String id = "root";
String password = "1234";
// DB 연결
DB db = new DB();
Connection conn = db.connectDB(id, password, url);
// 전체 게시물 수
String tableName = "mytable";
int total = db.getTotalRecord(tableName, conn);
// 현재 페이지 게시물 정보
ArrayList<BoardVO> boardList = db.getRecordForPageNum(
conn, total, pageNum, amount);
// 페이징에 필요한 정보
Board board = new Board();
PageVO pageVO = new PageVO();
pageVO = board.setPageVO(total, pageNum, amount, paginationNum);
// DB 연결 끊기
db.closeConnect(conn);
// view에 사용할 데이터 model에 담아 보내주기
model.addAttribute("pageVO",pageVO);
model.addAttribute("boardList",boardList);
return"paging";
}
}
package my.spring.project;
//페이징 정보 담는 VO
public class PageVO {
private int total; // 전체 글 수
private int amount; // 한 페이지에 보여줄 게시글 수
private int pageNum; // 현재 페이지 번호
private int startPage; // 페이지네이션 시작 번호
private int endPage; // 페이지네이션 끝 번호
private int realEnd; // 페이제니이션 진짜 끝 번호
private int prevPage; // 10 페이지 전 이동
private int nextPage; // 10 페이지 후 이동
private int paginationNum; // 페이지네이션 보여질 갯수 [1 2 3 ... 10]일경우 paginationNum = 10
// 예) 전체글수가 180개이고 현재 페이지가 15이고 10개씩 보여줄시
// startPage는 10이 되는 것이고 endPage는 20이 된다.
// realEnd는 18이 된다.
public int getStartPage() {
return startPage;
}
public int getPaginationNum() {
return paginationNum;
}
public void setPaginationNum(int paginationNum) {
this.paginationNum = paginationNum;
}
public int getPrevPage() {
return prevPage;
}
public void setPrevPage(int prevPage) {
this.prevPage = prevPage;
}
public int getNextPage() {
return nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public void setStartPage(int startPage) {
this.startPage = startPage;
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int endPage) {
this.endPage = endPage;
}
public int getRealEnd() {
return realEnd;
}
public void setRealEnd(int realEnd) {
this.realEnd = realEnd;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
}
package my.spring.project;
// 게시글 담는 VO
public class BoardVO {
private int id;
private String name;
private String phone;
private String email;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package my.spring.project;
public class Board {
public PageVO setPageVO(int total, int pageNum, int amount, int paginationNum) {
PageVO pageVO = new PageVO();
// 1.0을 곱하는 이유는 int형 / int형 일 경우 결과값이 int형이다
// 예를 들어 결과값이 0 ~ 1일 경우 올림 해도 0이 나오기 때문에 로직에 오류가 생기게 된다.
int endPage = (int)Math.ceil(pageNum * 1.0 / paginationNum) * paginationNum;
// 예) (5 / 3) * 3 -> 5페이지의 끝 페이지네이션은 6
int startPage = endPage - paginationNum + 1 ; // 예) 20페이지 - 페이지네이션갯수 + 1 -> 11
int prevPage = startPage - 1; // 무조건 시작페이지 -1 예) 18 에서 << 클릭시 10페이지로 이동
int nextPage = startPage + paginationNum; // 18에서 >> 클릭시 21페이지로 이동
int realEnd = (int)Math.ceil(total * 1.0 / amount); // 실제 마지막 페이지
if(endPage > realEnd) endPage = realEnd;
// 끝 페이지 경우 endPage가 realEnd보다 크면 endPage는 realEnd값이 된다.
pageVO.setPaginationNum(paginationNum);
pageVO.setPrevPage(prevPage);
pageVO.setNextPage(nextPage);
pageVO.setAmount(amount);
pageVO.setPageNum(pageNum);
pageVO.setTotal(total);
pageVO.setStartPage(startPage);
pageVO.setEndPage(endPage);
pageVO.setTotal(total);
pageVO.setRealEnd(realEnd);
return pageVO;
}
}
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">
<title>Home</title>
</head>
<body>
<!-- 게시글 start-->
<table border=1>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>phone</th>
<th>email</th>
<th>address</th>
</tr>
</thead>
<tbody>
<c:forEach var="item" items="${boardList}">
<tr>
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.phone}</td>
<td>${item.email}</td>
<td>${item.address}</td>
</tr>
</c:forEach>
</tbody>
</table>
<!-- 게시글 end-->
<!-- 페이징 start-->
<nav aria-label="Page navigation example">
<ul class="pagination">
<!-- 페이지네이션 중 first start -->
<c:if test="${ pageVO.pageNum > pageVO.paginationNum}">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=1&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}" aria-label="Previous">
<span aria-hidden="true">first</span>
</a>
</li>
</c:if>
<!-- 페이지네이션 중 first end -->
<!-- 페이지네이션 중 << 기호 start -->
<c:if test="${ pageVO.pageNum > pageVO.paginationNum}">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=${pageVO.prevPage}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
</c:if>
<!-- 페이지네이션 중 << 기호 end -->
<!-- 페이지네이션 중 < 기호 start -->
<c:if test="${ pageVO.pageNum != 1}">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=${pageVO.pageNum-1}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}" aria-label="Previous">
<span aria-hidden="true"><</span>
</a>
</li>
</c:if>
<!-- 페이지네이션 중 < 기호 end -->
<!-- 페이징번호 표현 start -->
<c:forEach var="num" begin="${pageVO.startPage}" end="${pageVO.endPage}">
<c:if test="${ pageVO.pageNum == num}">
<li class="page-item active">
<a class="page-link"
href="/paging?pageNum=${num}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}">${num}
</a>
</li>
</c:if>
<c:if test="${pageVO.pageNum != num}">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=${num}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}">${num}
</a>
</li>
</c:if>
</c:forEach>
<!-- 페이징번호 표현 end -->
<!-- 페이지네이션 중 > 기호 start-->
<c:if test="${ pageVO.pageNum != pageVO.realEnd }">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=${pageVO.pageNum+1}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}" aria-label="Next">
<span aria-hidden="true">></span>
</a>
</li>
</c:if>
<!-- 페이지네이션 중 > 기호 end-->
<!-- 페이지네이션 중 >> 기호 start-->
<c:if test="${ pageVO.endPage != pageVO.realEnd }">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=${pageVO.nextPage}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
<!-- 페이지네이션 중 >> 기호 end-->
<!-- 페이지네이션 중 last start-->
<c:if test="${ pageVO.endPage != pageVO.realEnd }">
<li class="page-item">
<a class="page-link"
href="/paging?pageNum=${pageVO.realEnd}&amount=${pageVO.amount}&paginationNum=${pageVO.paginationNum}" aria-label="Next">
<span aria-hidden="true">last</span>
</a>
</li>
</c:if>
<!-- 페이지네이션 중 last end-->
</ul>
</nav>
<!-- 페이징 end-->
</body>
</html>
통상적으로 자주 사용하는 약어는 사용해도 좋지만 약어 사전에 등록을 해놓아 다른 사람과 충돌이 안 생기게 한다.[ 이건 다들 작업을 시작 하기전에 미리 정의해야 할 사항 ]
협업자와 함께 개발을 하는 경우에는 이름을 통해 그것이 무엇인지 나타내야 한다.
로직이 끝나면 한 줄을 띄어준다 (보기 편하게 하는데 의의가 있음 너무 남발해도 좋지 않다.)
def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
if filepath.split('.')[-1] == 'pcm':
pcm = np.memmap(filepath, dtype='h', mode='r')
sig = np.array([float(x) for x in pcm])
elif filepath.split('.')[-1] == 'wav':
sig, _ = librosa.core.load(filepath, sr=16000)
else:
raise ValueError("Invalid format !!")
if del_silence:
non_silence_ids = librosa.effects.split(sig, top_db=30)
sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])
mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')
if input_reverse:
mfcc = mfcc[:,::-1]
return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )
→ 못된 사례
def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
if filepath.split('.')[-1] == 'pcm':
pcm = np.memmap(filepath, dtype='h', mode='r')
sig = np.array([float(x) for x in pcm])
elif filepath.split('.')[-1] == 'wav':
sig, _ = librosa.core.load(filepath, sr=16000)
else:
raise ValueError("Invalid format !!")
if del_silence:
non_silence_ids = librosa.effects.split(sig, top_db=30)
sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])
mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')
if input_reverse:
mfcc = mfcc[:,::-1]
return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )
→ 잘된 사례
클래스
동사를 넣지 않는다.
명사나 명사구로 작성한다.
메소드
동사로 시작한다.
카멜케이스 규정을 따른다.
어떤 행동을 하는지에 대한 내용이 있어야한다.
함수는 하나의 동작만 해야한다. → printBankName(String bankName)
변수명
전치사를 최대한 생략한다. [ to는 자주 쓰이므로 괜찮다 ]
굳이 관사를 넣지 않는다.
단수와 복수를 구분한다
상수는 모두 대문자 표시
변수명이 길어지더라도 정확한 의미를 내포해야한다.
동사를 넣지 않는다.
List와 같은 배열 타입일 경우 복수형으로 표시한다. → ArrayList<String> item(x) ArrayList<String> items(o)
Bool [참고]
isExecuting (실행 중인가?)
isShinhanBank (신한은행인가?)
isEditable (수정할 수 있는가?)
hasVideo (비디오를 가지고 있는가?)
canBecomeFirstResponder (첫번째 응답자가 될 수 있는가?)
shouldReinstallProduct (제품을 재설치해야 하는가?)
allowedAccess (허용된 엑세스인가?)
상수
상수는 대문자로 표시한다 → int MAIN_WIDTH = 1024
자바 메소드와 클래스명 주석 팁
@method : 메소드명 or 클래스명 @brief : 함수 or 클래스 설명 @detail : 함수 or 클래스 상세 설명 @author : 작성자 @since : 작성일자 @param : 인자(매개변수) @return : 반환값 @why : 만든 이유
Interface 팁
1. 함수의 확장성(교체성)이 있다면 Interface로 만든다
예) 피자 : 5000원, 햄버거 : 50000원 → 피자 5000
햄버거 50000 [출력기준이 바뀔 수 있는 경우]
2. 동일한 함수기능이(내용물은 살짝 달라도 동일한 기능) 여러 클래스에서 쓰이는 경우 Interface로 구성한다.
if (bank.equals("KB")){
for(int i = 0 ; i < 10; i++){
if()
}
}else if (bank.equals("NH"){
for(int i = 0 ; i < 10; i++){
if()
}
}else if (bank.equals("SH"){
for(int i = 0 ; i < 10; i++){
if()
}
}
→ 이런식이면 엄청 복잡하다
첫번째 if문, 두번째 else if , 세번째 else if → 동일한 부분을 interface로 만든다.
interface BankImpl{
public void print();
}
class KB{
@Override
public void printBankName() {
System.out.println("KB!!");
}
}
class NH{
@Override
public void printBankName() {
System.out.println("KB!!");
}
}
class SH{
@Override
public void printBankName() {
System.out.println("KB!!");
}
}
Map<String, Alphabet> typeMap = new HashMap<>();
typeMap.put("KB", new KB());
typeMap.put("NH", new NH());
typeMap.put("SH", new SH());
String type = "NH";
typeMap.get(type).printBankName();