@Component = 스프링으로 하여금 IOC 컨테이너에 객체생성해서 넣어 놓아라.
@Controller = 컨트롤러 객체(new 객체생성) = (최고부모)@Component + 의미
@Service = 커맨드 객체 = (최고부모)@Component + 의미
@Repository = DAO 객체 = (최고부모)@Component + 의미
@RequiredArgsConstructor = Autowired에 생성자 주입해 줌
@Autowired = 스프링에게(주입) 4바이트 주소를 줌 | ioc컨테이너 안에 있는 객체 찾아서 넣어라
[RequiredArgsConstructor 예시] @RequiredArgsConstructor // Autowired에 생성자 주입해 줌 public class BoardServiceImpl implements BoardService { @Autowired // 주입 private BoardDAO dao; // BoardDAO dao = new BoardDAO(); @Autowired // 필드 주입 private GradeVO gradeVO; @Override public List<BoardVO> getList() { log.info("getList().."); return dao.boardSelect(); } }
・(권장)생성자 주입(Constructor Injection) : 순환 참조 방지 가능
개발을 하다 보면 여러 컴포넌트 간에 의존성이 생김.
ex) A가 B를 참조하고, B가 다시 A를 참조하는 순환 참조되는 코드
⇒생성자 주입 방법을 사용하면 순환 참조 방지 가능
@Autowired // 생성자 주입 public BoardServiceImpl(GradeVO gradeVO) { this.gradeVO = gradeVO;}
・수정자 주입(Setter 주입, Setter Injection)
@Autowired // Setter주입 (수정된 주입) public void setGradeVO(GradeVO gradeVO) { this.gradeVO = gradeVO;}
・필드 주입(Field Injection)
@Autowired // 필드 주입 private GradeVO gradeVO;
소스적으로 스프링이란?
WebApplicationContext & IOC 컨테이너
예시)
String configLocation = "classpath:applicationCTX2.xml";
AbstractApplicationContext ctx = new GenericXmlApplicationContext(configLocation);
[예시 GradeVO.java] @Getter @Setter @AllArgsConstructor @ToString @Component public class GradeVO { private int kor; private int eng; private int math; // @NoArgsConstructor의 역할 public GradeVO() { this.kor = 85; this.eng = 76; this.math = 76; } } --------------------------------------------------------------------- [예시 GradeController.java] package edu.global.ex.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.*; import org.springframework.ui.*; import org.springframework.web.bind.annotation.*; import edu.global.ex.BoardService; import edu.global.ex.VO.GradeVO; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Controller // (@Component + 의미) BoardController board = new BoardController(); @RequestMapping("/jboard/*") // jboard로 들어오는 모든 것들은 BoardController를 생성해라 public class BoardController { @Autowired private GradeVO gradeVO; @GetMapping("/list") public String view_list(Model model) { log.info("view_list().."); // 디버그 System.out.println(gradeVO); model.addAttribute("boards", boardService.getList()); return "/board/list"; } }
[결과값]
[계산 EmpDAO.java] package edu.global.ex.repository; import java.sql.*; import java.util.*; import java.util.Date; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; import org.springframework.stereotype.Repository; import edu.global.ex.VO.*; import lombok.extern.slf4j.Slf4j; @Slf4j @Repository public class EmpDAO { private String url = "jdbc:oracle:thin:@localhost:1521:xe"; private String uid = "scott"; private String upw = "tiger"; public EmpDAO() { try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (Exception e) { e.printStackTrace(); } } public List<EmpVO> empSelect() { List<EmpVO> emps = new ArrayList<EmpVO>(); Connection con = null; Statement stmt = null; ResultSet resultSet = null; try { String sql = "Select * from emp"; con = DriverManager.getConnection(url, uid, upw); stmt = con.createStatement(); resultSet = stmt.executeQuery(sql); while (resultSet.next()) { int empno = resultSet.getInt("empno"); String ename = resultSet.getString("ename"); String job = resultSet.getString("job"); int mgr = resultSet.getInt("mgr"); Date hiredate = resultSet.getDate("hiredate"); int sal = resultSet.getInt("sal"); int comm = resultSet.getInt("comm"); int deptno = resultSet.getInt("deptno"); EmpVO vo = new EmpVO(empno, ename, job, mgr, hiredate, sal, comm, deptno); emps.add(vo); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (resultSet != null) resultSet.close(); if (stmt != null) stmt.close(); if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); } } return emps; } public EmpVO contentView(int empno) { EmpVO emp = null; Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { String query = "select * from emp where empno = ?"; connection = DriverManager.getConnection(url, uid, upw); preparedStatement = connection.prepareStatement(query); preparedStatement.setInt(1, empno); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { int empn = resultSet.getInt("empno"); String ename = resultSet.getString("ename"); String job = resultSet.getString("job"); int mgr = resultSet.getInt("mgr"); Date hiredate = resultSet.getDate("hiredate"); int sal = resultSet.getInt("sal"); int comm = resultSet.getInt("comm"); int deptno = resultSet.getInt("deptno"); emp = new EmpVO(empn, ename, job, mgr, hiredate, sal, comm, deptno); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (resultSet != null) resultSet.close(); if (preparedStatement != null) preparedStatement.close(); if (connection != null) connection.close(); } catch (Exception e2) { e2.printStackTrace(); } } return emp; } } --------------------------------------------------------------------- [계산 EmpVO.java] package edu.global.ex.VO; import java.util.Date; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; @Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString public class EmpVO { private int empno; private String ename; private String job; private int mgr; private Date hiredate; private int sal; private int comm; private int deptno; } --------------------------------------------------------------------- [계산 EmpController.java] package edu.global.ex.controller; import org.springframework.beans.factory.annotation.Autowired; 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 edu.global.ex.EmpService; import edu.global.ex.VO.BoardVO; import edu.global.ex.VO.EmpVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Controller // (@Component + 의미) BoardController board = new BoardController(); @RequestMapping("/emp/*") // jboard로 들어오는 모든 것들은 BoardController를 생성해라 @RequiredArgsConstructor public class EmpController { @Autowired // (주입)객체에 주소를 줌 private EmpService empService; // BoardService boardService = new BoardServiceImpl(); @GetMapping("/list") public String view_list(Model model) { log.info("view_list().."); // 디버그 model.addAttribute("emps", empService.getList()); return "/emp/list"; } @GetMapping("/content_view") public String content_view(EmpVO empVO, Model model) { log.info("content_view().."); // 디버그 int eno = empVO.getEmpno(); empVO = empService.get(eno); model.addAttribute("content_view", empVO); return "/emp/content_view"; } } --------------------------------------------------------------------- [계산 EmpService.java] package edu.global.ex; import java.util.List; import edu.global.ex.VO.BoardVO; import edu.global.ex.VO.EmpVO; public interface EmpService { public List<EmpVO> getList(); public EmpVO get(int eno); } --------------------------------------------------------------------- [계산 EmpServiceImpl.java] package edu.global.ex; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import edu.global.ex.VO.*; import edu.global.ex.repository.BoardDAO; import edu.global.ex.repository.EmpDAO; import lombok.*; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Service @RequiredArgsConstructor // Autowired에 생성자 주입해 줌 public class EmpServiceImpl implements EmpService { @Autowired // 주입 private final EmpDAO dao; @Override public List<EmpVO> getList() { log.info("getList().."); return dao.empSelect(); } @Override public EmpVO get(int eno) { log.info("get(int bno).."); return dao.contentView(eno); } } --------------------------------------------------------------------- [계산 lsit.jsp] <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <table width="500" cellpadding="0" cellspacing="0" border="1" style="text-align:center"> <tr> <th>empno</th> <th>ename</th> <th>job</th> <th>mgr</th> <th>hiredate</th> <th>sal</th> <th>comm</th> <th>deptno</th> </tr> <c:forEach var="emp" items="${emps}"> <tr> <td>${emp.empno}</td> <td>${emp.ename}</td> <td>${emp.job}</td> <td>${emp.mgr}</td> <td>${emp.hiredate}</td> <td>${emp.sal}</td> <td>${emp.comm}</td> <td>${emp.deptno}</td> </tr> </c:forEach> </table> </body> </html> --------------------------------------------------------------------- [계산 content_view.jsp] <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> $(document).ready(function (){ $('#a-delete').click(function(event){ //prevendDefault()는 href로 연결해 주지 않고 단순히 click에 대한 처리를 하도록 해준다. event.preventDefault(); console.log("ajax 호출전"); $.ajax({ type : "DELETE", url : "${pageContext.request.contextPath}/restful/emp/" + "${content_view.empno}", data:{"empno":"${content_view.empno}"}, success: function (result) { console.log(result); if(result == "SUCCESS"){ //getList(); } }, error: function (e) { console.log(e); } }) }); }); </script> </head> <body> <table id="list-table" width="500" cellpadding="0" cellspacing="0" border="1"> <form action="modify" method="get"> <input type="hidden" name="empno" value="${content_view.empno}"> <tr> <td> EMPNO </td> <td> ${content_view.empno} </td> </tr> <tr> <td> ENAME </td> <td> <input type="text" name="ename" value="${content_view.ename}"></td> </tr> <tr> <td> JOB </td> <td> <input type="text" name="job" value="${content_view.job}"></td> </tr> <tr> <td> MGR </td> <td> <input type="text" name="mgr" value="${content_view.mgr}"></td> </tr> <tr> <td> HIREDATE </td> <td> <input type="text" name="hiredate" value="${content_view.hiredate}"></td> </tr> <tr> <td> SAL </td> <td> <input type="text" name="sal" value="${content_view.sal}"></td> </tr> <tr> <td> COMM </td> <td> <input type="text" name="comm" value="${content_view.comm}"></td> </tr> <tr> <td> DEPTNO </td> <td> <input type="text" name="deptno" value="${content_view.deptno}"></td> </tr> <tr > <td colspan="2"> <input type="submit" value="수정"> <a href="list">목록보기</a> <a id="a-delete">삭제</a> <a href="reply_view?empno=${content_view.empno}">답변</a></td> </tr> </form> </table> </body> </html>
[결과값]
MyBatis or JPA = DAO : 스프링 시큐리티에 사용
https://mybatis.org/mybatis-3/ko/getting-started.html
[pom.xml]
<!-- MyBatis 라이브러리 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- MyBatis sql pretty -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
[application.properties]
mybatis.mapper-locations=classpath:mappers/**/*.xml
[계산 BoardMapper.xml] <?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="edu.global.ex.mapper.BoardMapper"> <!-- BoardMapper.java의 interface를 구현하겠다. --> <select id="getList" resultType="edu.global.ex.vo.BoardVO"> <!-- BoardMapper.java의 getList함수를 끌고 온다. --> <!-- BoardMapper.java의 List<BoardVO>를 끌고 온다.(DAO를 만들지 않아도 됨) --> <![CDATA[select * from mvc_board order by bGroup desc, bStep asc]]> </select> <select id="get" resultType="edu.global.ex.vo.BoardVO" parameterType="edu.global.ex.vo.BoardVO"> <![CDATA[select * from mvc_board where bid = #{bid}]]> <!-- #{bid} : BoardVO get(BoardVO vo) 안에 있는 필드 이름 사용 가능 --> </select> </mapper> --------------------------------------------------------------------- [계산 BoardController.java] package edu.global.ex.controller; import org.springframework.beans.factory.annotation.Autowired; 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 edu.global.ex.BoardService; import edu.global.ex.vo.BoardVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Controller // (@Component + 의미) BoardController board = new BoardController(); @RequestMapping("/jboard/*") // jboard로 들어오는 모든 것들은 BoardController를 생성해라 @RequiredArgsConstructor public class BoardController { @Autowired // (주입)객체에 주소를 줌 private BoardService boardService; // BoardService boardService = new BoardServiceImpl(); @GetMapping("/list") public String view_list(Model model) { log.info("view_list().."); // 디버그 model.addAttribute("boards", boardService.getList()); return "/board/list"; } @GetMapping("/content_view") public String content_view(BoardVO boardVO, Model model) { log.info("content_view().."); // 디버그 boardVO = boardService.get(boardVO); model.addAttribute("content_view", boardVO); return "/board/content_view"; } } --------------------------------------------------------------------- [계산 BoardMapper.java] package edu.global.ex.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import edu.global.ex.vo.BoardVO; @Mapper // MyBatis 연결을 알려주는 것 public interface BoardMapper { // interface를 BoardMapper.xml에서 구현한다. >> Mybatis public List<BoardVO> getList(); public BoardVO get(BoardVO vo); } --------------------------------------------------------------------- [계산 BoardService.java] package edu.global.ex; import java.util.List; import edu.global.ex.vo.BoardVO; public interface BoardService { public List<BoardVO> getList(); public BoardVO get(BoardVO vo); } --------------------------------------------------------------------- [계산 BoardServiceImpl.java] package edu.global.ex; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import edu.global.ex.mapper.BoardMapper; import edu.global.ex.repository.BoardDAO; import edu.global.ex.vo.*; import lombok.*; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Service @RequiredArgsConstructor // Autowired에 생성자 주입해 줌 public class BoardServiceImpl implements BoardService { @Autowired private BoardMapper mapper; @Override public List<BoardVO> getList() { log.info("getList().."); return mapper.getList(); } @Override public BoardVO get(BoardVO vo) { log.info("get(int bno).."); return mapper.get(vo); } }
[결과값]