D+56::DB_DECODE함수/CASE문/스프링부트 FinalBoard 프로젝트 생성/ th:field + th:object 기능 사용

Am.Vinch·2022년 9월 15일
0
post-thumbnail

20220915_thu

DB

DB시험 문제 연습_ 6번문제
6. 사원의 사번, 이름, 부서번호, 부서명을 조회해보자. ( 조인서브쿼리 X )
부서명은 부서번호가 10일 때는 ‘인사부’, 20일 때는 ‘영업부’ 그 외의 값은 ‘생산부’로 조회되어야 한다. DECODE함수나 CASE 함수를 사용하여 쿼리문을 작성해보자. (10점) [수행준거 1.2, 2.2]

DECODE() 함수

  • 방법1) DECODE() 함수사용
-- //DECODE 함수//---
--(디코드함수 : 자바의 IF문과 같다 )
--DECODE(컬럼명,조건1,값1,조건2,값2,....,)
SELECT * FROM EMP;
-- DISTINCT : 중복제외 하나씩만 조회하기
SELECT DISTINCT JOB FROM EMP;--직급별조회
--시험문제 6번
-- 직급이 사원인 조건만 1의 값을 부여,그밖은 2의 값 출력
SELECT JOB
    , DECODE(JOB,'사원','1')
    , DECODE(JOB,'사원','1','2')
    , DECODE(JOB,'사원','1','대리','2','3')
    , DECODE(JOB,'사원','1','대리','2')--사원이면 1, 대리면 2, 나머지는 NULL
FROM EMP;


CASE 문

  • 방법2) CASE문 사용
  • CASE 문법
CASE WHEN 조건1 THEN1
--      WHEN 조건2 THEN 값2
--      ...
--      ELSE 값
-- END

--시험문제 6번
SELECT ENAME
    , JOB
    , CASE WHEN JOB = '사원' THEN '1'
        WHEN JOB = '대리' THEN '2'
        ELSE '3' 
      END
FROM EMP;

GROUP BY절 그룹함수(단일행함수)

-- 사용예시) 직급별 급여의 합 구하기
-- 해석) 직급이 사원이면 신입 아니면 고인물이라고 조회하고,
-- COMM 성과금이 NULL이면 0으로 조회하라
SELECT DECODE(JOB,'사원','신입','고인물')
    , NVL(COMM,0)
FROM EMP;
-- 그룹함수(단일행함수) : 데이터 조회시, 하나(한줄)의 데이터만 나오는 함수.
-- MAX(),SUM() 해당
-- 단, 단일행함수는 여러 행으로 조회되는 함수와 같이 사용불가능!
-- 대신 단일행함수끼리는 같이 사용 가능! 
SELECT MAX(SAL)
FROM EMP;
SELECT SUM(SAL)
FROM EMP;

-- 소속 부서별 평균 급여 조회
SELECT DISTINCT DEPTNO FROM EMP;

-- ROUND : 반올림함수
-- ROUND 값 뒤의 숫자는 반올림해서 몇번째까지 표현해라 
SELECT ROUND(123.456)
    , ROUND(123.456,1)
    , ROUND(123.456,2)
FROM DUAL;

-- ROUND 이용
SELECT DEPTNO
    , ROUND(AVG(SAL),2)
    , NVL(ROUND(AVG(COMM),2),0) -- 인센티브가 NULL이면 안된다
FROM EMP
GROUP BY DEPTNO;-- 주의)조회되는 데이터의 행의 갯수가 동일하지않으면 사용불가능!

--(참고)
-- SUBSTR 이용
-- 부서별로 묶어서 평균을 구하라.
SELECT SUBSTR(AVG(SAL),1,6)
FROM EMP
GROUP BY deptno; -- 주의)조회되는 데이터의 행의 갯수가 동일하지않으면 사용불가능!

-- 직급별 인원수를 조회하되,
-- 직급이 과장은 직급은 조회에서 제외하라.
-- 순서중요!! FROM - WHERE - GROUP BY
SELECT JOB
    , COUNT(EMPNO) 
FROM EMP 
WHERE JOB != '과장'
GROUP BY JOB;

-- 주의) 그룹결과값으로 조회해야할 때 
-- HAVING 함수 사용!!!
-- 직급별 인원수를 조회하되,
-- 해당직급의 인원수가 2명 이상인 직급에 대해서만 조회
-- 순서) FROM - GROUP BY - HAVING
SELECT JOB
    , COUNT(EMPNO) 
FROM EMP
GROUP BY JOB
HAVING COUNT(EMPNO) >= 2;

-- 직급별 인원수, 급여의 합을 조회하되,
-- 직급이 과장인 직급은 제외하고 ,직급별 인원수가 2명이상인 직급에 대해서만 조회
-- 단, 조회시 급여의 합을 기준으로 내림차순 조회
-- <순서> FROM > WHERE > GROUP BY > HAVING > ORDER BY
SELECT JOB, COUNT(EMPNO) , SUM(SAL)
FROM EMP
WHERE JOB != '과장'
GROUP BY JOB
HAVING COUNT(EMPNO) >= 2 
ORDER BY SUM(SAL) DESC 


스프링부트에서 게시판 만들기
실습 : 새로운 게시판 프로젝트를 처음부터 만들어 게시판 기능 구현하기

  • 프로젝트 생성 : FinalBoard
    < 프로젝트 셋팅 순서>
      1. 설정 : application.properties
      1. porm.xml파일에 필요한 jar파일 추가 : dependecies 추가(2개)
      1. 필요한 파일 추가 (쿼리 로그 출력을 위한 파일) : log4jdbc.log4j2.properties , logback.xml
  • DB파일 생성 : FINAL_BOARD.sql (SHOP_USER계정)
  • cf)사용할 기능
    • layout(fragment)
    • bootStrap
    • thymeleaf(detail)
    • validation(input태그 유효성처리검사)
    • spring security


1. 전체프로젝트에 폰트 설정
2. top.html 디자인 작업하기.
3. 회원가입 페이지 만들기


  • FinalBoard 프로젝트 파일 생성

  • BaordVO

    package kh.study.board.board.vo;
    import groovy.transform.ToString;
    import org.springframework.stereotype.Service;
    import lombok.Getter;
    @Getter
    @Service
    @ToString
    public class BoardVO {
    	private int boardNum;
    	private String title;
    	private String content;
    	private String memberId;
    	private String createDate;
    }
  • MemberVO
    package kh.study.board.member.vo;
    import groovy.transform.ToString;
    import lombok.Getter;
    import lombok.Setter;
    @Getter
    @Setter
    @ToString
    public class MemberVO {
    	private String memberId;
    	private String memberPw;
    	private String memberName;
    	private String memberTell;
    	private String isAdmin;
    	private String memberStatus;
    }

커맨드객체

커맨드객체

  • 커맨드객체는 html로 데이터를 전달하는 코드를 작성하지 않아도 자동으로 넘어간다.
  • 이때 데이터가 넘어가는 이름은 클래스명에서 앞글자만 소문자로 변경된 이름으로 넘어간다.
  • BoardController
@Controller
@RequestMapping("/board")
public class BoardController {
	@Resource(name = "memberService")
	private MemberService memberService;
	//목록페이지
	@GetMapping("/list")
	public String boardList() {
		return "content/board/board_list";
	}
	//join
	@GetMapping("/join")//a태그는 무조건 get 방식!!!(암기)
	public String join(MemberVO memberVO) {
		//자동으로 커맨드 객체는 넘어간다.(memberVO)
		//커맨드객체에 아이디값 임의로 넣어주면, html로 넘어갈때 데이터 넘어감
		System.out.println(memberVO);
		//memberVO.setMemberId(memberService.join(memberVO));
		return "content/board/join";
	}
	//로그인
	@GetMapping("/login")//a태그는 무조건 get 방식!!!(암기)
	public String login() {
		return "content/board/login";
	}
}
  • member-mapper
    <mapper namespace="memberMapper">
    <!-- 회원가입 -->
    <insert id="join">
    INSERT INTO BOARD_MEMBER (
    		MEMBER_ID, MEMBER_PW, MEMBER_NAME, MEMBER_TELL,MEMBER_STATUS
    ) VALUES(
    		#{memberId},#{memberPw},#{memberName},#{memberTell},'ACTIVE'
    )
    </insert>   
    </mapper> 
  • common.css
@charset "UTF-8";
@font-face {
    font-family: 'HallymGothic-Regular';
    src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2204@1.0/HallymGothic-Regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
}
body{
    font-family: 'HallymGothic-Regular';
	font-size: 25px;
}
a{
	text-decoration: none;
	color: #224B0C;
}
a:hover {
	color: #A1C298;
}
  • board_list.html
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
    	xmlns:layout="http://www.ultra.net.nz/thymeleaf/layout" 
    	layout:decorate="~{layout/base_layout}"><!-- 콘솔 warn 안뜨기위해 -->
    <div layout:fragment="content">
    	게시글 목록....
    </div>
    </html>

타임리프

th:field / th:object

  • th 타임리프사용하려면 경로이동은!!! 골뱅이+{}사용하기!!!
  • th:object="${memberVO}" 는 데이터받기위해 사용 : 컨트롤러에서 보낸 객체 받아오기!!!
  • 커맨드객체 memberVO는 자동으로 데이터 가져와서 사용가능하다
  • 단, th:field는 th:object와 반드시 함께 사용하는 애트리뷰트
  • formx태그에 th:object로 넘어오는 커맨드객체를 지정할 경우. 해당 폼 태그 내에서 th:field 속성으로 자동으로 id,name,value 값을 세팅할 수 있다.
  • 개발자모드 콘솔을 보면 th:feild속성값만으로 name,id,value값 모두 확인가능하다!!!
  • th:field 받지않고 원래 사용하던 방법
    id :<input type="text" name="memberId" id="memberId">
    th:field 받아와서 사용하는 방법
    *{memberId}라는 값으로 들어오는 데이터 받아와서 사용하겠다.
  • join.html

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
    	xmlns:layout="http://www.ultra.net.nz/thymeleaf/layout"
    	layout:decorate="~{layout/base_layout}">
    <div layout:fragment="content">
    	<!-- row justify-content-center : 가운데 정렬 -->
    	<div class="row justify-content-center">
    		<div class="col-6">
    			<form th:action="@{/member/join}" class="row g-3" method="post" th:object="${memberVO}">
    				<div class="col-12">
    					<label for="memberId" class="form-label"> ID </label> 
    					<input type="text" class="form-control" th:field="*{memberId}">
    				</div>
    				<div class="col-12">
    					<label for="memberPw" class="form-label">PASSWORD</label> 
    					<input type="password" class="form-control" th:field="*{memberPw}">
    				</div>
    				<div class="col-12">
    					<label for="memberName" class="form-label">NAME</label> 
    					<input type="text" class="form-control" th:field="*{memberName}">
    				</div>
    				<div class="col-4">
    					<!-- 연락처는 타임리프 사용하면 에러난다!!! -->					
    					<label for="memberTell" class="form-label">TELL</label> 
    					<select id="memberTell" class="form-select" >
    						<option selected>010</option>
    						<option>011</option>
    					</select>
    				</div>
    				<div class="col-4">
    					<label for="" class="form-label">&nbsp;</label> 
    					<input type="text" class="form-control" id="" name="">
    				</div>
    				<div class="col-4">
    					<label for="" class="form-label">&nbsp;</label> 
    					<input type="text" class="form-control" id="" name="">
    				</div>
    				<div class="col-12 d-grid gap-2">
    					<button type="submit" class="btn btn-primary">JOIN</button>
    				</div>
    			</form>
    		</div>
    	</div>
    </div>
    </html>
  • login.html

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
    	xmlns:layout="http://www.ultra.net.nz/thymeleaf/layout" 
    	layout:decorate="~{layout/base_layout}">
    <div layout:fragment="content">
    	login 
    </div>
    </html>
  • top.html
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <div th:fragment="topFragment">
    <!-- 로그인 클릭시 로그인html파일 이동방법 -->
    	<!-- 1번 <a href="/board/login">login</a> -->
    	<!-- 2번 <a th:href="@{/board/login}"> login</a><!-- 타임리프 경로이동시!!! 골뱅이+중괄호 -->
    	<div class="row">
    		<div class="col text-end" style="color:#224B0C;">
    			<a th:href="@{/board/login}">login</a><!-- a태그 -> get방식!!! -->
    			<a th:href="@{/board/join}">join</a><!-- a태그 -> get방식!!! -->
    			<!-- <span th:onclick="location.href='/board/join';"></span> -->
    		</div>
    	</div>
    	<div class="row">
    		<div class="col text-center" style="background-color: #EEF2E6;">
    			<span style="font-weight: bold; font-size: 50px; color: #3D8361;">Board</span>
    		</div>
    	</div>
    </div>
    </html>
  • base_layout.html
    <!DOCTYPE html>
    <!-- 타임리프,레이아웃 기능 사용하겠다 -->
    <html xmlns:th="http://www.thymeleaf.org"
    		xmlns:layout="http://www.ultra.net.nz/thymeleaf/layout">
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <!-- 부트스트랩 사용 1 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
    <link href="/css/common.css" rel="stylesheet">
    </head>
    <body>
    <!-- 화면에 보여지는 모든 내용은 여기 div태그 안에서 표시된다 -->
    <div class="container">
    	<div class="row">
    		<div class="col">
    			<div th:replace="fragment/top::topFragment" ></div>
    		</div>
    	</div> 
    	<div class="row">
    		<div class="col">
    			<div layout:fragment="content"></div>
    		</div>
    	</div> 
    </div>
    <!-- jquery 로딩 -->
    <script src="https://code.jquery.com/jquery-latest.min.js"></script>
    <!-- 부트스트랩 로딩 _사용 2 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8" crossorigin="anonymous"></script>
    </body>
    </html>
  • MemberService
    public interface MemberService {
     void join(MemberVO memberVO);
    }
  • MeberServiceImpl
    @Service("memberService")
    public class MemberServiceImpl implements MemberService{
    	@Autowired//어노테이션으로 객체생성
    	private SqlSessionTemplate sqlSession;
    	//회원가입
    	@Override
    	public void join(MemberVO memberVO) {
    		sqlSession.insert("memberMapper.join", memberVO);
    	}
    }
profile
Dev.Vinch

0개의 댓글