파일 업로드 마무리
자바스크립트 이미지 오브젝트 배열 메소드 부연설명
https://talkwithcode.tistory.com/19
카드 테이블 생성
create table card(
no varchar2(30),
valid_month varchar2(10),
constraint pk_card primary key(no)
);
select * from card;
카드 설명 추가 , CardVO 클래스 생성
package kr.or.ddit.vo;
import lombok.Data;
@Data
public class CardVO {
private String no;
private String validMonth;
}
card와 quick 테이블의 우선순위?
quick이 있어야 card가 존재( quick(부모) > card(자식) , 1 : N )
부모테이블 기본키 -> 자식테이블의 기본키로
관계 설정
1명의 회원 : 여러개의 카드 가질수있다(1 : N)
1개의 카드 : 1명의 회원 ( 1 : 1)
1*N = N
1*1 =1
-> 1 : N의 관계
다대다 관계시에만 관계테이블 생성
고객/상품
한명의 고객 -> 여러상품 구매가능( 1 : n )
하나의 상품 -> 여러고객이 구매 가능(1 : m)
(n : m)
부모테이블의 기본키가 자식테이블의 키로서 사용될때
1. 자식테이블에서 기본키로 사용될지 외래키로 사용될지 고려 여부
최소성 원리
카드테이블의 카드번호가 카드를 구분가능(각 카드 식별가능 , 카드번호가 이미 pk의 역할을 수행하고있음 , 복합키로 구성할 필요가 없다)
외래키가 기본키 -> 식별관계
외래키는 null을 허용하지만 일반적으로 허용하지 않는다.
테이블 제약조건 추가
// QUICK : CARD = 1 : N QuickVO 테이블에 추가
private List<CardVO> cardVOList;
QuickVO 테이블에 추가
quick/create 에서 카드번호 입력 후 등록시 DB로 넘어가는지 확인
--------------------------------------------------------------------
취미 추가 - > quick.jsp 아래
<div class="form-group">
<label for="exampleInputEmail1">취미</label>
<input type="email" class="form-control" name="hobby" id="emailAdres" placeholder="이메일" required />
</div>
취미 테이블 생
-- 취미들
create table likes(
likes_code varchar2(20),
likes_title varchar2(90),
likes_cont varchar2(300),
CONSTRAINT pk_likes PRIMARY key(likes_code)
);
comment on table likes is '취미정보';
comment on column likes.likes_code is '취미코드';
comment on column likes.likes_title is '취미명';
comment on column likes.likes_cont is '취미상세';
commit;
누구의 취미인지 -> quick에 존재하는 사람의 취미 정보
열추가 , 제약조건 추가 , LikesVO 클래스 생성
package kr.or.ddit.vo;
import lombok.Data;
@Data
public class LikesVO {
private String likesCode;
private String likesTitle;
private String likesCont;
private String emailAdres;
}
QuickVO클래스에 추가
// QUICK : LIKES = 1 : N QuickVO 테이블에 추가
private List<LikesVO> likesVOList;
mybatisAlias 추가
<typeAlias type="kr.or.ddit.vo.LikesVO" alias="likesVO" />
likesCode에 기존에는 max+1 이었으나
LKS001의 형태로 처리
처리과
--LKS001 + 1
--LKS (001+1)
--LKS 2
--LKS 002
--LKS002
취미부분 변경
<div class="form-group" id="divLikes">
<div>
<label for="likesTitle1">취미</label>
<input type="email" class="form-control" name="likesVOList[0].likesTitle" id="likesTitle1" placeholder="취미명" required />
<label for="likesCont1">취미상세</label>
<input type="email" class="form-control" name="likesVOList[0].likesCont" id="likesCont1" placeholder="취미상세" required />
</div>
</div>
화면단에서 +버튼을 누를시 아래와 같이 적용되게 (작성란 추가)
<div class="form-group" id="divLikes">
<div>
<div style="width: 50%; float: left;">
<label for="likesTitle1">취미</label>
<input type="email" class="form-control" name="likesVOList[0].likesTitle" id="likesTitle1" placeholder="취미명" required />
</div>
<div style="width: 50%; float: left;">
<label for="likesCont1">취미상세</label>
<input type="email" class="form-control" name="likesVOList[0].likesCont" id="likesCont1" placeholder="취미상세" required />
</div>
</div>
<div>
<div style="width: 50%; float: left;">
<label for="likesTitle2">취미</label>
<input type="email" class="form-control" name="likesVOList[1].likesTitle" id="likesTitle2" placeholder="취미명" required />
</div>
<div style="width: 50%; float: left;">
<label for="likesCont2">취미상세</label>
<input type="email" class="form-control" name="likesVOList[1].likesCont" id="likesCont2" placeholder="취미상세" required />
</div>
</div>
</div>
quick_SQL.xml 에 쿼리문 추가
-> selectkey 쿼리문 (기존 DB 값이 존재하면 에러뜸!)
<insert id="insertLikes" parameterType="likesVO">
<selectKey resultType="String" order="BEFORE" keyProperty="likesCode">
SELECT NVL(SUBSTR(MAX(LIKES_CODE),1,3) || TRIM(TO_CHAR(SUBSTR(MAX(LIKES_CODE),4)+1,'000')),'LKS001')
FROM LIKES
</selectKey>
insert into likes(LIKES_CODE, LIKES_TITLE, LIKES_CONT, EMAIL_ADRES)
values (#{likesCode} , #{likesTitle} , #{likesCont} , #{emailAdres})
</insert>
이후 DB까지 데이터 넘어가는지 확인
버튼 태그 복사
<div class="col-lg-6">
<div class="btn-group w-100">
<span class="btn btn-success col fileinput-button dz-clickable">
<i class="fas fa-plus"></i>
<span>Add files</span>
</span>
<button type="submit" class="btn btn-primary col start">
<i class="fas fa-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning col cancel">
<i class="fas fa-times-circle"></i>
<span>Cancel upload</span>
</button>
</div>
</div>
script문 추가
// 취미 + / -
$(".divLikesAdd").on("click" , function () {
console.log("취미 추가");
});
$(".divLikesMinus").on("click" , function () {
console.log("취미 삭제");
})
개발자 모드에서 console.log 찍히는지 확인
$(function(){
// 취미 + / -
$(".divLikesAdd").on("click" , function () {
console.log("취미 추가");
let len = $(".clsLikesTitle").length;
console.log("len : " + len);
let str="<div>";
str += "<div style='width: 50%; float: left;'>";
str += "<label for='likesTitle"+(len+1)+"'>취미명</label>";
str += "<input type='text' class='form-control clsLikesTitle'";
str += "name='likesVOList["+len+"].likesTitle' id='likesTitle+"+(len+1)+"'"
str += "placeholder='취미명' />";
str += "</div>";
str += "<div style='width: 50%; float: left;'>";
str += "<label for='likesCont"+(len+1)+"'>취미상세</label>";
str += "<input type='text' class='form-control clsLikesCont'";
str += "name='likesVOList["+len+"].likesCont' id='likesCont"+(len+1)+"'";
str += "placeholder='취미상세' />";
str += "</div>";
str += "</div>";
$("#divLikes").append(str);
//divLikes의 자식요소에 추가
});
+버튼 누를시 추가되는지 확인, index값 확인(console.log)
// length를 인덱스에 추가
$(".divLikesMinus").on("click" , function () {
console.log("취미 삭제");
let len = $(".clsLikesTitle").length;
if(len<2){
alert("취미 영역은 최소 한개가 있어야 합니다.");
} else {
$("#divLikes").children().last().remove();
}
// -버튼 누를시 자식요소 삭제
/*
<div id = "divLikes">
<div></div>
<div></div> -> 삭제된다!
</div>
*/
});
삭제버튼 추가
http://localhost/quick/create 에서 +/- 버튼 눌러서 작동하는지 확인
에러코드
SQL.xml 에서 쿼리문에 세미콜론 포함되어있을시 -> 500에러
### The error may involve kr.or.ddit.mapper.QuickMapper.insertCard-Inline
### The error occurred while setting parameters
### SQL: insert into card(no , valid_month ,email_adres) values (? , ? , ?)
### Cause: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (JSPEXAM.PK_CARD) violated
; ORA-00001: unique constraint (JSPEXAM.PK_CARD) violated
; nested exception is java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (JSPEXAM.PK_CARD) violated
]을(를) 발생시켰습니다.
java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (JSPEXAM.PK_CARD) violated
해당 에러코드
에러코드
SQL.xml 에서 쿼리문에 컬럼명 불일치시 -> 500에러
2월 02, 2024 2:50:42 오후 org.apache.catalina.core.StandardWrapperValve invoke
심각: 경로 []의 컨텍스트 내의 서블릿 [appServlet]을(를) 위한 Servlet.service() 호출이, 근본 원인(root cause)과 함께, 예외 [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'likestitle' in 'class kr.or.ddit.vo.LikesVO']을(를) 발생시켰습니다.
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'likestitle' in 'class kr.or.ddit.vo.LikesVO'
해당 에러코드
ajax 로 바꿔서
<div class="card-footer">
<button type="button" id="btnAjaxSubmit" class="btn btn-primary">등록</button>
</div>
버튼타입 submit -> button 으로 바꾸기 , id추가
비동기 방식으로 파일업로드 -> 카드 -> 취미 -> insert까지 확인
console.log 확인하
카드 사용내역?
부모 -> 자식 -> 자식
AJAX
web.xml 파일 열기
에러코드 종류 상태 코드를 사용하여 오류 페이지 설정 시작
HTTP 오류 코드 정리
- 400 : Bad Request. 문법 오류(잘못 입력한 url)
- 404* : Not Found. 요청한 문서를 찾지 못함(url확인 및 캐시 삭제가 필요한 상태)
- 405 : Method not allowed. 메소드 허용 안됨(메소드 매핑이 안 될 때 발생)
- 415 : 서버의 요청에 대한 승인 거부. (ContentType, Content Encoding 데이터 확인 필요)
- 500* : 서버 내부 오류. (웹 서버가 요청사항을 수행할 수 없을 때 발생)
- 505 : HTTP Version Not Supported.
web.xml 파일 하단에 추가
<!-- 기본 오류 페이지 설정 시작 -->
<!-- <error-page> -->
<!-- <location>/error/errorDefault</location> -->
<!-- </error-page> -->
<!-- 기본 오류 페이지 설정 시작 -->
<!-- HTTP 상태코드를 사용하여 오류페이지 설정 시작
HTTP 오류 코드 정리
- 400 : Bad Request. 문법 오류(잘못 입력한 url)
- 404* : Not Found. 요청한 문서를 찾지 못함(url확인 및 캐시 삭제가 필요한 상태)
- 405 : Method not allowed. 메소드 허용 안됨(메소드 매핑이 안 될 때 발생)
- 415 : 서버의 요청에 대한 승인 거부. (ContentType, Content Encoding 데이터 확인 필요)
- 500* : 서버 내부 오류. (웹 서버가 요청사항을 수행할 수 없을 때 발생)
- 505 : HTTP Version Not Supported.
-->
<error-page>
<error-code>400</error-code>
<location>/error/error400</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error/error404</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/error500</location>
</error-page>
<!-- HTTP 상태코드를 사용하여 오류페이지 설정 끝 -->
<!-- 예외 타입을 사용한 에러 페이지 설정 시작
웹 컨테이너(tomcat서버) 설정 파일(web.xml)의 exception-type 태그 요소에 예외 타입을 설정하고
location 요소에 이동 대상 페이지 및 URI를 지정함
IOException, SQLException, NullPointerException, ArrayIndexOutOfBoundsException,
ArtimeticException(0으로 나눌경우)
-->
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error/errorException</location>
</error-page>
<!-- 예외 타입을 사용하여 오류 페이지 설정 시작 -->
ErrorController 클래스 생성
package kr.or.ddit.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
// 자바빈 선언
@Slf4j
@Controller
@RequestMapping("/error")
public class ErrorController {
// error/error400
@GetMapping("/error400")
public String error400() {
//forwarding : jsp
return "error/error400";
}
@GetMapping("/error404")
public String error404() {
//forwarding : jsp
return "error/error404";
}
@GetMapping("/error500")
public String error500() {
//forwarding : jsp
return "error/error500";
}
}
@Controller 어노테이션 선언
views -> error 폴더 생성 -> error400.jsp , error404.jsp , error500.jsp 생성
400 : url 오류
404 : page not pond
500 : 개발자 오류?