22.06.27 snsboard 테이블 생성,등록하기,목록띄우기
-- SNS 게시판
CREATE TABLE snsboard (
bno NUMBER(10,0) PRIMARY KEY,
writer VARCHAR2(50) NOT NULL,
uploadpath VARCHAR2(100) NOT NULL,
fileloca VARCHAR2(100) NOT NULL,
filename VARCHAR2(50) NOT NULL,
filerealname VARCHAR2(50) NOT NULL,
content VARCHAR2(2000),
regdate DATE DEFAULT sysdate
);
CREATE SEQUENCE snsboard_seq
START WITH 1
INCREMENT BY 1
MAXVALUE 1000
NOCYCLE
NOCACHE;
<script>
package com.spring.myweb.command;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class SnsBoardVO {
private int bno;
private String writer;
private String uploadpath;
private String fileloca;
private String filename;
private String filerealname;
private String content;
private Timestamp regdate;
}
</script>
package com.spring.myweb.snsboard.mapper;
public interface ISnsBoardMapper {
//등록
void insert(SnsBoardVO vo);
//목록
List<SnsBoardVO> getList(PageVO paging);
//상세
SnsBoardVO getDetail(int bno);
//삭제
void delete(int bno);
}
db-config에 mapper 등록
<mybatis-spring:scan base-package="com.spring.myweb.freeboard.mapper"/>
<mybatis-spring:scan base-package="com.spring.myweb.reply.mapper"/>
<mybatis-spring:scan base-package="com.spring.myweb.user.mapper"/>
<mybatis-spring:scan base-package="com.spring.myweb.snsboard.mapper"/>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spring.myweb.snsboard.mapper.ISnsBoardMapper">
</mapper>
package com.spring.myweb.snsboard.service;
public interface ISnsBoardService {
//등록
void insert(SnsBoardVO vo);
//목록
List<SnsBoardVO> getList(PageVO paging);
//상세
SnsBoardVO getDetail(int bno);
//삭제
void delete(int bno);
}
package com.spring.myweb.snsboard.service;
@Service
public class SnsBoardService implements ISnsBoardService {
@Autowired
private ISnsBoardMapper mapper;
@Override
public void insert(SnsBoardVO vo) {
}
@Override
public List<SnsBoardVO> getList(PageVO paging) {
return null;
}
@Override
public SnsBoardVO getDetail(int bno) {
return null;
}
@Override
public void delete(int bno) {
}
}
로그인 안한 사람이라면 로그인 진행될수 있게 한다.
<div class="menu1">
<c:choose>
<c:when test="${login != null}">
<p>
<img src="../resources/img/profile.png"> ${login.userName}님
</p>
<ul>
<li>내정보</li>
<li>내쿠폰</li>
<li>내좋아요게시물</li>
</ul>
</c:when>
<c:otherwise>
<button type="button" class="btn btn-info" onclick="location.href=<c:url value='/user/userLogin'/>">로그인</button>
</c:otherwise>
</c:choose>
</div>
form태그 없이 비동기로 form데이터 보내기
<script>
$(function() {
//등록하기 버튼 클릭 이벤트
$('#uploadBtn').click(function() {
regist();
});
//등록을 담당하는 함수
function regist() {
//세션에서 현재 로그인 중인 사용자 정보(아이디)를 얻어오기
const user_id = '${sessionScope.login.userId}'
//자바스크립트의 파일 확장자 체크 검색.
let file = $('#file').val();
console.log(user_id); //kim1234
console.log(file); //C:\fakepath\sky.jpg
//.을 제거한 확장자만 얻어낸 후 그것을 소문자로 일괄 변경
file = file.slice(file.indexOf('.')+1).toLowerCase();
console.log(file); //jpg
if(file !== 'jpg' && file !== 'png' && file !== 'jpeg' && file !== 'bmp'){
alert('이미지 파일(jpg,png,jpeg,bmp)만 등록이 가능합니다.');
$('#file').val(''); //input창 비우기
return;
} else if(user_id === ''){ //세션 데이터가 없다 -> 로그인 X
alert('로그인인 필요한 서비스 입니다.');
return;
}
//ajax 폼 전송의 핵심 FormData 객체.
const formData = new FormData();
const data = $('#file');
console.log('폼데이터: ' + formData);
console.log('data: ' + data);
console.log(data[0]); //input type="file" 요소를 지목할 때 사용.
console.log(data[0].files); //파일 태그에 담긴 파일 정보를 확인하는 키값.
console.log(data[0].files[0]); //사용자가 등록한 최종 파일 정보
/*
data[index] -> 파일 업로드 버튼이 여러개 존재할 경우 요소의 인덱스를 지목해서 가져오는 방법.
우리는 요소를 id로 취득했기 때문에 하나만 찍히지만, class 이름 같은 걸로 지목하면 여러개가 취득되겠죠?
files[index] -> 파일이 여러 개 전송되는 경우, 몇 번째 파일인지를 지목.
우리는 miltiple 속성을 주지 않았기 때문에 0번 인덱스 밖에 없는 겁니다.
*/
//FormData 객체에 사용자가 업로드한 파일의 정보다 들어있는 객체를 전달해야한다.
formData.append('file', data[0].files[0]);
//formData.append('file', data[0].files[1]); //miltiple사용했을 경우 파일마다 정보를 넣어준다.
//content(글 내용) 값을 얻어와서 폼 데이터에 추가
const content = $('#content').val();
formData.append('content', content);
//비동기 방식으로 파일 업로드 및 게시글 등록을 진행
$.ajax({
url: '<c:url value="/snsBoard/upload"/>',
type: 'post',
data: formData, //폼 데이터 객체를 넘깁니다.
contentType: false,
//ajax 방식에서 파일을 넘길 때는 반드시 false로 처리 -> "multipart/form-data"로 선언됨.
processData: false, //폼 데이터를 &변수=값&변수=값..형식으로 변경되는 것을 막는 요소
success: function(result) {
if(result === 'success'){
$('#file').val(''); //파일 선택지 비우기
$('#content').val(''); //글 영역 비우기
$('.fileDiv').css('display', 'none'); //미리보기 감추기
getList(1, true); //글 목록 함수 호출.
} else {
alert('업로드에 실패했습니다. 관리자에게 문의해 주세요.');
}
},
error: function(request, status, error) {
console.log('code: ' + request + '\n message: ' + request.responseText + "\n" + 'error: ' + error);
alert('업로드에 실패했습니다. 관리자에게 문의해 주세요.');
}
});
}
}); //end jQuery
</script>
<script>
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file, String content, HttpSession session) {
String writer = ((UserVO)session.getAttribute("login")).getUserId();
//날짜별로 폴더를 생성해서 파일을 관리
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
String fileloca = sdf.format(date);
//저장할 폴더 경로
String uploadPath = "C:\\Users\\jwons\\OneDrive\\바탕 화면\\upload\\" + fileloca;
File folder = new File(uploadPath);
if(!folder.exists()) {
folder.mkdirs(); //폴더가 존재하지 않는다면 생성하라.
}
//원본 파일명.
String fileRealName = file.getOriginalFilename();
//파일명을 고유한 랜덤 문자로 생성.
UUID uuid = UUID.randomUUID();
String uuids = uuid.toString().replaceAll("-", ""); //'-'다 삭제
//확장자를 추출합니다.
String fileExtension = fileRealName.substring(fileRealName.indexOf("."), fileRealName.length());
System.out.println("저장할 폴더 경로: " + uploadPath);
System.out.println("실제 파일명: " + fileRealName);
System.out.println("폴더 명: " + fileloca);
System.out.println("확장자: " + fileExtension);
System.out.println("고유랜덤문자 : " + uuids);
String fileName = uuids + fileExtension;
System.out.println("변경해서 저장할 파일명: " + fileName);
//업로드한 파일을 서버 컴퓨터 내의 지정한 경로에 실제로 저장.
File saveFile = new File(uploadPath + "\\" + fileName);
try {
file.transferTo(saveFile);
} catch (Exception e) {
e.printStackTrace();
}
//DB에 insert 작업을 실행.
SnsBoardVO snsVO = new SnsBoardVO(0, writer, uploadPath, fileloca, fileName, fileRealName, content, null);
service.insert(snsVO);
return "success";
}
</script>
@Override
public void insert(SnsBoardVO vo) {
mapper.insert(vo);
}
<!-- 등록하기 -->
<insert id="insert">
INSERT INTO snsboard
(bno, writer, uploadpath, fileloca, filename, filerealname, content)
VALUES(snsboard_seq.NEXTVAL, #{writer}, #{uploadpath}, #{fileloca}, #{filename}, #{filerealname}, #{content})
</insert>
<script>
//리스트 작업
let str = '';
let page = 1;
getList(1, true);
function getList(page, reset) {
if(reset === true){
str = ''; //화면 리셋 여부가 true라면 str변수를 초기화.
}
$.getJSON(
'<c:url value="/snsBoard/getList?pageNum=' + page + '" />',
function(list) {
console.log(list);
for(let i=0; i<list.length; i++){
str +=
`<div class="title-inner">
<!--제목영역-->
<div class="profile">
<img src="<c:url value='/img/profile.png'/>">
</div>
<div class="title">
<p>` + list[i].writer + `</p>
<small>` + timeStamp(list[i].regdate) +`</small>
<a href="">이미지 다운로드</a>
</div>
</div>
<div class="content-inner">
<!--내용영역 내용은 NOT NULL이 아니라서 삼항연산식을 이용해서 검사-->
<p>` + (list[i].content === null ? '' : list[i].content) +`</p>
</div>
<div class="image-inner">
<!-- 이미지영역 -->
<img src="<c:url value='/snsBoard/display?fileLoca=` + list[i].fileloca + `&fileName=` + list[i].filename + `'/>">
</div>
<div class="like-inner">
<!--좋아요-->
<img src="../resources/img/icon.jpg"> <span>522</span>
</div>
<div class="link-inner">
<a href="##"><i class="glyphicon glyphicon-thumbs-up"></i>좋아요</a>
<a href="##"><i class="glyphicon glyphicon-comment"></i>댓글달기</a>
<a href="##"><i class="glyphicon glyphicon-remove"></i>삭제하기</a>
</div>
</div>`;
$('#contentDiv').html(str);
} //end for
}
);//end getJSON
}//end getList()
</script>
//비동기 통신 후 가져올 글 목록
@GetMapping("/getList")
@ResponseBody
public List<SnsBoardVO> getList(PageVO paging){
paging.setCpp(3);
return service.getList(paging);
}
@Override
public List<SnsBoardVO> getList(PageVO paging) {
return mapper.getList(paging);
}
SnsBoardVO 별칭 추가
<typeAliases>
<typeAlias type="com.spring.myweb.command.UserVO" alias="user" />
<typeAlias type="com.spring.myweb.command.ReplyVO" alias="reply" />
<typeAlias type="com.spring.myweb.command.FreeBoardVO" alias="board" />
<typeAlias type="com.spring.myweb.command.SnsBoardVO" alias="sns" />
</typeAliases>
<!-- 글 전체 목록 -->
<select id="getList" resultType="sns">
SELECT * FROM
(
SELECT ROWNUM AS rn, tbl.* FROM
(
SELECT * FROM snsboard
ORDER BY bno DESC
) tbl
)
<![CDATA[
WHERE rn > (#{pageNum}-1) * #{cpp}
AND rn <= #{pageNum} * #{cpp}
]]>
</select>