20220829_Mon
참고)
학원 로드맵
웹개발 하기위해서
선수학습-java 1달
자바기반 웹개발- servlet,jsp -> 개념이 부족하면 다음에 배울것들이 모두 흐트러진다.
스프링부트 / jsp / react..
=>수료하면 그때부터 다시 공부해야한다..
- IOC: 제어의역전(코드제어의 주체가 바뀐다)
-> 사용해야하는 객체를 만들어서 코드 개발(개발자의 역할) ex)new boardDTO()..
-> 스프링에서는 객체를 스프링 컨테이너가 만들어준다.
-> 클래스간의 결합도를 낮추기위해서 new로 객체생성시 결합도가 너무 높기 때문에.
그럼 어떻게 스프링이 알아서 객체를 자동으로 만드냐??
- DI(Dependancy Injection) : 의존성 주입
- 스프링은 자동으로 객체를 만드는게 아니라 만들어진 객체 중 적절한 객체를 찾아 바인딩(연결)시켜준다!-> "의존성 주입"
- 의존성 주입을 하기 위해서는!
- 먼저 객체를 생성
- 방법 4가지(클래스명 바깥에 사용)
- (1) @Component:객체하나 생성(클래스명 맨 첫글자 소문자로 자동생성)
- (2) @Respository:객체하나 생성
- (3) @Service:객체하나 생성
- (4) @Controller: Component에서 파생/객체하나 생성
- 만들어진 객체를 의존성 주입시킨다.
- 방법 2가지 (어노테이션 사용)
- 1) @Autowired
- 2) @Resource: name값과 동일한 값의 객체를 가져오겠다
단, 의존성 주입은 디폴트 패키지를 기본으로 되어 있어야한다.
-스프링에서는 패키지명을 절대 수정할 수 없다. 안그럼 다시 만들어 사용해야한다!
예를 들어...
자바의 jsp 경우
:컨트롤러 실행시 jsp에서 .뒤에 끝나는 것과 같은 컨트롤러를 따라 실행한다. (스프링도 마찬가지)
Member컨트롤러(.me)
Item컨트롤러(.it)
Admin컨트롤러(.ad)
스프링의 경우
: 각 컨트롤러의 괄호 안의 내용을 기본경로 뒤에 넣으면 그 컨트롤러를 들어가겠다는 의미
Member컨트롤러(/member) -> http://localhost:8081/member/login
Item컨트롤러(/item) -> http://localhost:8081/item
Admin컨트롤러(/admin) -> http://localhost:8081/admin
thymeleafController.java 파일
package kh.study.board.testController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/test") //-> 이렇게 밖으로 빼면 안에 썻을때보다 중복되는 "/test" 부분을 제거할 수 있다.
public class thymeleafController {
//참고) return "aa";//template(기본) 폴더 안의 aa.html 파일을 실행하겠다
//경로이동: http://localhost:8081/test/ex1
@GetMapping("/ex1")// get 메소드를 사용( form태그 제외 나머지 모두 get)
public String textTest() {
//스프링에서 return: 이동할 페이지명 정하는 것
return "test/text_test";//template 기준으로 test 폴더안의 text_test.html 파일 실행
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"><!-- jsp에서 foreach문 사용할때 lib태그 사용하는 것과 같다.앞으로 html 만들때는 사용해야한다. 원래 html만들때 next누르고 별도로 생성한 htnl_thymeleaf를 선택하면 자동생성된다-->
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
hello
</body>
</html>
(초창기버전)
(현재버전)
: 컨트롤러에서 보낸 데이터값을(board) 받아서 가져와 사용하려는데 자바와 자바스크립트와 어떻게 다른가?
:
<span th:text="${board.title}"></span><br>
[[${board.title}]]
for_test.html 파일 생성
testController
package kh.study.board.testController;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import kh.study.board.vo.BoardVO;
@Controller
@RequestMapping("/test") //-> 이렇게 밖으로 빼면 안에 썻을때보다 중복되는 "/test" 부분을 제거할 수 있다.
public class thymeleafController {
//참고) return "aa";//template(기본) 폴더 안의 aa.html 파일을 실행하겠다
@GetMapping("/ex1")// get 메소드를 사용( form태그 제외 나머지 모두 get)
public String textTest(Model model) {//model 인터페이스 객채생성
//BoardVO에서 getter,setter 어너테이션 만들고
BoardVO vo = new BoardVO();
vo.setTitle("제목입니다");
vo.setWriter("작성자입니다");
model.addAttribute("board", vo);//
//스프링에서 return: 이동할 페이지명 정하는 것
return "test/text_test";//template 기준으로 test 폴더안의 text_test.html 파일 실행
}
@GetMapping("/for")
public String forTest(Model model) {
List<BoardVO> boardList = new ArrayList<>();
for(int i = 0 ; i<10; i++) {
BoardVO vo = new BoardVO();
vo.setTitle("제목" + (i +1));
vo.setWriter("admin");
boardList.add(vo);
}
model.addAttribute("list",boardList);
return "test/for_test";
}
}
<!DOCTYPE html>
<html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<td>제목</td>
<td>작성자</td>
</tr>
<tr th:each="board : ${list}"> <!-- list에서 for문 돌려서 board라는 이름으로 데이터를 빼오겠다. -->
<td th:text="${board.title}"></td>
<td th:text="${board.writer}"></td>
</tr>
</table>
<br>
<table border="1">
<tr>
<td>제목</td>
<td>작성자</td>
<td>현재 반복중인 인덱스 번호(0부터)</td>
<td>현재 반복중인 인덱스 번호(1부터)</td>
<td>총 갯수</td>
<td>현재 반복중인 객체정보</td>
<td>짝수행 여부</td>
<td>홀수행 여부</td>
<td>첫번째행 여부</td>
<td>마지막행 여부</td>
</tr>
<!-- status 변수 사용할 때-->
<tr th:each="board, status : ${list}"> <!-- list에서 for문 돌려서 board라는 이름으로 데이터를 빼오겠다. -->
<td th:text="${board.title}"></td>
<td th:text="${board.writer}"></td>
<td th:text="${status.index}"></td>
<td th:text="${status.count}"></td>
<td th:text="${status.size}"></td>
<td th:text="${status.current}"></td>
<td th:text="${status.even}"></td>
<td th:text="${status.odd}"></td>
<td th:text="${status.first}"></td>
<td th:text="${status.last}"></td>
</tr>
</table>
<br>
<table border="1">
<tr>
<td>제목</td>
<td>작성자</td>
<td>현재 반복중인 인덱스 번호(0부터)</td>
<td>현재 반복중인 인덱스 번호(1부터)</td>
<td>총 갯수</td>
<td>현재 반복중인 객체정보</td>
<td>짝수행 여부</td>
<td>홀수행 여부</td>
<td>첫번째행 여부</td>
<td>마지막행 여부</td>
</tr>
<!-- status 사용 안할 때-> boardStat 대체 -->
<tr th:each="board : ${list}"> <!-- list에서 for문 돌려서 board라는 이름으로 데이터를 빼오겠다. -->
<td th:text="${board.title}"></td>
<td th:text="${board.writer}"></td>
<td th:text="${boardStat.index}"></td>
<td th:text="${boardStat.count}"></td>
<td th:text="${boardStat.size}"></td>
<td th:text="${boardStat.current}"></td>
<td th:text="${boardStat.even}"></td>
<td th:text="${boardStat.odd}"></td>
<td th:text="${boardStat.first}"></td>
<td th:text="${boardStat.last}"></td>
</tr>
</table>
</body>
</html>
http://localhost:8081/test/for
@GetMapping("/if")
public String ifTest(Model model) {
BoardVO vo = new BoardVO();
vo.setTitle("제목1");
model.addAttribute("board",vo);
return "test/if_test";
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<span th:if="${board.title == '제목1'}" th:text="제목1입니다."></span>
<span th:unless="${board.title == '제목1'}" th:text="제목1아닙니다."></span>
</body>
</html>
@GetMapping("/if")
public String ifTest(Model model) {
BoardVO vo = new BoardVO();
vo.setTitle("제목11145");
model.addAttribute("board",vo);
return "test/if_test";
}
package kh.study.board.service;
import java.util.List;
import kh.study.board.vo.BoardVO;
public interface BoardService {
//게시글 목록조회
List<BoardVO> selectBoardList();
}
package kh.study.board.service;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import kh.study.board.vo.BoardVO;
public class BoardServiceImpl implements BoardService {
//쿼리 실행하는 객체
// SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
// SqlSession sqlSession;//생성이 아닌 선언만
//@Autowired어노테이션은 미리 생성한 객체를 의존성 주입 시킬 때 사용한다.
//아래코드가 진행이 된다는 것은, 프로젝트 실행 시
// 스프링이 내부적으로 sqlSessionTemplate 자료형으로 객체를 미리 만들어 놓기 때문에 사용가능하다.
//@Autowired는 그래서 동일한 자료형으로 객체가 미리 2개 이상 생성되어있다면,
//프로젝트 실행과 동시에 오류 발생
//-> DB로 이동
@Autowired//자동연결
SqlSessionTemplate sqlSession;
@Override
public List<BoardVO> selectBoardList() {
//원래 이클립스에서 하는 방식
// List<BoardVO> list = sqlSession.selectList("boardMapper.selectBoardList");
// return list;
// sqlSession.commit();(스프링은 자동 커밋)
//->(스프링) 그래서 이제 부터 한 줄로 작성 가능해짐
return sqlSession.selectList("boardMapper.selectBoardList");
}
// @Override
// public List<CategoryDTO> selectCategoryList() {
// List<CategoryDTO> list = sqlSession.selectList("itemMapper.selectCategoryList");
// sqlSession.commit();
// return list;
// }
}
<?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="boardMapper">
<resultMap type="kh.study.board.vo.BoardVO" id="board">
<id column="BOARD_NUM" property="boardNum"/>
<result column="TITLE" property="title"/>
<result column="WRITER" property="writer"/>
<result column="CONTENT" property="content"/>
<result column="CREATE_DATE" property="createDate"/>
</resultMap>
<select id="selectBoardList" resultMap="board">
SELECT BOARD_NUM
, TITLE
, WRITER
, CREATE_DATE
FROM SPRING_BOARD
ORDER BY BOARD_NUM DESC
</select>
</mapper>
package kh.study.board.vo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
//@Data
@Getter
@Setter
@ToString
public class BoardVO {
//lombok 어노테이션(위에) 을 이용해 getter,setter를 편하게 만들수있다
private int boardNum;
private String title;
private String content;
private String writer;
private String createDate;
}
@Controller
@RequestMapping("/board")// "/board"로 시작하면 무조건 컨트롤러 실행하겠다
public class Boardcontroller {
//boardService 라는 이름으로 만들어진 개체를 로드해서
//"의존성 주입"을 실행한다
//@Resource는 @autoWired와 비슷하지만 자료형이 같은 객체가 아니라
//name값이 같은 변수명을 가져와서 데이터를 넣어준다
@Resource(name = "boardService")
private BoardService boardService;//스프링에서는 선언만!
//게시글 목록 페이지
@GetMapping("/list")
public String selectBoardList() {
//게시글 목록 조회
boardService.selectBoardList();
return "board/board_list";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
게시글목록페이지
</body>
</html>
20220829 17:55:31.537 [http-nio-8081-exec-4] DEBUG j.sqltiming - com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1. SELECT BOARD_NUM
, TITLE
, WRITER
, CREATE_DATE
FROM SPRING_BOARD
ORDER BY BOARD_NUM DESC
{executed in 123 msec}
20220829 17:55:31.561 [http-nio-8081-exec-4] INFO j.resultsettable -
|----------|------|-------|------------|
|board_num |title |writer |create_date |
|----------|------|-------|------------|
|----------|------|-------|------------|