2018-12-04 수업 내용 정리

  • 리턴 값은 프로그램의 유연성을 위해 인터페이스 자료형으로 한다.

  • try-with-resources

    • 자바 버전 7에 추가된 기능으로 try에 자원 객체를 전달하면 finally 블록으로 close 처리를 하지 않아도, try 코드 블록이 끝나면 자동으로 자원을 종료해주는 기능

    • closeable 인터페이스를 상속한 객체만이 try 소괄호 안으로 들어올 수 있다

    • 만약 해당 인터페이스를 상속 받지 못했다면 try 구문에 올 수 없다

    • try 문의 존재 이유가 finally이기 때문에 try-with-resources로 구현했다면 굳이 catch 문을 구현하지 않는다. 이 경우 메서드에서 예외처리가 같이 명시되어 있어야 한다.

    • PreparedStatement로 쿼리문을 날릴 때, ‘? 처리가 try 소괄호 안에서 처리가 불가능하다

      • 이 경우에는 set을 try 구문 안(중괄호 속)에서 입력

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        public Board findByNo(int no) throws Exception {
        DriverManager.registerDriver(new Driver());
        try (
        Connection con = DriverManager.getConnection("jdbc:mariadb://localhost:3306/studydb", "study", "1111");
        PreparedStatement stmt = con.prepareStatement(
        "select bno, cont, cdt, view, mno, lno" + " from board where bno=?");) {
        stmt.setInt(1, no);
        try (ResultSet rs = stmt.executeQuery()) {
        if (rs.next()) {
        Board board = new Board();
        board.setNo(rs.getInt("bno"));
        board.setContents(rs.getString("cont"));
        board.setCreatedDate(rs.getDate("cdt"));
        board.setViewCount(rs.getInt("view"));
        board.setWriterNo(rs.getInt("mno"));
        board.setLessonNo(rs.getInt("lno"));
        return board;
        } else {
        return null;
        }
        }
        }
        }
    • 만약 try 소괄호 안, 마지막 구문은 세미콜론 생략이 가능하다

  • 만약 try 문을 구현한 메서드에서 예외를 던지게 설정되어 있다면 (throws Exception) catch 블록을 따로 구현할 필요가 없다.

MyBatis 적용

  1. gradle에 의존 설정을 해준 뒤 gradle eclipse 실행해 설정 파일 갱신

  2. src/main/resources/자바경로/comfmybatis-config.xml를 둔다.
    resources가 없으면 생성

    mybatis-config.xml에 자바 소스 폴더로 등록 후 gradle eclipse 재실행

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    <environments default="development">
    <environment id="development">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
    </dataSource>
    </environment>
    </environments>
    <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
    </configuration>
    • jdbc.properties 파일 작성해서 해당 프로퍼티가 안으로 들어갈 수 있도록 설정

      1
      2
      3
      4
      jdbc.driver=org.mariadb.jdbc.Driver
      jdbc.url=jdbc:mariadb://localhost:3306/studydb
      jdbc.username=study
      jdbc.password=1111
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      <-- xml은 이렇게 수정된다 -->
      <configuration>
      <-- properties의 경로 설정해준다-->
      <properties resource="com/eomcs/lms/conf/jdbc.properties"></properties>
      <-- db 연결 정보를 설정, default는 아래와 같다
      db 연결 정보를 여러 개 설정할 수 있다 -->
      <environments default="development">
      <environment id="development">
      <-- 트랜젝션 관리는 jdbc를 쓰겠다 -->
      <transactionManager type="JDBC"/>
      <-- db 커넥션 풀 -->
      <dataSource type="POOLED">
      <property name="driver" value="${jdbc.driver}"/>
      <property name="url" value="${jdbc.url}"/>
      <property name="username" value="${jdbc.username}"/>
      <property name="password" value="${jdbc.password}"/>
      <-- value와 프로퍼티 파일의 이름이 같아야 한다 -->
      </dataSource>
      </environment>
      </environments>
      <-- sql을 보관할 xml 파일 경로 설정 -->
      <mappers>
      <mapper resource="com/eomcs/lms/mapper/BoardMapper.xml"/>
      </mappers>
      </configuration>
  3. src/main/resources/자바경로/mapper/BoardMapper.xml에 파일 작성(sql문들)

  4. 실행 클래스에서 mybatis의 SqlSessionFactory 객체 준비

    1
    2
    3
    4
    5
    6
    7
    8
    String resource = "com/eomcs/lmes/conf/mybatis-config.xml";
    <!-- 팩토리 패턴 -->
    InputStream inputStream = Resources.getResourceAsStream(resource);
    <!-- 빌더 패턴 -->
    SqlSessionFactory sqlSessionFactory =
    new SqlSessionFactoryBuilder().build(inputStream);

    BoardDao boardDao = new MariaDBBoardDao(sqlSessionFactory);
    • inputStream : 설계도의 역할

    • SqlSessionFactoryBuilder는 전문적으로 SqlSessionFactory를 만듦

    • 객체 생성 과정이 복잡할 때는 대부분 *Builder 클래스를 활용해 생성 - 빌더 패턴

    • 디자인 패턴 중 하나인 빌더 패턴, 팩토리 패턴
    • 팩토리 패턴은 간단한 조립의 기능 수행, 빌더는 보다 큰 기능을 수행한다

    dao가 사용할 수 있도록 생성자에 해당 객체 주입

  5. dao 단에서 세션 생성

    1
    2
    3
    4
    5
    6
    public List<Board> findAll() throws Exception {

    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
    return sqlSession.selectList("DoardDao.findAll");
    }
    }

    실습 중 에러 기록

    • mapper의 namespace 대소문자 오타

    • 인터페이스 상속 받은 메서드 오타

    • 메서드 실행 시 필요한 파라미터 값 넘기지 않음
    • gradle eclipse 실행 후 새로고침 에러
  6. mybatis의 경우 오토커밋이 안되기 때문에 커밋 설정을 따로 해줘야 한다.
    트랜젝션 관리 때문에 오토커밋을 자동으로 실행하는 옵션을 설정할 수 없다.

    1
    2
    3
    4
    5
    6
    7
    public int insert(Board board) throws Exception {
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
    int count = sqlSession.insert("BoardDao.insert", board);
    sqlSession.commit();
    return count;
    }
    }
  7. 별명 지정 가능

    1
    2
    3
    4
    5
    <properties resource="com/eomcs/lms/conf/jdbc.properties"></properties>
    <!-- 프로퍼티 아래로 들어와야 한다 -->
    <typeAliases>
    <package name="com.eomcs.lms.domain"/>
    </typeAliases>
  8. db 내 컬럼과 domain의 이름이 다를 때
    매퍼의 상위에 아래 코드를 기술해 지정해주고,

    1
    2
    3
    4
    5
    6
    <resultMap type="board" id="boardMap">
    <!-- board 칼럼을 프로퍼티 이름과 연결 -->
    <id column="bno" property="no"/>
    <!-- pk는 result가 아니라 id로 해줘야 한다 -->
    <result column="cont" property="contents"/>
    </resultMap>

    sql 태그에서 파라미터맵이나, resultMap으로 위를 가리켜 실행

    1
    2
    3
    <select id="findAll" resultMap="boardMap">
    select bno, cont, cdt, view from board
    </select>