[개발] Spring 과정
//데이터베이스 생성
create databases test;
create users;
cerate user '#{데이터베이스 계정아이디}'@'%' identified '#{데이터베이스 계정 비밀번호}';
//환경설정
applicationContext.xml
jndi
transction
annotaion 설정
-- rollbakc 처리; 3개처리중 2개성공 1개 이상있을때
sqlSessionFactory
db connection
mybatisConfig.xml route
mapper route
sqlSession
//root-context.xml에 설정해주기
xmlns:tx= "http://www.springframework.org/schema/tx"
xmlns:jndi= "http://www.springframework.org/schema/jee"
//jndi설정 = 서버측 WAS(tomcat)에서 데이터베이스를 관리해주겠다.
<jndi:jndi-lookup jndi-name="jdbc/test" resource-ref ="true" id ="dataSourceNm">
//transcation 설정
<bean id ="txManagerDB" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSourve" ref ="dataSourceNm" />
</bean>
<tx:annotation-driven transaction-manager="txManagerDb" />
//server -> tomcat #{버전} -> server.xml -> context안에 설정
<Resource auth="Container"
driverClassName="com.mysql.cj.jdbc.Driver" name="jdbc/text"
username="#{데이터베이스 계정ID}"
password="#{데이터베이스 계정PW}"
type="javax.sql.DataSource"
url="jdbc:mysql://127.0.0.1:3306/#{데이터베이스이름}?serverTimezone=UTC">
Spring 과정
- view -> controller -> service -> dao -> mapper -> dao -> service -> controller -> view
- interface를 통해 작업단위 관리
- service 여러 dao호출가능
- 서로 연관된 UPDATE면 @Transactional 어노테이션을 통해서 처리 (에러시 rollback진행)
- api호출도 service에서 진행
로그인 처리 방법
- 컨트롤러 -> view를 통해 데이터 받아오기
- 비동기 방식일때 @RsponseBody 적어준다.
-
비동기식으로 중복체크 == 값을 줌;
-
숫자 반환으로 case를 나누어 처리한다.
- 0001 - 비밀번호 틀림
- 0002 - 일치하는 아이디 없음
- 0003 - 5번 비밀번호 틀림(계정 비활성화)
- 0009 - 로그인 성공–> 계정 세션에 담기
AJAX 방식 3가지
- SERIALIZE 해서 객체로 받기
- JSON객체를 만들어서 주고받기
- FORM태그로해서 주고받기
- 참고 ajax 메소드 :
- beforeSend - 대용량데이터 처리시 비동기과정중에 하는것 = ‘로딩바 뛰우기’
- success나 error결과가 나오면 로딩바 멈춰주면된다.
- beforeSend - 대용량데이터 처리시 비동기과정중에 하는것 = ‘로딩바 뛰우기’
session
- Session Method
@ResponseBody //ajax통신시 추가
@RequestMapping(value = "/loginChk", method = RequestMethod.POST)
public void Method(HttpServletRequest request, HttpServletResponse response, UserVO vo){
//세션 유지시간 -> 파라미터(초단위)
request.getSession().setMaxInactiveInterval(6000);
//세션 추가
request.getSession().setAttribute("userInfo", user);
//세션 제거
request.getSession().removeAttribute("userInfo");
//세션 가져오기
UserVO user = request.getSession().getAttribute("userInfo")
}
//httpSession과 다른점은?
-
세션 저장소 : ServletContext, HttpSession, HttpServletRequest
-
각 저장소의 차이점 : 메모리에서 살아있는 기간이 다름
-
ServletContext
-
생성 : 서버 시작 시
제거 : 서버 중지 시
web application 이 서비스 중인 동안에는 계속 존재
-
-
HttpSession
-
생성 : Client 최초 접속 시
제거 : Client 접속 종료 시
Client가 접속 중인 동안에만 존재
-
ex) 로그인/로그아웃장바구니 등
-
-
HttpServletRequest
-
생성 : Client가 요청 시
삭제 : Server가 응답 시
Request 중인 동안에만 존재
-
*요청 재지정
-
Mapper.xml = Query문 처리
${} = Statement
- 쿼리를 값이 매핑으로 인식
- String 연산자로 '+'로 이어 붙임
- 그때그때마다 컴파일한다
ex) (테이블명같이 변동이 안되는곳에 사용)
SELECT * FROM ${user};이면
-> SELECT * FROM users이렇게 고정되어 보낸진다.
#{} = PreparedStatement (Statement의 자식)
- 쿼리가 ?로 인식
- 쿼리를 db에 보내면 한번만 컴파일하는데 메모리에 올려놈(재사용가능하다)
- statement보다 더유리함
ex) SELECT * FROM ${user};이면
-> SELECT * FROM ? 로 인식한다.
사진업로드
-
과정
-
pom.xml에 fileupload dependency추가
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>#{version}</version> </dependency>
-
jsp에서 form 태그
<form method="post"enctype="multipart/form-data">
-
controller안에서
@RequestMapping(value = "/registerUser", method = RequestMethod.POST) public void acceptFile (MultipartFile user_image) { //업로드한 파일이름 얻기 String fileName = user_image.getOriginalFilename(); //서버측 경로에다가 파일저장 File f = new File(context.getRealPath("/") + "resources/users/" + fileName); FileOutputStream fos = new FileOutputStream(f); fos.write(img.getBytes()); fos.close(); }
-
-
파일 미리보기
<script> //사진 미리보기 function previewImage(f) { var file = f.files; // 확장자 체크 if (!/\.(gif|jpg|jpeg|png)$/i.test(file[0].name)) { alert('gif, jpg, png 파일만 선택해 주세요.\n\n현재 파일 : ' + file[0].name); // 선택한 파일 초기화 f.outerHTML = f.outerHTML; document.getElementById('preview').innerHTML = ''; } else { // FileReader 객체 사용 var reader = new FileReader(); // 파일 읽기가 완료되었을때 실행 reader.onload = function (rst) { $("#photo").attr("src", rst.target.result); } // 파일을 읽는다 reader.readAsDataURL(file[0]); } } </script> <img src="/tys/resources/static/default.png" id="photo" width="150px" height="150px" /> <input type="file" name="user_image" id="img" placeholder="이미지 선택" accept="image/*" onchange="previewImage(this);">
- 설명
- 따로 AJAX를 통해 임시폴더를 만들고 사진을 관리(저장/삭제)할 필요가 없다.
- JS를 통해 URL형식으로 미리보기를 만들수 있다.
- 그리고나서 form태그의 등록을 통해 image의 value값을 보내주면된다.
- 설명
Transactional
@Transactional
public static void function{
....
}
-
트랜잭션의 성질 ACID
- 원자성
- 일관성
- 격리성
- 지속성
-
사용이유
- business을 하나의 트랜잭션 단위로, Service쪽으로 옮기는 작업할 때
- 중간에 데이터처리에 있어서 전체적으로 트랜젹션을 관리할수 있따.
- 만약 작동하다 중단될시 전체를 Rollback을 통해 원래 상태로 되돌린다.
- 이상없이 완료가 되면 commit을 진행한다.
sqlSession Batch처리
-
일반적인 sqlSession은
- sqlsession.open -> 1개 작업 ->sqlSession.close 순서대로 진행된다.
- 만약 작업이 10000000개라면 어떨까?
- sqlsession을 열고 닫으면서 10000000개의 작업을 수행해야된다.
- 수행시간에 있어서 문제가 있을것이다.
- sqlsession.open -> 1개 작업 ->sqlSession.close 순서대로 진행된다.
-
Batch를 사용해서
- sqlsession.open -> 10000000개 작업 ->sqlSession.close 을 수행할수 있따.
- 문제가 생길시 Rollback을 진행한다.
try catch
- method를 호출해주는쪽에 try catch를 통해 예외처리를 해주면된다.
- 각각해주면 좋지만 throw만 던져주고
- 최종적으로 받는 곳에서 일치하는 Exception마다 예외를 받아주면된다.
제약조건삭제(mysql)
### 제약조건확인
select * from information_schema.table_constraints where information_schema.table_constraints.table_schema = "#{dbName}";
### 제약조건 삭제
ALTER TABLE #{table} DROP CONSTRAINT #{제약조건삭제};
table 내용날리기
##헷갈리지말자!!
##테이블 안에 데이터초기화
delete from #{table명};
##테이블삭제
truncate table users;
##테이블삭제
drop table users;
두 table을 join해서 출력하고싶을때
- mapper에서 조인하고 vo에서 필요한 부분만 변수를 두어서 객체로 관리한다.
- ex) user와 board의 객체의 연결되는 객체를 얻고싶을 때!
- vo끼리 서로 상속(extends) 받으면된다,