날아라쩡글이의 블로그입니다.

DB Access 방법 (CRUD) 본문

중앙 HTA (2106기) story/spring java framwork story

DB Access 방법 (CRUD)

날아라쩡글이 2021. 12. 28. 16:09
728x90
반응형

BasicDataSource

  • connectionPool을 가지고 있다. 
  • 데이터베이스에서 밀리 Connection객체를 만들고 보관, 관리하고 있다.
  • 미리 connection을 맺고 있기 때문에 connection에 대한 시간이 줄어 든다. 
  • common-dbcp 라이브러리가 제공하는 BasicDataSource는 가장 일반적으로 많이 사용되는 DataSource의 구현체이다. 
  • jdbc드라이버의 클래스명, 데이터베이스 접속 URL, 사용자명, 비밀번호를 제공해야한다. 
  • 종류가 많고, DataSource를 구현한 객체이면 된다. 

JdbcTemplate

  • int update(String sql, object...args)
    • insert, update, delete
  • T queryForObject(String sql, object...args)
    • 객체 한건에 대한 select
  • List<T> query(String sql, obejct...args)
    • 객체 여러건에 대한 select
  • DB access를 위하여 DataSource에 의존하고 있다. 
  • 커넥션을 제공하는 ConnectionPool객체를 제공받아야한다. 
  • object ...args는 가변길이 매개변수를 의미한다. 
  • DB Access의 작업이 쉬워진다. 
    • spring은 SQL Exception이 발생하지않고, DataAccessException이 발생한다. 

EmployeeDao

  • SQL실행작업을 지원하는 JdbcTemplate객체를 제공받아야한다. 
  • 제공받고 SQL을 여기서 작성한다. 

EmployeeService

  • EmployeeDao는 직원관리에 필요한 데이터베이스 엑세스를 지원한는 인터페이스다. 
  • 스프링 컨테이너에 빈으로 등록된 EmployeeDao 인터페이스의 구현객체를 의존성 주입을 사용해서 제공받는다. 
  • 업무로직 구현에 필요한 데이터베이스 엑세스 작업을 지원하는 EmployeeDaoImpl 객체를 제공받아야한다. 

 

스프링 프레임 워크의 DB Access

  • javax.SQL.DataSource인터페이스를 구현한 ConnectionPool구현객체가 반드시 필요하다.
    • commons-dbcp라이브러리가 반드시 필요하다.
  • 모든 데이터베이스엑세스 작업 중 오류가 발생하면 DataAccessException이 발생한다. 
    • DataAccessException은 RuntimeException의 하위 클래스다.
    • DataAccessException은 unchecked예외이다. 
      • try-catch작업을 하지 않아도된다. 
    • DataAccessException은 상속받는 다양한 하위 클래스가 존재한다. 
    • DB오류코드를 조사하고, 그에 해당하는 Exception을 발생시킨다. 
  • spring Framwork의 특징
    • 다양한 xxxTemplate, xxxDaoSupport클래스를 제공한다. 
      • 다양한 데이터베이스 엑세스 작업을 쉽게 구현할 수 있도록, 데이터베이스 엑세스 기술별로 다양한 xxxTemplate, xxxDaoSupport클래스를 제공한다. 
    • jdbc기술
      • JdbcTemplate
      • JdbcDaoSupport
    • ibatis기술
      • SqlmapClientDaoSupport
      • SqlmapClientTemplate
    • hibernate기술
      • HibernateTemplate
      • HibernateDaoSupport
    • 다양한 데이터베이스 엑세스 프레임워크와 연동을 지원한다. 
      • ibatis(spring 4버젼부터 제외), myBatis, Hibernate, JPA
    • 선언적 트랜잭션처리를 지원한다. 
      • 트랜잭션처리와 관련된 코드를 직접 장성하는 것이 아니라 트랜잭션 처리가 필요한 클래스나 메소드에 어노테이션을 부착하거나 트랜잭션처리가 필요한 클래스나 패키지를 지정하기만 하면 트랜젝션 처리가 자동으로 지원된다. 
      • spring에서는 AOP와 관련이 있어서 지원이 가능하다. 
      • 코딩을 작게 하기 위해서 만들어 놓은 장치이다. 

 Select는 다른 SQL형태를 가지고 있다. 

Dao에서 jdbcTemplate를 insert, update, delete, select의 쿼리 실행기능을 제공하는 클래스로 
스프링 컨에이너의 빈으로 등록하고, 데이터베이스 엑세스 작업을 담당하는 xxxDaoImpl은 의존성 주입을 사용해서 
제공받는다. 
JdbcTemplate 타입의 멤버변수 선언
JdbcTemplate 객체를 전달받는 setter메소드를 정의

JdbcTemplate 의존성 주입 

  • private JdbcTemplate template;
    public void setTemplate(JdbcTemplate template) {
    this.template = template;
    }
  • insert 
    @Override
    public void insert(Employee employee) {
    String sql = "insert into employees "
    + "(employee_id, first_name, last_name, email, phone_number, hire_date, job_id, salary, manager_id, department_id) "
    + "values "
    + "(employees_seq.nextval, ?, ?, ?, ?, sysdate, 'ST_CLERK', 2008, 120, 50)";
    template.update(sql, employee.getFirstName(),employee.getLastName(),employee.getEmail(),employee.getPhoneNumber());
    //무조건 처음에는 sql을 넣는다. 그리고 물음표의 갯수만큼 쭉 작성하면 된다.
    }
  • delete
    @Override
    public void delete(int employeeId) {
    String sql ="delete from employees where employee_id = ?";
    template.update(sql, employeeId);

    }
  • update
    @Override
    public void update(Employee employee) {
    String sql ="update employees"
    + "set "
    + "job_id = ? "
    + "salary = ? "
    + "commission_pct = ? "
    + "manager_id = ? "
    + "department_id = ? "
    + "where employee_id = ?";
    template.update(sql, 
    employee.getJobId(), 
    employee.getSalary(), 
    employee.getCommissionPct() > 0 ? employee.getCommissionPct() : null, 
    employee.getManagerId(),
    employee.getDepartmentId(),
    employee.getId());
    }
  • select(하나의 객체 )
    @Override
    public Employee getEmployeeById(int employeeId) {
    String sql = "select * from employees where employee_id = ?";
    return template.queryForObject(sql, new EmployeeRowMapper(), employeeId);
    }
  • select(다수 )
    @Override
    public List<Employee> getAllEmployees() {
    String sql = "select * from employees";
    return template.query(sql, new EmployeeRowMapper());
    }
  • select를 사용할 때 RowMapping객체를 만들어서 new로 입력할 수 있다. 
    public class EmployeeRowMapper implements RowMapper<Employee> {

    @Override
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
    Employee emp = new Employee();
    emp.setId(rs.getInt("employee_id"));
    emp.setFirstName(rs.getString("first_name"));
    emp.setLastName(rs.getString("last_name"));
    emp.setPhoneNumber(rs.getString("phone_number"));
    emp.setEmail(rs.getString("email"));
    emp.setHireDate(rs.getDate("hire_date"));
    emp.setJobId(rs.getString("job_id"));
    emp.setSalary(rs.getDouble("salary"));
    emp.setCommissionPct(rs.getDouble("commission_pct"));
    emp.setManagerId(rs.getInt("manager_id"));
    emp.setDepartmentId(rs.getInt("department_id"));
    return emp;
    }
    • 익명객체와 람다식을 사용해서 객체를 만들지 않고 사용할 수 있다. 
  • 익명객체 사용방법
    @Override
    public List getAllEmployees() {
    String sql = "select * from employees";
    return template.query(sql, new RowMapper(ResultSet rs, int rowNum) throws SQLException{
    Employee emp = new Employee();
    emp.setId(rs.getInt("employee_id"));
    emp.setFirstName(rs.getString("first_name"));
    emp.setLastName(rs.getString("last_name"));
    emp.setPhoneNumber(rs.getString("phone_number"));
    emp.setEmail(rs.getString("email"));
    emp.setHireDate(rs.getDate("hire_date"));
    emp.setJobId(rs.getString("job_id"));
    emp.setSalary(rs.getDouble("salary"));
    emp.setCommissionPct(rs.getDouble("commission_pct"));
    emp.setManagerId(rs.getInt("manager_id"));
    emp.setDepartmentId(rs.getInt("department_id"));
    return emp;
    })
    }
  • 람다식 사용방법
    public List getAllEmployees() {
    String sql = "select * from employees";
    return template.query(sql, ( rs, rowNum ) -> { 
    Employee emp = new Employee();
    emp.setId(rs.getInt("employee_id"));
    emp.setFirstName(rs.getString("first_name"));
    emp.setLastName(rs.getString("last_name"));
    emp.setPhoneNumber(rs.getString("phone_number"));
    emp.setEmail(rs.getString("email"));
    emp.setHireDate(rs.getDate("hire_date"));
    emp.setJobId(rs.getString("job_id"));
    emp.setSalary(rs.getDouble("salary"));
    emp.setCommissionPct(rs.getDouble("commission_pct"));
    emp.setManagerId(rs.getInt("manager_id"));
    emp.setDepartmentId(rs.getInt("department_id"));
    return emp;
    })
    }

  • 자바스크립트에서는 화살표함수 , 자바에서는 람다식을 사용한다. 
    컴파일 과정에서 타입추론이 가능하여, 반환타입, 메소드이름, 매개변수의 타입을 전부 알아 낼 수있다. 
    매개변수의 이름과 수행문은 수정이 가능하기 때문에 입력을 받을 수 있다. 
  • 수행문이 2개이상이면 반드시 {}괄호를 붙여서 적어줘야한다. 
  • 자바의 경우 익명객체가 행위가 전달되지 않기 때문에 같은 이름으로 메소드를 재정의하는 꼼수를 사용한다. 사용방법을 동일하게 만드는 것이다.
    • 람다식은 추상메소드가 1개여야만 사용할 수 잇다. 
    • 어떤게 들어갈지 정해져있어야 타입추론이 가능하다. 

spring 

WEB-INF에 context-root.xml, context-web.xml을 spring Bean Configuration File로 만들어 준다. 

현재 강의는 연결에만 집중하기 때문에 자세한 부분은 나중에 설명을 할 예정이다. 
spring은 설정파일이 많다. Data-access, Connection, 각 분야마다의 Dao파일등 설정파일이 존재한다. 
web.xml에 작성을 해놓으면 서버가 start시 자동으로 읽어가서 spring Container에 객체를 생성하고, 보관한다. 

  • home.jsp생성, homeController을 만들었다. 

  • @Controller
    public class HomeController {
    @RequestMapping(path = "/home.do")
    public String home() {
    return "home.jsp";
    }
    }
  • @Controller
    • 자동으로 스캔이 가능하게 만들고, Http요청처리하는 어노테이션이다. 
    • 메소드를 여러개 가질 수 있고, 메소드이름, 매개변수, 반환타입에 대한 제약은 없지만 관례적으로는 반환타입은 String을 줘야한다. 
  • @RequestMapping(path = "/home.do")
    • 클래스의 요청경로가 http://localhost:8080/home.do URL요청이 오면 실행되는 요청핸들러 메소드이다. 
    • context-web.xml에서 mvc:jsp prefix로 작성해둬서 자동으로 연결이 가능하다. 
    • 요청핸들러 메소드가 반환하는 문자열은 보통 뷰페이지(jsp페이지의 이름이다.)의 이름이다. 
    •  실제 home.jsp 페이지의 실제 경로는 /WEB-INF/jsp/home.jsp 이지만, home.jsp만 적어도 된다. 
    • home.do라는 응답이 오면 이동할 jsp으로 보낼 예정이다. do는 web.xml에서 작성된 경로이다. 
  • EmployeeController을 만들고, 전체 직원 목록이 표현될 list.jsp를 생성했다. 
    • @Controller
      @RequestMapping("/emp")
      public class EmployeeController {

      @Autowired
      private EmployeeService employeeService;

      @RequestMapping(path = "/list.do")
      public String list(Model model) {
      //전체 직원 목록 조회
      List<Employee> employees = employeeService.getAllEmployees();
      //보여주기 위해서 list.jsp에 Model model매개변수에 담아서 전달해준다.
      // spring이 list에 담아보낼때 ui.model에 담아서 보낸다. 
      //employee/list.jsp에서 표현할 데이터를 Model객체에 저장한다. 
      //model에 담은걸 속성에 넣는다. ui로 표현할 데이터를 객체에 저장한다. 
      model.addAttribute("employees", employees);
      return "/employee/list.jsp";

      }
      //나중에는 계속 늘려갈 예정이다.
      @RequestMapping(path = "/insert.do")
      public String form() {
      return "/employee/list.jsp";

      }

      }
    • @AutoWired
      • 자동으로 의존성 주입을 해주는 어노테이션이다. 
      • 클래스와 메소드의 경로는 합쳐서 경로가 지정된다. 
    • list.jsp
      • EmployeeController의 list()메소드에서 전체 직원리스트를 조회하였다.
        조회된 전체 직원목록을 Model객체에 "employees"속성명으로 저장하였다. 
        JSP 페이지에서는 ${employees }로 조회하면 전체 직원목록을 획득할 수 있다.

        List<Employee> employees = employeeService.getAllEmployees();
        model.addAttribute("employees", employees);

        items="${employees }"로 전체 직원 목록 데이터를 획득한다.
        <c:forEach />는 획득된 데이터에 포함된 직원의 갯수만큼 HTML태그를 반복해서 출력한다. 
         var="emp"는 획득한 전체 직원목록 데이터에서 한 번 반복될 때마다 순서대로 직원정보가(Employee객체) 가 저장된다.
        <c:forEach var="emp"  items="${employees }">
        </c:forEach>
        반복수행을 위해서 c:forEach에 담고 반복해서 표현한다. 
      • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
        <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"  %>
      • 태그를 넣어주고 
      • <c:forEach var="emp"  items="${employees }">
        <tr>
        <td>${emp.id }</td>
        <td>${emp.firstName } ${emp.lastName }</td>
        <td>${emp.phoneNumber }</td>
        <td>${emp.jobId }</td>
        <td><fmt:formatNumber value="${emp.salary }" pattern="##,###"/>달러</td>
        <td><fmt:formatDate value="${emp.hireDate }" pattern="yyyy년 M월 d일" /></td>
        </tr>
        </c:forEach>
      • c와 fmt태그를 이용하여 데이터를 조회할 수 있다.
    • 컴퓨터가 켜지면 원래는 new로 작성 후 컨트롤러를 만들었다.
    • 이제는 web이 켜지면 context-root.xml과 context-web.xml이 web.xml에 적혀 있고,
      Tomcat이 web-xml인 설정정보파일을 읽고, 설정정보대로 로딩이 된다. 
      로딩시점에서 xml을 읽어서 spring Container가 만들어지고, 객체가 생성되어 보관되어 있다. 
    • 이제는 getBean을 사용하지 않고도, 자동으로 읽혀진다. 
  •  

자동으로 추가되는 것을 확인 할 수 있다. 

반응형
Comments