MyBatis (persistance framework)

woom·2023년 1월 27일
0

Framework

목록 보기
1/20
post-thumbnail

🌼 MyBatis

  • SQL을 이용한 처리결과를 원시타입, 인터페이스 자바 객체로 매핑하기 위해 XML과 어노테이션 사용

  • 마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다.

  • 마이바티스는 JDBC로 처리하는 상당부분의 코드와 파라미터 설정및 결과 매핑을 대신해준다.

  • 마이바티스는 데이터베이스 레코드에 원시타입과 Map 인터페이스 그리고 자바 POJO 를 설정해서 매핑하기 위해 XML과 애노테이션을 사용할 수 있다.


📕 MyBatis 빌드 처리

  1. https://blog.mybatis.org/ : mybatis 블로그 사이트 접속 → 상단 메뉴바에서 Products 선택

  1. MyBatis 3 Project download (docs : Mybatis Document로 설명서 )

  1. mybatis-3.5.11.zip download

  1. eclipse에 mybatis-3.5.11.zip 폴더 안의 jar파일 빌드처리 (4-1 참고)
  • lib폴더 안의 로그 구현체 jar파일도 함께 빌드처리

4-1. 로깅 : 로그 팩토리에 로깅정보(기록물: 동작이 잘 구현되는지 확인할수있는 정보)를 생성하여 로그 구현체에 전달

  • 로그 구현체 : SLF4J, Apache Commons Logging, Apache Log4j, JDK Logging API

4-2. 로깅정보를 전달 받기 위한 환경설정

  • 프로젝트 → Java Resources → src/main/java 폴더 안에 xml파일 생성 (log4j2.xml)

    • java class 가 읽어들이는 파일 (가져다 쓸 수 있음)
    • properties → java Build Path → source 에서 빌드처리 가능
  • Appender (Console) : 로깅정보를 기록하는 장치 (SYSTEM_OUT인 로그 기록자를 이용해 구현)

  • PatternLayout : 로깅정보를 기록하는 방식

    • pattern 속성으로 어떤레벨로 제공되는 로깅인지, 언제 발생하고(thread), 어떤 메시지를 제공하는지 작성
    • pattern="%5level [%t] - %msg%n"
  • Root level : 어느 수준 이상부터 로깅을 전달할지에 대한 등급(6단계)

    • level="error" : error 메시지만 출력
    • level="info" : error 메시지와 진행 정보 출력


🐣 log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">

	<Appenders>
		<Console name="stdout" target="SYSTEM_OUT">
			<PatternLayout pattern="%5level [%t] - %msg%n"/>
		</Console>
	</Appenders>

	<Root level="info" >
		<AppenderRef ref="stdout"/>
	</Root>

</Configuration>




⭐ MyBatis 환경 설정

  • 프로젝트 → Java Resources → src/main/java 폴더 안에 xml파일 생성

    • properties → java Build Path → source (java class 가 읽어들이는 파일로 가져다 쓸 수 있음)
  • typeAliases : 1개 이상의 typeAlias 엘리먼트를 등록하기 위한 상위 엘리먼트

    • typeAlias : XML 기반의 매퍼 파일에서 Java 자료형을 간단하게 표현하기 위한 별칭(AliasName)을 설정하기 위한 엘리먼트
    • mybatis 프레임워크는 내부적으로 설정된 Java 자료형에 대한 별칭 제공
    • type 속성 : Java 자료형을 속성값으로 설정
    • alias 속성 : Java 자료형 대신 사용할 별칭을 속성값으로 설정
    • <typeAlias type="xyz.itwill.dto.MyMember" alias="MyMember"/>
    • package : 특정 패키지에 작성된 모든 클래스에 별칭을 자동으로 등록하는 엘리먼트
    • 패키지의 작성된 모든 클래스는 패키지를 제외한 클래스 이름을 별칭으로 자동 등록
    • <package name="xyz.itwill.dto"/>
  • callSettersOnNulls : 가져온 값이 null일 때 setter나 맵의 put 메소드를 호출할지를 명시. Map.keySet() 이나 null값을 초기화할때 유용하다. int, boolean 등과 같은 원시타입은 null을 설정할 수 없다는 점은 알아두면 좋다.

  • environments : 1개 이상의 environment 엘리먼트을 등록하기 위한 상위 엘리먼트

    • default 속성 : environment 엘리먼트의 식별자(id 속성값)를 속성값으로 설정
    • mybatis 프레임워크가 기본적으로 사용하기 위한 DBMS 서버를 표현하기 위한 속성
  • environment : DBMS 서버 접속에 필요한 정보를 설정하기 위한 엘리먼트

    • id 속성 : environment 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정
  • transactionManager : 트렌젝션 관리자(커밋 또는 롤백 처리)를 설정하기 위한 엘리먼트

    • type 속성 : [JDBC] 또는 [MANAGED] 중 하나를 속성값으로 설정
    • JDBC 속성값 : JDBC 기능(Connection 객체의 메소드 호출)을 사용하여 직접 트렌젝션 관리
    • MANAGED 속성값 : 트렌젝션을 관리하는 프로그램을 사용하여 트렌젝션 관리
  • dataSource : Connection 객체 생성에 필요한 정보를 설정하기 위한 엘리먼트

    • type 속성 : [UNPOOLED], [POOLED], [JNDI] 중 하나를 속성값으로 설정
    • type 속성값에 따라 하위 엘리먼트 설정을 다르게 설정
    • UNPOOLED 속성값 : Connection 객체를 미리 생성하지 않고 실행시 생성하여 제공
    • POOLED 속성값 : 다수의 Connection 객체를 미리 생성하여 실행시 제공 (DBCP)
    • JNDI 속성값 : WAS에 등록된 자원을 이용하여 실행시 Connection 객체를 제공
  • property : Connection 객체를 생성하기 위한 값을 제공하는 엘리먼트

    • name 속성 : Connection 객체 생성에 필요한 값이 저장될 이름을 속성값으로 설정
    • value 속성 : Connection 객체 생성에 필요한 값을 속성값으로 설정
  • environment를 여러개 만들어주는 이유 : 접속되는 서버를 선택할 수 있도록 하기 위해서

    • local server (개인이 작성 후 실행)
    • test server(team)
    • real server 연동되는 실제 서버 (실제 서버에서 잘 동작되는 지 확인)
  • mappers : 1개 이상의 mapper 엘리먼트을 등록하기 위한 상위 엘리먼트

    • 매퍼(Mapper) : SQL 명령에 필요한 값을 전달받아 SQL 명령을 등록하고 실행결과를 Java 객체(원시형)로 매핑하기 위한 정보를 제공
    • mybatis 프레임워크에는 XML 기반의 매퍼 파일과 Interface 기반의 매퍼 파일을 이용하여 매퍼 설정
    • ibatis 프레임워크에는 XML 기반의 매퍼 파일로만 매퍼 설정 가능
    • resource 속성 : XML 기반의 매퍼 파일의 경로를 속성값으로 설정
    • XML 기반의 매퍼 파일에 경로는 파일 시스템 경로를 기반으로 작성
  • package : 특정 패키지에 작성된 모든 Interface 기반의 매퍼 파일을 자동으로 매퍼로 등록하기 위한 엘리먼트

    • name 속성 : Interface 기반의 매퍼 파일이 작성된 패키지를 속성값으로 설정
    • <package name="xyz.itwill.mapper"/>
  • mapUnderscoreToCamelCase : 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함


📌 매퍼 설정 방법 3가지

  • 매퍼(Mapper) : SQL 명령에 필요한 값을 전달받아 SQL 명령을 등록하고 실행결과를 Java 객체(원시형)로 매핑하기 위한 정보를 제공

  • mybatis 프레임워크에는 1. XML 기반의 매퍼 파일과 2. Interface 기반의 매퍼 파일을 이용하여 매퍼 설정

    • ibatis 프레임워크에는 XML 기반의 매퍼 파일로만 매퍼 설정 가능
  1. XML 기반의 매퍼 파일

    • resource 속성 : XML 기반의 매퍼 파일에 경로를 속성값으로 설정
    • XML 기반의 매퍼 파일 경로는 파일 시스템 경로를 기반으로 작성
    • <mapper resource="xyz/itwill/mapper/MyMemberXMLMapper.xml"/>
    • XML 기반의 매퍼 파일의 장점 : 수동 매핑 설정과 동적 SQL 설정에 대한 기능 구현이 편리
    • XML 기반의 매퍼 파일의 단점 : SqlSession 객체로 SQL 명령을 제공받아 사용하기 불편
  2. Interface 기반의 매퍼 파일

    • class 속성 : Interface 기반의 매퍼 파일의 경로를 속성값으로 설정
    • Interface 기반의 매퍼 파일 경로는 Java 자료형(인터페이스)을 기반으로 작성
    • Interface 기반의 매퍼 파일의 장점 : SqlSession 객체로 SQL 명령을 제공받아 사용하기 편리
    • Interface 기반의 매퍼 파일의 단점 : 수동 매핑 설정과 동적 SQL 설정에 대한 기능 구현이 불편
    • <mapper class="xyz.itwill.mapper.MyMemberInterfaceMapper"/>
  1. XML 기반의 매퍼 파일과 Interface 기반의 매퍼 파일을 하나의 매퍼로 동작되도록 설정 가능
    • 매퍼 바인딩(Mapper Binding) : SQL 명령은 XML 기반의 매퍼 파일에 등록하고 DAO 클래스의 메소드는 Interface 기반의 매퍼 파일의 추상메소드를 호출하여 작성
    • mapper 엘리먼트에는 XML 기반의 매퍼 파일만 등록하여 사용

💡 환경설정 시 참고

  • environment를 여러개 만들어주는 이유 : 접속되는 서버를 선택할 수 있도록 하기 위해서
  1. local server (개인이 작성 후 실행)
  2. test server (team)
  3. real server 연동되는 실제 서버 (실제 서버에서 잘 동작되는지 확인)
  • transactionManager : sql명령에 대한 실행을 관리
    • 잘못된 명령에 대한 취소 가능
    • 일관성있는 데이터를 제공
    • Managed속성값 : 일관성있는 관리가 가능하지만 복잡

🐣 예제


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis 환경설정 파일 : SqlSessionFactory 객체를 생성하기 위해 필요한 정보를 제공하는 파일 -->
<configuration>
	<!-- properties : 1개 이상의 property 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
	<!-- resource 속성 : Properties 파일의 경로를 속성값으로 설정 -->
	<!-- => property 엘리먼트 대신 Properties 파일에서 제공되는 값을 mybatis 환경설정 파일에서 사용 가능 -->
	<properties resource="dbms.properties">
		<!-- property : mybatis 환경설정 파일에 필요한 값을 제공하는 엘리먼트 -->
		<!-- => 다른 엘리먼트에서 ${이름} 형식으로 표현하여 property 엘리먼트의 값을 제공받아 사용 -->
		<!-- => 다수의 엘리먼트에서 공통적으로 사용되는 값을 제공하기 위해 설정 - 유지보수의 효율성 증가 -->
		<!-- name 속성 : property 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정 -->
		<!-- value 속성 : property 엘리먼트를 제공하기 위한 값을 속성값으로 설정 -->
		<property name="oracleDriver" value="oracle.jdbc.driver.OracleDriver"/>
	</properties>

	<!-- settings : 1개 이상의 setting 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
	<settings>
		<!-- setting : mybatis 프레임워크가 실행될 때 필요한 값을 제공하기 위한 엘리먼트 -->
		<!-- => setting 엘리먼트를 설정하지 않아도 실행에 필요한 값은 기본값으로 제공받아 사용 -->
		<!-- => 기본값이 아닌 값을 사용할 경우에만 setting 엘리먼트를 설정하여 실행에 필요한 값을 제공받아 사용 -->
      	<!-- mapUnderscoreToCamelCase : 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<setting name="jdbcTypeForNull" value="NULL"/>
		<setting name="callSettersOnNulls" value="true"/>
	</settings>

	<!-- typeAliases : 1개 이상의 typeAlias 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
	<typeAliases>
		<!-- typeAlias : XML 기반의 매퍼 파일에서 Java 자료형을 간단하게 표현하기 위한 
		별칭(AliasName)을 설정하기 위한 엘리먼트 -->
		<!-- => mybatis 프레임워크는 내부적으로 설정된 Java 자료형에 대한 별칭 제공 -->
		<!-- type 속성 : Java 자료형을 속성값으로 설정 -->
		<!-- alias 속성 : Java 자료형 대신 사용할 별칭을 속성값으로 설정 -->
		<!-- <typeAlias type="xyz.itwill.dto.Student" alias="Student"/> -->
		<!-- <typeAlias type="xyz.itwill.dto.MyMember" alias="MyMember"/> -->
		
		<!-- package : 특정 패키지에 작성된 모든 클래스에 별칭을 자동으로 등록하는 엘리먼트 -->
		<!-- => 패키지의 작성된 모든 클래스는 패키지를 제외한 클래스 이름을 별칭으로 자동 등록 -->
		<package name="xyz.itwill.dto"/>
	</typeAliases>

	<!-- environments : 1개 이상의 environment 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
	<!-- default 속성 : environment 엘리먼트의 식별자(id 속성값)를 속성값으로 설정 -->
	<!-- => mybatis 프레임워크가 기본적으로 사용하기 위한 DBMS 서버를 표현하기 위한 속성 -->
	<environments default="development">
		<!-- environment : DBMS 서버 접속에 필요한 정보를 설정하기 위한 엘리먼트 -->
		<!-- id 속성 : environment 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정 -->
		<environment id="development">
			<!-- transactionManager : 트렌젝션 관리자(커밋 또는 롤백 처리)를 설정하기 위한 엘리먼트 -->
			<!-- type 속성 : [JDBC] 또는 [MANAGED] 중 하나를 속성값으로 설정 -->
			<!-- => JDBC 속성값 : JDBC 기능(Connection 객체의 메소드 호출)을 사용하여 직접 트렌젝션 관리 -->
			<!-- => MANAGED 속성값 : 트렌젝션을 관리하는 프로그램을 사용하여 트렌젝션 관리 -->
			<transactionManager type="JDBC"/>
			<!-- dataSource : Connection 객체 생성에 필요한 정보를 설정하기 위한 엘리먼트 -->
			<!-- type 속성 : [UNPOOLED], [POOLED], [JNDI] 중 하나를 속성값으로 설정 -->
			<!-- => type 속성값에 따라 하위 엘리먼트 설정을 다르게 설정 -->
			<!-- => UNPOOLED 속성값 : Connection 객체를 미리 생성하지 않고 실행시 생성하여 제공 -->
			<!-- => POOLED 속성값 : 다수의 Connection 객체를 미리 생성하여 실행시 제공 - DBCP -->
			<!-- => JNDI 속성값 : WAS에 등록된 자원을 이용하여 실행시 Connection 객체를 제공 -->
			<dataSource type="POOLED">
				<!-- property : Connection 객체를 생성하기 위한 값을 제공하는 엘리먼트 -->
				<!-- name 속성 : Connection 객체 생성에 필요한 값이 저장될 이름을 속성값으로 설정 -->
				<!-- value 속성 : Connection 객체 생성에 필요한 값을 속성값으로 설정 -->
				<!-- <property name="driver" value="oracle.jdbc.driver.OracleDriver"/> -->
				<property name="driver" value="${oracleDriver}"/>
				<!-- <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/> -->
				<property name="url" value="${local}"/>
				<property name="username" value="scott"/>
				<property name="password" value="tiger"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- mappers : 1개 이상의 mapper 엘리먼트를 등록하기 위한 상위 엘리먼트 -->
	<mappers>
		<!-- mapper : 매퍼(Mapper)을 등록하기 위한 엘리먼트 -->
		<!-- 매퍼(Mapper) : SQL 명령에 필요한 값을 전달받아 SQL 명령을 등록하고 실행결과를
		Java 객체(원시형)로 매핑하기 위한 정보를 제공 -->
		<!-- mybatis 프레임워크에는 XML 기반의 매퍼 파일과 Interface 기반의 매퍼 파일을 이용하여 매퍼 설정 -->
		<!-- => ibatis 프레임워크에는 XML 기반의 매퍼 파일로만 매퍼 설정 가능 -->
		<!-- resource 속성 : XML 기반의 매퍼 파일에 경로를 속성값으로 설정 -->
		<!-- => XML 기반의 매퍼 파일 경로는 파일 시스템 경로를 기반으로 작성 -->
		<!-- XML 기반의 매퍼 파일의 장점 : 수동 매핑 설정과 동적 SQL 설정에 대한 기능 구현이 편리 -->
		<!-- XML 기반의 매퍼 파일의 단점 : SqlSession 객체로 SQL 명령을 제공받아 사용하기 불편 -->
		<mapper resource="xyz/itwill/mapper/StudentMapper.xml"/>
		<mapper resource="xyz/itwill/mapper/MyMemberXMLMapper.xml"/>

		<!-- class 속성 : Interface 기반의 매퍼 파일의 경로를 속성값으로 설정 -->
		<!-- => Interface 기반의 매퍼 파일 경로는 Java 자료형(인터페이스)을 기반으로 작성 -->
		<!-- Interface 기반의 매퍼 파일의 장점 : SqlSession 객체로 SQL 명령을 제공받아 사용하기 편리 -->
		<!-- Interface 기반의 매퍼 파일의 단점 : 수동 매핑 설정과 동적 SQL 설정에 대한 기능 구현이 불편 -->
		<!-- <mapper class="xyz.itwill.mapper.MyMemberInterfaceMapper"/> -->
		
		<!-- XML 기반의 매퍼 파일과 Interface 기반의 매퍼 파일을 하나의 매퍼로 동작되도록 설정 가능 -->
		<!-- 매퍼 바인딩(Mapper Binding) : SQL 명령은 XML 기반의 매퍼 파일에 등록하고 DAO
		클래스의 메소드는 Interface 기반의 매퍼 파일의 추상메소드를 호출하여 작성 -->
		<!-- mapper 엘리먼트에는 XML 기반의 매퍼 파일만 등록하여 사용 -->
		<!-- <mapper resource="xyz/itwill/mapper/MyMemberMapper.xml"/> -->
		
		<!-- package : 특정 패키지에 작성된 모든 Interface 기반의 매퍼 파일을 자동으로 
		매퍼로 등록하기 위한 엘리먼트 -->
		<!-- name 속성 : Interface 기반의 매퍼 파일이 작성된 패키지를 속성값으로 설정 -->
		<package name="xyz.itwill.mapper"/>
	</mappers>
</configuration>





🐣 MyBatis 환경 설정 요약

  • mybatis 환경설정 파일 : SqlSessionFactory 객체를 생성하기 위해 필요한 정보를 제공하는 파일
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- resource 속성 : Properties 파일의 경로를 속성값으로 설정 (Properties 파일에서 제공되는 값) -->
	<properties resource="dbms.properties">
		<!-- property : mybatis 환경설정 파일에 필요한 값을 제공, 다른 엘리먼트에서 ${이름} 형식으로 표현 -->
		<property name="oracleDriver" value="oracle.jdbc.driver.OracleDriver"/>
	</properties>

	<settings>
		<!-- setting : mybatis 프레임워크가 실행될 때 필요한 값을 제공(설정하지 않을 경우 기본값 실행) -->
		<setting name="jdbcTypeForNull" value="NULL"/>
		<setting name="callSettersOnNulls" value="true"/>
	</settings>

	<typeAliases>
		<!-- typeAlias : XML 기반의 매퍼 파일에서 Java 자료형을 간단하게 표현하기 위한 별칭 설정 -->
		<!-- <typeAlias type="xyz.itwill.dto.MyMember" alias="MyMember"/> -->
		
		<!-- package : 특정 패키지에 작성된 모든 클래스에 클래스 이름으로 별칭을 자동으로 등록 -->
		<package name="xyz.itwill.dto"/>
	</typeAliases>

	<environments default="development">
		<!-- environment : DBMS 서버 접속에 필요한 정보를 설정하기 위한 엘리먼트 -->
		<environment id="development">
			<!-- transactionManager : 트렌젝션 관리자(커밋 또는 롤백 처리)를 설정하기 위한 엘리먼트 -->
			<!-- => JDBC 속성값 : JDBC 기능(Connection 객체의 메소드 호출)을 사용하여 직접 트렌젝션 관리 -->
			<!-- => MANAGED 속성값 : 트렌젝션을 관리하는 프로그램을 사용하여 트렌젝션 관리 -->
			<transactionManager type="JDBC"/>
			<!-- dataSource : Connection 객체 생성에 필요한 정보를 설정하기 위한 엘리먼트 -->
			<!-- => POOLED 속성값 : 다수의 Connection 객체를 미리 생성하여 실행시 제공 (DBCP) -->
			<dataSource type="POOLED">
				<!-- property : Connection 객체를 생성하기 위한 값을 제공하는 엘리먼트 -->
				<property name="driver" value="${oracleDriver}"/>
				<property name="url" value="${local}"/>
				<property name="username" value="scott"/>
				<property name="password" value="tiger"/>
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<!-- Mapper : SQL 명령을 전달받아 등록하고 실행결과를 Java 객체(원시형)로 매핑하기 위한 정보를 제공 -->
		<!-- resource 속성 : XML 기반의 매퍼 파일에 경로를 속성값으로 설정 -->
		<mapper resource="xyz/itwill/mapper/StudentMapper.xml"/>
		<mapper resource="xyz/itwill/mapper/MyMemberXMLMapper.xml"/>

		<!-- class 속성 : Interface 기반의 매퍼 파일의 경로를 속성값으로 설정 -->
		<!-- <mapper class="xyz.itwill.mapper.MyMemberInterfaceMapper"/> -->
		
		<!-- 매퍼 바인딩(Mapper Binding) : SQL 명령은 XML 기반의 매퍼 파일에 등록하고 DAO
		클래스의 메소드는 Interface 기반의 매퍼 파일의 추상메소드를 호출하여 작성 -->
		<!-- mapper 엘리먼트에는 XML 기반의 매퍼 파일만 등록하여 사용 -->
		<!-- <mapper resource="xyz/itwill/mapper/MyMemberMapper.xml"/> -->
		
		<!-- package : 특정 패키지에 작성된 모든 Interface 기반의 매퍼 파일을 자동으로 등록 -->
		<package name="xyz.itwill.mapper"/>
	</mappers>
</configuration>


📌 properties

  • MyBatis 환경 설정에서 Properties 파일의 경로를 속성값으로 설정 (dbms.properties)
  • <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
#name = value
local = jdbc:oracle:thin:@localhost:1521:xe




🌼 XML 기반의 매퍼 파일

  • Mapper 파일 : SQL 명령을 등록하기 위한 파일

  • mybatis 환경설정 파일에서 mapper 엘리먼트를 사용하여 매퍼 파일로 등록해야만 사용 가능


📙 XML Mapper 파일 (select)

  • mapper : SQL 명령을 등록하기 위한 상위 엘리먼트

    • namespace 속성 : 매퍼를 구분하기 위한 식별자를 속성값으로 설정
    • SqlSession 객체가 원하는 매퍼의 SQL 명령을 제공받아 사용하기 위해 설정
    • mybatis 프레임워크에서는 namespace 속성값을 Java 자료형의 형식으로 표현하여 작성하는 것을 권장
    • ibatis 프레임워크에서는 namespace 속성 생략 가능
  • select : SELECT 명령을 등록하기 위한 엘리먼트

    • id 속성 : 매퍼에 등록된 SQL 명령을 구분하기 위한 식별자를 속성값으로 설정
    • resultType 속성 : SQL 명령의 실행 결과를 매핑하여 제공하기 위한 Java 자료형을 속성값으로 설정
    • SELECT 명령으로 실행된 하나의 검색행에 대한 Java 자료형을 설정하여 객체로 매핑되도록 처리
  • resultType 속성값으로 Java 자료형 대신 mybatis 환경설정 파일의 typeAlias 엘리먼트로 설정된 별칭 사용 가능


🐣 예제


<?xml version="1.0" encoding="UTF-8"?>
<!-- Mapper 파일 : SQL 명령을 등록하기 위한 파일 -->
<!-- => mybatis 환경설정 파일에서 mapper 엘리먼트를 사용하여 매퍼 파일로 등록해야만 사용 가능 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper : SQL 명령을 등록하기 위한 상위 엘리먼트 -->
<!-- namespace 속성 : 매퍼를 구분하기 위한 식별자를 속성값으로 설정 -->
<!-- => SqlSession 객체가 원하는 매퍼의 SQL 명령을 제공받아 사용하기 위해 설정 -->
<!-- => mybatis 프레임워크에서는 namespace 속성값을 Java 자료형의 형식으로 표현하여 작성하는 것을 권장 -->
<!-- => ibatis  프레임워크에서는 namespace 속성 생략 가능 -->
<mapper namespace="xyz.itwill.mapper.StudentMapper">
	<!-- select : SELECT 명령을 등록하기 위한 엘리먼트 -->
	<!-- id 속성 : 매퍼에 등록된 SQL 명령을 구분하기 위한 식별자를 속성값으로 설정 -->
	<!-- resultType 속성 : SQL 명령의 실행 결과를 객체로 매핑하여 제공하기 위한 Java 자료형을 속성값으로 설정 -->
	<!-- => SELECT 명령으로 실행된 하나의 검색행에 대한 Java 자료형을 설정하여 객체로 매핑되도록 처리 -->
	<!-- 
	<select id="selectStudentList" resultType="xyz.itwill.dto.Student">
		select * from student order by no
	</select>
	 -->
	 
	<!-- resultType 속성값으로 Java 자료형 대신 mybatis 환경설정 파일의 typeAlias 엘리먼트로
	설정된 별칭 사용 가능 --> 
	<select id="selectStudentList" resultType="Student">
		select * from student order by no
	</select>	 
</mapper>





📙 XML DAO Class

  • SqlSessionFactory 객체를 생성하여 반환하는 메소드

    • SqlSessionFactory 객체를 생성하기 위해서는 반드시 mybatis 환경설정 파일(mybatis-config.xml)이 필요
    • SqlSessionFactory 객체 : SqlSession 객체를 생성하여 제공하기 위한 객체
  • mybatis 환경설정 파일이 특정 패키지에 작성된 경우 파일 시스템 경로로 표현

    • String resource="xyz/itwill/config/mybatis-config.xml";(package안에 작성된 경우)
    • String resource="mybatis-config.xml";
  • mybatis 환경설정 파일을 읽기 위한 입력스트림을 반환받아 저장

    • Resources.getResourceAsStream(String resource) : 서버에 저장된 mybatis 환경설정 파일의 경로를 제공받아 파일 입력스트림을 생성하여 반환하는 메소드
  • SqlSessionFactoryBuilder.build(InputStream inputStream) : mybatis 환경설정 파일을 입력스트림을 이용하여 제공받아 SqlSessionFactory 객체를 생성하여 반환하는 메소드

  • STUDENT 테이블에 저장된 모든 학생정보를 검색하여 반환하는 메소드

    • SqlSession 객체의 메소드를 호출하여 메소드 작성
    • SqlSessionFactory.openSession() : SqlSession 객체를 생성하여 반환하는 메소드
    • SqlSession 객체 : 매퍼에 등록된 정보를 이용하여 SQL 명령을 전달하여 실행하고 실행결과를 Java 객체로 반환하는 기능을 제공하는 객체
  • SqlSession.selectList(String elementId) : 매퍼에 등록된 SELECT 명령을 제공받아 전달하여 실행하고 처리결과를 List 객체로 생성하여 반환하는 메소드

    • elementId 매개변수는 매퍼의 식별자(namespace 속성값)와 select 엘리먼트의 식별자(id 속성값)를 이용하여 매퍼에 등록된 SQL 명령을 구분하여 사용
  • SqlSession.close() : SqlSession 객체가 사용한 JDBC 관련 객체를 제거하는 메소드


🐣 예제

package xyz.itwill.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import xyz.itwill.dto.Student;

public class StudentDAO {
	private static StudentDAO _dao;
	
	private StudentDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new StudentDAO();
	}
	
	public static StudentDAO getDAO() {
		return _dao;
	}

	//SqlSessionFactory 객체를 생성하여 반환하는 메소드
	// => SqlSessionFactory 객체를 생성하기 위해서는 반드시 mybatis 환경설정 파일(mybatis-config.xml)이 필요
	//SqlSessionFactory 객체 : SqlSession 객체를 생성하여 제공하기 위한 객체
	private SqlSessionFactory getSqlSessionFactory() {
		//mybatis 환경설정 파일이 특정 패키지에 작성된 경우 파일 시스템 경로로 표현
		//String resource="xyz/itwill/config/mybatis-config.xml"; 패키지안에 작성된 경우
		String resource="mybatis-config.xml";//패키지 없이 작성된 경우
		
		InputStream inputStream=null;
		try {
			//mybatis 환경설정 파일을 읽기 위한 입력스트림을 반환받아 저장
			//Resources.getResourceAsStream(String resource) : 서버에 저장된 mybatis 환경설정 
			//파일의 경로를 제공받아 파일 입력스트림을 생성하여 반환하는 메소드			
			inputStream=Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		
		//SqlSessionFactoryBuilder.build(InputStream inputStream) : mybatis 환경설정 파일을
		//입력스트림을 이용하여 제공받아 SqlSessionFactory 객체를 생성하여 반환하는 메소드
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 반환하는 메소드
	// => SqlSession 객체의 메소드를 호출하여 메소드 작성
	public List<Student> selectStudentList() {
		//SqlSessionFactory.openSession() :  SqlSession 객체를 생성하여 반환하는 메소드
		//SqlSession 객체 : 매퍼에 등록된 정보를 이용하여 SQL 명령을 전달하여 실행하고
		//실행결과를 Java 객체로 반환하는 기능을 제공하는 객체
		SqlSession sqlSession=getSqlSessionFactory().openSession();
		try {
			//SqlSession.selectList(String elementId) : 매퍼에 등록된 SELECT 명령을 제공받아 
			//전달하여 실행하고 처리결과를 List 객체로 생성하여 반환하는 메소드
			// => elementId 매개변수는 매퍼의 식별자(namespace 속성값)와 select 엘리먼트의 
			//식별자(id 속성값)를 이용하여 매퍼에 등록된 SQL 명령을 구분하여 사용
			return sqlSession.selectList("xyz.itwill.mapper.StudentMapper.selectStudentList");
		} finally {
			//SqlSession.close() : SqlSession 객체가 사용한 JDBC 관련 객체를 제거하는 메소드
			sqlSession.close();
		}
	}
}





🐣 DAO 메소드 출력

  • 로깅정보확인

<%@page import="xyz.itwill.dao.StudentDAO"%>
<%@page import="xyz.itwill.dto.Student"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<Student> studentList=StudentDAO.getDAO().selectStudentList();
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
<style type="text/css">
table {
	border: 1px solid black;
	border-collapse: collapse;
}
td {
	border: 1px solid black;
	text-align: center;
	padding: 10px;	
}
</style>
</head>
<body>
	<h1>학생목록</h1>
	<hr>
	<table>
		<tr>
			<td>학번</td>
			<td>이름</td>
			<td>전화번호</td>
			<td>주소</td>
			<td>생년월일</td>
		</tr>
		<% for(Student student:studentList) { %>
		<tr>
			<td><%=student.getNo() %></td>
			<td><%=student.getName() %></td>
			<td><%=student.getPhone() %></td>
			<td><%=student.getAddress() %></td>
			<td><%=student.getBirthday().substring(0, 10) %></td>
		</tr>
		<% } %>
	</table>
</body>
</html>





📌 DTO class (mymember)

package xyz.itwill.dto;

public class MyMember {
	private String id;
	private String name;
	private String phone;
	private String email;
	
	public MyMember() {
		// TODO Auto-generated constructor stub
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	
	
}






📙 XML Mapper 파일 (DML)

  • DML 명령 (INSERT, UPDATE, DELETE) 관련 엘리먼트는 등록된 SQL 명령 실행 후 조작행의 갯수를 무조건 정수값(int)으로 매핑하여 제공하므로 resultType 속성 생략

  • parameterType 속성 : SQL 명령에 필요한 값을 제공받기 위한 객체(값)의 Java 자료형을 속성값으로 설정

    • Java 자료형 대신 typeAlias 엘리먼트의 별칭 사용 가능
    • SQL 명령에 필요한 값이 없는 경우 parameterType 속성 생략
    • parameterType 속성으로 전달받은 값은 SQL 명령에서 #{변수명|필드명|맵키} 형식으로 표현하여 사용
    • parameterType 속성으로 전달받은 값이 Java 객체인 경우 #{필드명} 형식으로 필드값을 제공받아 사용 (Getter 메소드 자동 호출)
    • ibatis 프레임워크에서는 #변수명|필드명|맵키# 형식으로 표현하여 사용
  • insert : INSERT 명령을 등록하기 위한 엘리먼트

    • id 속성 : SQL 명령이 등록된 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정
    • parameterType="MyMember"
    • insert into mymember values(#{id},#{name},#{phone},#{email})
  • update : UPDATE 명령을 등록하기 위한 엘리먼트

    • parameterType="MyMember"
    • update mymember set name=#{name},phone=#{phone},email=#{email} where id=#{id}
  • delete : DELETE 명령을 등록하기 위한 엘리먼트

    • parameterType="string"
    • parameterType 속성으로 하나의 값만 전달된 경우 #{변수명} 형식으로 전달값을 제공받아 사용
    • 변수명은 특별한 형식없이 표현하여 사용 가능
    • delete from mymember where id=#{id}
  • select : SELECT 명령을 등록하기 위한 엘리먼트

    • 반드시 resultType 속성(resultMap 속성)을 설정하여 매핑정보를 제공받아 사용
    • resultType 속성 : 검색결과를 제공하기 위한 객체(값)의 Java 자료형을 속성값으로 설정
    • Java 자료형 대신 typeAlias 엘리먼트의 별칭 사용 가능
    • resultType 속성값으로 Java 클래스를 설정한 경우 Java 객체를 생성하여 검색행의 컬럼값을 같은 이름의 필드에 자동 저장하여 제공 (자동 매핑)
    • parameterType="string" resultType="MyMember"
    • select * from mymember where id=#{id}
  • select List

    • SELECT 명령에 의해 여러개 행이 검색되도 resultType 속성에는 하나의 검색행에 대한 Java 자료형을 속성값으로 설정
    • resultType="MyMember"
    • select * from mymeber order by id

🐣 예제

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="MyMemberMapper">
	<!-- insert : INSERT 명령을 등록하기 위한 엘리먼트 -->
	<!-- id 속성 : SQL 명령이 등록된 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정 -->
	<!-- parameterType 속성 : SQL 명령에 필요한 값을 제공받기 위한 객체(값)의 Java 자료형을 속성값으로 설정 -->
	<!-- => Java 자료형 대신 typeAlias 엘리먼트의 별칭 사용 가능 -->
	<!-- => SQL 명령에 필요한 값이 없는 경우 parameterType 속성 생략 -->
	<!-- DML 명령(INSERT,UPDATE,DELETE) 관련 엘리먼트는 등록된 SQL 명령 실행 후 조작행의
	갯수를 무조건 정수값(int)으로 매핑하여 재공하므로 resultType 속성 생략 -->
	<insert id="insertMember" parameterType="MyMember">
		<!-- parameterType 속성으로 전달받은 값은 SQL 명령에서 #{변수명|필드명|맵키} 형식으로 표현하여 사용 -->
		<!-- => parameterType 속성으로 전달받은 값이 Java 객체인 경우 #{필드명| 형식으로 
		필드값을 제공받아 사용 - Getter 메소드 자동 호출 -->
		<!-- => ibatis 프레임워크에서는 #변수명|필드명|맵키# 형식으로 표현하여 사용 -->
		insert into mymember values(#{id},#{name},#{phone},#{email})
	</insert>
	
	<!-- update : UPDATE 명령을 등록하기 위한 엘리먼트 -->
	<update id="updateMember" parameterType="MyMember">
		update mymember set name=#{name},phone=#{phone},email=#{email} where id=#{id}
	</update>
	
	<!-- delete : DELETE 명령을 등록하기 위한 엘리먼트 -->
	<delete id="deleteMember" parameterType="string">
		<!-- parameterType 속성으로 하나의 값만 전달된 경우 #{변수명} 형식으로 전달값을 제공받아 사용 -->
		<!-- => 변수명은 특별한 형식없이 표현하여 사용 가능 -->
		delete from mymember where id=#{id}
	</delete>
	
	<!-- select : SELECT 명령을 등록하기 위한 엘리먼트 -->
	<!-- => 반드시 resultType 속성(resultMap 속성)을 설정하여 매핑정보를 제공받아 사용 -->
	<!-- resultType 속성 : 검색결과를 제공하기 위한 객체(값)의 Java 자료형을 속성값으로 설정 -->
	<!-- => Java 자료형 대신 typeAlias 엘리먼트의 별칭 사용 가능 -->
	<!-- resultType 속성값으로 Java 클래스를 설정한 경우 Java 객체를 생성하여 검색행의
	컬럼값을 같은 이름의 필드에 자동 저장하여 제공 - 자동 매핑 -->
	<select id="selectMember" parameterType="string" resultType="MyMember">
		select * from mymember where id=#{id}
	</select>
	
	<!-- SELECT 명령에 의해 여러개 행이 검색되도 resultType 속성에는 하나의 검색행에 대한 
	Java 자료형을 속성값으로 설정 -->
	<select id="selectMemberList" resultType="MyMember">
		select * from mymeber order by id
	</select>
</mapper>





📙 XML DAO Class

  • SqlSessionFactory 객체를 생성하여 반환하는 메소드

  • 회원정보를 전달받아 MYMEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드

    • SqlSession.insert(String elementId, Object parameterValue) : 매퍼에 등록된 insert 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 삽입행의 갯수를 반환하는 메소드
    • elementId : SQL 명령이 등록된 맵퍼와 엘리먼트의 식별자를 매개변수에 전달
    • parameterValue : SQL 명령에 필요한 객체(값)을 매개변수에 전달 (parameterType 속성값으로 사용)
    • 엘리먼트에 전달할 값이 없는 경우 parameterValue 매개변수에 값 전달 생략
    • int rows=sqlSession.insert("MyMemberMapper.insertMember",member);
  • 회원정보를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 변경하고 변경행의 갯수를 반환하는 메소드

    • SqlSessionFactory.openSession(boolean autoCommit) : SqlSession 객체를 생성하여 반환하는 메소드
    • false : AutoCommit 기능 비활성화(기본), true : AutoCommit 기능 활성화
    • SqlSession.update(String elementId, Object parameterValue) : 매퍼에 등록된 update 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 변경행의 갯수를 반환하는 메소드
    • return sqlSession.update("MyMemberMapper.updateMember", member);
  • 아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 삭제하고 삭제행의 갯수를 반환하는 메소드

    • SqlSession.delete(String elementId, Object parameterValue) : 매퍼에 등록된 delete 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 삭제행의 갯수를 반환하는 메소드
    • return sqlSession.delete("MyMemberMapper.deleteMember", id);
  • 아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 검색하여 반환하는 메소드

    • SqlSession.selectOne(String elementId, Object parameterValue) : 매퍼에 등록된 select 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 검색결과를 하나의 객체(값)으로 매핑하여 반환하는 메소드
    • 하나의 행만 검색하는 SELECT 명령을 전달하여 실행할 경우 호출하는 메소드
    • return sqlSession.selectOne("MyMemberMapper.selectMember",id);
  • MYMEMBER 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드

    • SqlSession.selectList(String elementId, Object parameterValue) : 매퍼에 등록된 select 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 검색결과를 요소로 생성되도록 매핑하고 List 객체에 추가하여 반환하는 메소드
    • 여러 개의 행을 검색하는 SELECT 명령을 전달하여 실행할 경우 호출하는 메소드
    • return sqlSession.selectList("MyMemberMapper.selectMemberList");

🐣 예제

package xyz.itwill.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import xyz.itwill.dto.MyMember;

public class MyMemberXMLDAO {
	private static MyMemberXMLDAO _dao;
	
	private MyMemberXMLDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyMemberXMLDAO();
	}
	
	public static MyMemberXMLDAO getDAO() {
		return _dao;
	}
	
	//SqlSessionFactory 객체를 생성하여 반환하는 메소드
	private SqlSessionFactory getSqlSessionFactory() {
		String resource="mybatis-config.xml";
		InputStream inputStream=null;
		try {
			inputStream=Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	//회원정보를 전달받아 MYMEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
	public int insertMember(MyMember member) {
		SqlSession sqlSession=getSqlSessionFactory().openSession();
		try {
			//SqlSession.insert(String elementId, Object parameterValue) : 매퍼에 등록된 insert 
			//엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 삽입행의 갯수를 반환하는 메소드
			// => elementId : SQL 명령이 등록된 맵퍼와 엘리먼트의 식별자를 매개변수에 전달
			// => parameterValue : SQL 명령에 필요한 객체(값)을 매개변수에 전달 - parameterType 속성값으로 사용
			// => 엘리먼트에 전달할 값이 없는 경우 parameterValue 매개변수에 값 전달 생략
			int rows=sqlSession.insert("MyMemberMapper.insertMember",member);
			
			//mybatis 프레임워크는 기본적으로 AutoCommit 기능을 비활성화 처리하고 SQL 명령을 전달하여 실행
			// => DML 명령을 전달하여 실행한 경우 반드시 트렌젝션 관련 메소드 호출하여 커밋 또는 롤백 처리
			if(rows>0) {
				//SqlSession.commit() : 트렌젝션 적용 명령(COMMIT) 명령을 전달하여 실행하는 메소드 - 커밋 처리
				sqlSession.commit();
			} else {
				//SqlSession.rollback() : 트렌젝션 취소 명령(ROLLBACK) 명령을 전달하여 실행하는 메소드 - 롤백 처리
				sqlSession.rollback();
			}
			
			return rows;
		} finally {
			sqlSession.close();
		}
	}
	
	//회원정보를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 변경하고 변경행의 갯수를 반환하는 메소드
	public int updateMember(MyMember member) {
		//SqlSessionFactory.openSession(boolean autoCommit) : SqlSession 객체를 생성하여 반환하는 메소드
		// => false : AutoCommit 기능 비활성화(기본), true : AutoCommit 기능 활성화
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			//SqlSession.update(String elementId, Object parameterValue) : 매퍼에 등록된 update 
			//엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 변경행의 갯수를 반환하는 메소드
			return sqlSession.update("MyMemberMapper.updateMember", member);
		} finally {
			sqlSession.close();
		}
	}
	
	//아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
	public int deleteMember(String id) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			//SqlSession.delete(String elementId, Object parameterValue) : 매퍼에 등록된 delete 
			//엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 삭제행의 갯수를 반환하는 메소드
			return sqlSession.delete("MyMemberMapper.deleteMember", id);
		} finally {
			sqlSession.close();
		}
	}
	
	//아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 검색하여 반환하는 메소드
	public MyMember selectMemeber(String id) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			//SqlSession.selectOne(String elementId, Object parameterValue) : 매퍼에 등록된  
			//select 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 검색결과를 하나의
			//객체(값)으로 매핑하여 반환하는 메소드
			// => 하나의 행만 검색하는 SELECT 명령을 전달하여 실행할 경우 호출하는 메소드
			return sqlSession.selectOne("MyMemberMapper.selectMember",id);
		} finally {
			sqlSession.close();
		}
	}
	
	//MYMEMBER 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드
	public List<MyMember> selectMemberList() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			//SqlSession.selectList(String elementId, Object parameterValue) : 매퍼에 등록된  
			//select 엘리먼트의 SQL 명령을 제공받아 전달하여 실행하고 검색결과를 요소로 생성
			//되도록 매핑하고 List 객체에 추가하여 반환하는 메소드
			// => 여러 개의 행을 검색하는 SELECT 명령을 전달하여 실행할 경우 호출하는 메소드
			return sqlSession.selectList("MyMemberMapper.selectMemberList");
		} finally {
			sqlSession.close();
		}
	}
}





🎀 연습문제 (회원관리)

🐣 회원목록 출력

<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyMember> memberList=MyMemberXMLDAO.getDAO().selectMemberList();
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1 align="center">회원목록</h1>
	<hr>
	<table align="center" border="1" cellspacing="0" width="300">
		<tr>
			<th width="140">아이디</th>
			<th width="160">이름</th>
		</tr>
		<%-- 회원목록 출력 => 반복문 시작 --%>
		<% for(MyMember member:memberList) { %>	
		<tr align="center">
			<td width="140"><%=member.getId() %></td>
			<td width="160">
				<a href="memberView.jsp?id=<%=member.getId() %>"><%=member.getName() %></a></td>
		</tr>
		<% } %>
		<%-- 반복문 종료 --%>

		<tr align="right">
			<td colspan="2">
				<button type="button" 
					onclick="location.href='memberInputForm.jsp';">회원등록</button>
			</td>
		</tr>
	</table>
</body>
</html>





🐣 회원등록 form

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MYBATIS</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
	$("#id").focus();
	
	$("#submitBtn").click(function() {
		if($("#id").val()=="") {
			alert("아이디를 입력해 주세요");
			$("#id").focus();
			return;
		}
		
		if($("#name").val()=="") {
			alert("이름을 입력해 주세요");
			$("#name").focus();
			return;
		}
		
		if($("#phone").val()=="") {
			alert("전화번호를 입력해 주세요");
			$("#phone").focus();
			return;
		}
		
		if($("#email").val()=="") {
			alert("이메일을 입력해 주세요");
			$("#email").focus();
			return;
		}
		
		$("#input").attr("method","POST").attr("action","memberInputAction.jsp").submit();
	});
	
	$("#resetBtn").click(function() {
		$("#input").each(function() {
			this.reset();
		});
		$("#id").focus();
	});
	
	$("#displayBtn").click(function() {
		location.href="memberDisplay.jsp";
	});
});
</script>
</head>
<body>
	<h1 align="center">회원등록</h1>
	<form id="input">
	<table align="center" border="1" cellspacing="0" width="300">
		<tr>
			<th width="100">아이디</th>
			<td align="center" width="200">
				<input type="text" name="id" id="id">
			</td>
		</tr>
		<tr>
			<th width="100">이름</th>
			<td align="center" width="200">
				<input type="text" name="name" id="name">
			</td>
		</tr>
		<tr>
			<th width="100">전화번호</th>
			<td align="center" width="200">
				<input type="text" name="phone" id="phone">
			</td>
		</tr>
		<tr>
			<th width="100">이메일</th>
			<td align="center" width="200">
				<input type="text" name="email" id="email">
			</td>
		</tr>
		<tr>
			<th colspan="2">
				<button type="button" id="submitBtn">입력전송</button>
				<button type="button" id="resetBtn">다시입력</button>
				<button type="button" id="displayBtn">회원정보</button>
			</th>
		</tr>
	</table>	
	</form>
</body>
</html>





🐣 회원등록 action

<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	request.setCharacterEncoding("utf-8");
	String id=request.getParameter("id");
	String name=request.getParameter("name");
	String phone=request.getParameter("phone");
	String email=request.getParameter("email");
	
	MyMember member=new MyMember();
	member.setId(id);
	member.setName(name);
	member.setPhone(phone);
	member.setEmail(email);
	try {
		//SqlSession 객체를 이용하여 매퍼에 등록된 SQL 명령을 전달하여 실행한 경우 문제가
		//발생되면 PersistenceException 발생 - 예외처리
		MyMemberXMLDAO.getDAO().insertMember(member);
		response.sendRedirect("memberDisplay.jsp");
	} catch(Exception e) {
		//response.sendRedirect("memberInputForm.jsp");
		
		out.println("<script type='text/javascript'>");
		out.println("alert('이미 사용중인 아이디를 입력하여 회원등록이 실패 하였습니다.');");
		out.println("history.back();");//out.println("history.go(-1);");
		out.println("</script>");
	}
%>





🐣 회원정보 출력

<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String id=request.getParameter("id");
	MyMember member=MyMemberXMLDAO.getDAO().selectMemeber(id);
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1 align="center">회원정보</h1>
	<hr>
	<table align="center" border="1" cellspacing="0" width="300">
		<tr>
			<th width="100">아이디</th>
			<td align="center" width="200"><%=member.getId() %></td>
		</tr>
		<tr>
			<th width="100">이름</th>
			<td align="center" width="200"><%=member.getName() %></td>
		</tr>
		<tr>
			<th width="100">전화번호</th>
			<td align="center" width="200"><%=member.getPhone() %></td>
		</tr>
		<tr>
			<th width="100">이메일</th>
			<td align="center" width="200"><%=member.getEmail() %></td>
		</tr>
		<tr align="right">
			<td colspan="2">
				<button type="button" onclick="location.href='memberUpdateForm.jsp?id=<%=member.getId()%>';">회원변경</button>
				<button type="button" onclick="location.href='memberDeleteAction.jsp?id=<%=member.getId()%>';">회원삭제</button>
				<button type="button" onclick="location.href='memberDisplay.jsp';">회원목록</button>
			</td>
		</tr>
	</table>
</body>
</html>





🐣 회원변경 form

<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String id=request.getParameter("id");
	
	MyMember member=MyMemberXMLDAO.getDAO().selectMemeber(id);
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MYBATIS</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
	$(document).ready(function() {
	$("#id").focus();
	
	$("#submitBtn").click(function() {
		if($("#name").val()=="") {
			alert("이름을 입력해 주세요");
			$("#name").focus();
			return;
		}
		
		if($("#phone").val()=="") {
			alert("전화번호를 입력해 주세요");
			$("#phone").focus();
			return;
		}
		
		if($("#email").val()=="") {
			alert("이메일을 입력해 주세요");
			$("#email").focus();
			return;
		}
		
		$("#input").attr("method","POST").attr("action","memberUpdateAction.jsp").submit();
	});
	
	$("#resetBtn").click(function() {
		$("#input").each(function() {
			this.reset();
		});
		$("#id").focus();
	});
	
	$("#displayBtn").click(function() {
		location.href="memberDisplay.jsp";
	});
});
</script>
</head>
<body>
	<h1 align="center">회원변경</h1>
	<form id="input">
	<input type="hidden" name="id" value="<%=member.getId()%>">
	<table align="center" border="1" cellspacing="0" width="300">
		<tr>
			<th width="100">아이디</th>
			<td align="center" width="200">
				<%=member.getId()%>
			</td>
		</tr>
		<tr>
			<th width="100">이름</th>
			<td align="center" width="200">
				<input type="text" name="name" id="name" value="<%=member.getName()%>">
			</td>
		</tr>
		<tr>
			<th width="100">전화번호</th>
			<td align="center" width="200">
				<input type="text" name="phone" id="phone" value="<%=member.getPhone()%>">
			</td>
		</tr>
		<tr>
			<th width="100">이메일</th>
			<td align="center" width="200">
				<input type="text" name="email" id="email" value="<%=member.getEmail()%>">
			</td>
		</tr>
		<tr>
			<th colspan="2">
				<button type="button" id="submitBtn">변경전송</button>
				<button type="button" id="resetBtn">다시입력</button>
				<button type="button" id="displayBtn">회원정보</button>
			</th>
		</tr>
	</table>	
	</form>
</body>
</html>





🐣 회원변경 action

<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	request.setCharacterEncoding("utf-8");
	
	String id=request.getParameter("id");
	String name=request.getParameter("name");
	String phone=request.getParameter("phone");
	String email=request.getParameter("email");
	
	MyMember member=new MyMember();
	member.setId(id);
	member.setName(name);
	member.setPhone(phone);
	member.setEmail(email);
	
	MyMemberXMLDAO.getDAO().updateMember(member);
	
	response.sendRedirect("memberDisplay.jsp");
%>





🐣 회원정보 삭제 action

<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String id=request.getParameter("id");
	MyMemberXMLDAO.getDAO().deleteMember(id);
	
	response.sendRedirect("memberDisplay.jsp");
%>





🌼 interface 기반의 매퍼 파일

  • mybatis 프레임워크에서는 인터페이스를 이용하여 매퍼 설정 가능

    • 추상메소드에 매퍼 어노테이션(Mapper Annotation)을 사용하여 SQL 명령 등록

📒 interface Mapper 파일

  • @Insert : 추상메소드에 INSERT 명령을 등록하기 위한 어노테이션

    • value 속성 : 추상메소드에 등록할 SQL 명령을 속성값으로 설정
    • value 속성외에 다른 속성이 없는 경우 속성값만 설정 가능
    • @Insert("insert into mymember values(#{id},#{name},#{phone},#{email})")
  • 추상메소드의 매개변수는 SQL 명령에 필요한 객체(값)을 전달하기 위해 선언하며 반환형은 등록된 SQL 명령을 전달하여 실행한 결과를 제공받기 위한 Java 자료형을 선언

    • int insertMember(MyMember member);
  • @Update : 추상메소드에 UPDATE 명령을 등록하기 위한 어노테이션

    • @Update("update mymember set name=#{name},phone=#{phone},email=#{email} where id=#{id}")
  • @Delete : 추상메소드에 DELETE 명령을 등록하기 위한 어노테이션

    • @Delete("delete from mymember where id=#{id}")
  • @Select : 추상메소드에 SELECT 명령을 등록하기 위한 어노테이션

    • @Select("select * from mymember where id=#{id}")
    • @Select("select * from mymember order by id")

🐣 예제

package xyz.itwill.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import xyz.itwill.dto.MyMember;

//mybatis 프레임워크에서는 인터페이스를 이용하여 매퍼 설정 가능
// => 추상메소드에 매퍼 어노테이션(Mapper Annotation)을 사용하여 SQL 명령 등록
public interface MyMemberInterfaceMapper {
	//@Insert : 추상메소드에 INSERT 명령을 등록하기 위한 어노테이션
	//value 속성 : 추상메소드에 등록할 SQL 명령을 속성값으로 설정
	// => value 속성외에 다른 속성이 없는 경우 속성값만 설정 가능
	@Insert("insert into mymember values(#{id},#{name},#{phone},#{email})")
	//추상메소드의 매개변수는 SQL 명령에 필요한 객체(값)을 전달하기 위해 선언하며 반환형은
	//등록된 SQL 명령을 전달하여 실행한 결과를 제공받기 위한 Java 자료형을 선언 
	int insertMember(MyMember member);
	
	//@Update : 추상메소드에 UPDATE 명령을 등록하기 위한 어노테이션
	@Update("update mymember set name=#{name},phone=#{phone},email=#{email} where id=#{id}")
	int updateMember(MyMember member);
	
	//@Delete : 추상메소드에 DELETE 명령을 등록하기 위한 어노테이션
	@Delete("delete from mymember where id=#{id}")
	int deleteMember(String id);
	
	//@Select : 추상메소드에 SELECT 명령을 등록하기 위한 어노테이션
	@Select("select * from mymember where id=#{id}")
	MyMember selectMember(String id);
	
	@Select("select * from mymember order by id")
	List<MyMember> selectMemberList();
}





📒 interface DAO Class

  • 회원정보를 전달받아 MYMEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드

    • SqlSession.getMaaper(Class<T> clazz) : 메모리에 저장된 인터페이스(맵퍼)를 제공받아 Mapper 객체로 생성하여 반환하는 메소드
    • 매개변수에 [XXX.class] 형식으로 인터페이스를 직접 표현하여 Class 객체(Clazz)를 전달
    • Mapper 객체 : 인터페이스를 제공받아 생성되며 추상메소드를 호출하여 등록된 SQL 명령을 전달하여 실행하고 실행결과를 매핑하여 반환하기 위한 기능을 제공하는 객체
    • return sqlSession.getMapper(MyMemberInterfaceMapper.class).insertMember(member);
  • 회원정보를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 변경하고 변경행의 갯수를 반환하는 메소드

    • return sqlSession.getMapper(MyMemberInterfaceMapper.class).updateMember(member);
  • 아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 삭제하고 삭제행의 갯수를 반환하는 메소드

    • return sqlSession.getMapper(MyMemberInterfaceMapper.class).deleteMember(id);
  • 아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 검색하여 반환하는 메소드

    • return sqlSession.getMapper(MyMemberInterfaceMapper.class).selectMember(id);
  • MYMEMBER 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드

    • return sqlSession.getMapper(MyMemberInterfaceMapper.class).selectMemberList();

📌 class객체(clazz) 생성 방법

  • clazz : static영역 안에 있는 클래스의 메모리 주소 저장 (객체 안의 메모리 주소로 클래스에 접근 가능)
  1. [클래스명.class] 형식으로 직접 클래스 객체 전달

  2. Class.forName(String className) : 문자열로 클래스를 전달받아 메모리에 저장하는 메소드 - Class 객체 반환

  3. Object.getClass() 메소드를 호출하는 방법 (현재 사용하는 클래스에 대한 Class 객체 반환)


🐣 예제

package xyz.itwill.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import xyz.itwill.dto.MyMember;
import xyz.itwill.mapper.MyMemberInterfaceMapper;

public class MyMemberInterfaceDAO {
	private static MyMemberInterfaceDAO _dao;
	
	private MyMemberInterfaceDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyMemberInterfaceDAO();
	}
	
	public static MyMemberInterfaceDAO getDAO() {
		return _dao;
	}
	
	//SqlSessionFactory 객체를 생성하여 반환하는 메소드
	private SqlSessionFactory getSqlSessionFactory() {
		String resource="mybatis-config.xml";
		InputStream inputStream=null;
		try {
			inputStream=Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	//회원정보를 전달받아 MYMEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
	public int insertMember(MyMember member) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			//SqlSession.getMaaper(Class<T> clazz) : 메모리에 저장된 인터페이스(맵퍼)를 
			//제공받아 Mapper 객체로 생성하여 반환하는 메소드
			// => 매개변수에 [XXX.class] 형식으로 인터페이스를 직접 표현하여 Class 객체(Clazz)를 전달
			//Mapper 객체 : 인터페이스를 제공받아 생성되며 추상메소드를 호출하여 등록된 SQL  
			//명령을 전달하여 실행하고 실행결과를 매핑하여 반환하기 위한 기능을 제공하는 객체
			return sqlSession.getMapper(MyMemberInterfaceMapper.class).insertMember(member);
		} finally {
			sqlSession.close();
		}
	}
	
	//회원정보를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 변경하고 변경행의 갯수를 반환하는 메소드
	public int updateMember(MyMember member) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberInterfaceMapper.class).updateMember(member);
		} finally {
			sqlSession.close();
		}
	}
	
	//아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
	public int deleteMember(String id) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberInterfaceMapper.class).deleteMember(id);
		} finally {
			sqlSession.close();
		}
	}
	
	//아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 검색하여 반환하는 메소드
	public MyMember selectMemeber(String id) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberInterfaceMapper.class).selectMember(id);
		} finally {
			sqlSession.close();
		}
	}
	
	//MYMEMBER 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드
	public List<MyMember> selectMemberList() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberInterfaceMapper.class).selectMemberList();
		} finally {
			sqlSession.close();
		}
	}
}





🐣 DAO 메소드 출력

  • List<MyMember> memberList=MyMemberInterfaceDAO.getDAO().selectMemberList();
<%@page import="xyz.itwill.dao.MyMemberInterfaceDAO"%>
<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//List<MyMember> memberList=MyMemberXMLDAO.getDAO().selectMemberList();
	List<MyMember> memberList=MyMemberInterfaceDAO.getDAO().selectMemberList();
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1 align="center">회원목록</h1>
	<hr>
	<table align="center" border="1" cellspacing="0" width="300">
		<tr>
			<th width="140">아이디</th>
			<th width="160">이름</th>
		</tr>
		<%-- 회원목록 출력 => 반복문 시작 --%>
		<% for(MyMember member:memberList) { %>	
		<tr align="center">
			<td width="140"><%=member.getId() %></td>
			<td width="160">
				<a href="memberView.jsp?id=<%=member.getId() %>"><%=member.getName() %></a></td>
		</tr>
		<% } %>
		<%-- 반복문 종료 --%>

		<tr align="right">
			<td colspan="2">
				<button type="button" 
					onclick="location.href='memberInputForm.jsp';">회원등록</button>
			</td>
		</tr>
	</table>
</body>
</html>
          
          
          
          
  

🌼 매퍼 바인딩 (xml+interface)

  • XML 기반의 매퍼 파일과 Interface 기반의 매퍼 파일을 바인딩하여 하나의 매퍼로 동작되도록 설정하는 방법

  • XML 기반의 매퍼 파일에서 mapper 엘리먼트의 namespace 속성값과 같은 이름으로 Interface 매퍼 파일 생성

  • XML 기반의 매퍼 파일에서 SQL 명령을 등록한 엘리먼트와 동일한 형식으로 Interface 기반의 매퍼 파일에 추상메소드 작성


📗 매퍼 바인딩 (xml)

  • DAO 클래스의 메소드에서 Interface 기반의 매퍼 파일에 추상메소드를 호출할 경우 동일한 형식의 XML 기반의 매퍼 파일의 엘리먼트로 등록된 SQL 명령을 전달하여 실행
    • 엘리먼트의 id 속성값과 동일한 이름의 추상메소드 선언
    • 엘리먼트의 parameterType 속성값과 동일한 자료형으로 추상메소드의 매개변수를 선언
    • 엘리먼트의 resultType 속성값과 동일한 자료형으로 추상메소드의 반환형을 선언

🐣 예제

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- XML 기반의 매퍼 파일과 Interface 기반의 매퍼 파일을 바인딩하여 하나의 매퍼로 동작되도록 설정하는 방법 -->
<!-- => XML 기반의 매퍼 파일에서 mapper 엘리먼트의 namespace 속성값과 같은 이름으로 Interface 매퍼 파일 생성 -->
<!-- => XML 기반의 매퍼 파일에서 SQL 명령을 등록한 엘리먼트와 동일한 형식으로 Interface 기반의
매퍼 파일에 추상메소드 작성 -->
<mapper namespace="xyz.itwill.mapper.MyMemberMapper">
	<!-- DAO 클래스의 메소드에서 Interface 기반의 매퍼 파일에 추상메소드를 호출할 경우 동일한
	형식의 XML 기반의 매퍼 파일의 엘리먼트로 등록된 SQL 명령을 전달하여 실행 -->
	<!-- => 엘리먼트의 id 속성값과 동일한 이름의 추상메소드 선언 -->
	<!-- => 엘리먼트의 parameterType 속성값과 동일한 자료형으로 추상메소드의 매개변수를 선언 -->
	<!-- => 엘리먼트의 resultType 속성값과 동일한 자료형으로 추상메소드의 반환형을 선언 -->
	<insert id="insertMember" parameterType="MyMember">
		insert into mymember values(#{id},#{name},#{phone},#{email})
	</insert>
	
	<update id="updateMember" parameterType="MyMember">
		update mymember set name=#{name},phone=#{phone},email=#{email} where id=#{id}
	</update>
	
	<delete id="deleteMember" parameterType="string">
		delete from mymember where id=#{id}
	</delete>
	
	<select id="selectMember" parameterType="string" resultType="MyMember">
		select * from mymember where id=#{id}
	</select>
	
	<select id="selectMemberList" resultType="MyMember">
		select * from mymember order by id
	</select>
</mapper>





📗 매퍼 바인딩 (interface)

package xyz.itwill.mapper;

import java.util.List;

import xyz.itwill.dto.MyMember;

public interface MyMemberMapper {
	int insertMember(MyMember member);
	int updateMember(MyMember member);
	int deleteMember(String id);
	MyMember selectMember(String id);
	List<MyMember> selectMemberList();
}





📗 DAO class

  • SqlSessionFactory 객체를 생성하여 반환하는 메소드

  • 회원정보를 전달받아 MYMEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드

    • return sqlSession.getMapper(MyMemberMapper.class).insertMember(member);
  • 회원정보를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 변경하고 변경행의 갯수를 반환하는 메소드

    • return sqlSession.getMapper(MyMemberMapper.class).updateMember(member);
  • 아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 삭제하고 삭제행의 갯수를 반환하는 메소드

    • return sqlSession.getMapper(MyMemberMapper.class).deleteMember(id);
  • 아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 검색하여 반환하는 메소드

    • return sqlSession.getMapper(MyMemberMapper.class).selectMember(id);
  • MYMEMBER 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드

    • return sqlSession.getMapper(MyMemberMapper.class).selectMemberList();

🐣 예제

package xyz.itwill.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import xyz.itwill.dto.MyMember;
import xyz.itwill.mapper.MyMemberMapper;

public class MyMemberDAO {
	private static MyMemberDAO _dao;
	
	private MyMemberDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyMemberDAO();
	}
	
	public static MyMemberDAO getDAO() {
		return _dao;
	}
	
	//SqlSessionFactory 객체를 생성하여 반환하는 메소드
	private SqlSessionFactory getSqlSessionFactory() {
		String resource="mybatis-config.xml";
		InputStream inputStream=null;
		try {
			inputStream=Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	//회원정보를 전달받아 MYMEMBER 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
	public int insertMember(MyMember member) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberMapper.class).insertMember(member);
		} finally {
			sqlSession.close();
		}
	}
	
	//회원정보를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 변경하고 변경행의 갯수를 반환하는 메소드
	public int updateMember(MyMember member) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberMapper.class).updateMember(member);
		} finally {
			sqlSession.close();
		}
	}
	
	//아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
	public int deleteMember(String id) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberMapper.class).deleteMember(id);
		} finally {
			sqlSession.close();
		}
	}
	
	//아이디를 전달받아 MYMEMBER 테이블에 저장된 회원정보를 검색하여 반환하는 메소드
	public MyMember selectMemeber(String id) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberMapper.class).selectMember(id);
		} finally {
			sqlSession.close();
		}
	}
	
	//MYMEMBER 테이블에 저장된 모든 회원정보를 검색하여 반환하는 메소드
	public List<MyMember> selectMemberList() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyMemberMapper.class).selectMemberList();
		} finally {
			sqlSession.close();
		}
	}
}





🐣 DAO 메소드 출력

  • List<MyMember> memberList=MyMemberDAO.getDAO().selectMemberList();
 <%@page import="xyz.itwill.dao.MyMemberDAO"%>
<%@page import="xyz.itwill.dao.MyMemberInterfaceDAO"%>
<%@page import="xyz.itwill.dao.MyMemberXMLDAO"%>
<%@page import="xyz.itwill.dto.MyMember"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//List<MyMember> memberList=MyMemberXMLDAO.getDAO().selectMemberList();
	//List<MyMember> memberList=MyMemberInterfaceDAO.getDAO().selectMemberList();
	List<MyMember> memberList=MyMemberDAO.getDAO().selectMemberList();
%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1 align="center">회원목록</h1>
	<hr>
	<table align="center" border="1" cellspacing="0" width="300">
		<tr>
			<th width="140">아이디</th>
			<th width="160">이름</th>
		</tr>
		<%-- 회원목록 출력 => 반복문 시작 --%>
		<% for(MyMember member:memberList) { %>	
		<tr align="center">
			<td width="140"><%=member.getId() %></td>
			<td width="160">
				<a href="memberView.jsp?id=<%=member.getId() %>"><%=member.getName() %></a></td>
		</tr>
		<% } %>
		<%-- 반복문 종료 --%>

		<tr align="right">
			<td colspan="2">
				<button type="button" 
					onclick="location.href='memberInputForm.jsp';">회원등록</button>
			</td>
		</tr>
	</table>
</body>
</html>





📌 DTO class (myuser)



package xyz.itwill.dto;


//Java 자료형(Class, Interface, Enum)을 선언할 경우에는 파스칼 표기법 사용
// => 파스칼 표기법(PascalCase) : 모든 단어의 첫문자를 대문자로 표현하여 식별자를 선언하는 방법
public class MyUser {
	//Java 자료형을 제외한 식별자를 선언할 경우에는 카멜 표기법 사용
	// => 카멜 표기법(CamelCase) : 첫단어를 제외한 나머지 단어의 첫문자를 대문자로 표현하여 식별자를 선언하는 방법
	private String userId;
	private String userName;
	
	public MyUser() {
		// TODO Auto-generated constructor stub
	}
    
	public MyUser(String userId, String userName) {
		super();
		this.userId = userId;
		this.userName = userName;
	}
	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
}






📌 식별자 표기법

  • MYUSER 테이블 : 회원정보를 저장하기 위한 테이블

    • SQL 명령은 대소문자를 구분하지 않아 식별자를 선언할 때 스네이크 표기법 사용
    • 스네이크 표기법(SnakeCase) : 단어와 단어를 구분하기 위해 _ 기호를 사용하여 식별자를 선언하는 방법
    • create table myuser(user_id varchar2(50) primary key, user_name varchar2(50));
  • Java 자료형(Class, Interface, Enum)을 선언할 경우에는 파스칼 표기법 사용

    • 파스칼 표기법(PascalCase) : 모든 단어의 첫문자를 대문자로 표현하여 식별자를 선언하는 방법
  • Java 자료형을 제외한 식별자를 선언할 경우에는 카멜 표기법 사용

    • 카멜 표기법(CamelCase) : 첫단어를 제외한 나머지 단어의 첫문자를 대문자로 표현하여 식별자를 선언하는 방법
    • private String userId;

🌼 속성명과 필드명이 다를 경우

  • resultType 속성을 사용하면 resultType 속성값으로 설정된 클래스로 객체를 생성하여 검색행의 컬럼값과 같은 이름의 객체 필드값으로 자동 저장하여 제공 (자동 매핑)

  • 문제점 : 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 모두 다른 경우 resultType 속성값으로 설정된 클래스의 객체 대신 NULL 제공

  • 해결방법1 : 검색행의 컬럼명을 resultType 속성값으로 설정된 클래스의 필드명과 같도록 검색
    • SELECT 명령에서 Column Alias 기능을 이용하여 검색대상의 별칭을 필드명과 같도록 검색
    • select user_id userId,user_name userName from myuser order by user_id
  • 해결방법2 : mybatis 환경설정 파일(mybatis-config.xml)의 setting 엘리먼트를 사용하여 스네이크 표기법으로 표현된 식별자를 자동으로 카멜 표기법으로 변환되도록 환경설정 변경
    • mapUnderscoreToCamelCase : 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함
    • <setting name="mapUnderscoreToCamelCase" value="true"/>
  • 해결방법3 : resultMap 엘리먼트를 사용하여 검색행의 컬럼값이 클래스의 필드에 저장되도록 설정 (수동 매핑)
    • resultMap : 검색행을 Java 객체로 생성하여 제공하기 위한 엘리먼트
    • 검색행의 컬럼값을 필드에 저장하기 위해 하위 엘리먼트를 사용
    • id 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정
    • <resultMap type="MyUser" id="myUserResultMap">
  • id : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 (Setter 메소드 호출)
    • PK 제약조건이 설정된 컬럼값을 제공받아 필드에 저장하기 위해 사용
    • column 속성 : 검색행의 컬럼명을 속성값으로 설정
    • property 속성 : 클래스의 필드명을 속성값으로 설정
    • <id column="user_id" property="userId"/>
  • result : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 (Setter 메소드 호출)
    • <result column="user_name" property="userName"/>
  • resultMap 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정 (수동 매핑)
    • <select id="selectUserList" resultMap="myUserResultMap">

📘 xml 매퍼 (MyUser)

  • sql : SQL 명령을 구성하는 일부분의 문장을 등록하기 위한 엘리먼트

    • 반복적인 별칭을 만들 때, 조건문을 만들 때 사용 가능 (include 태그와 함께 사용)
  • include : sql 엘리먼트로 등록된 문장을 제공받아 SQL 명령에 포함하는 엘리먼트

    • refid 속성 : sql 엘리먼트의 식별자를 속성값으로 설정
    • select <include refid="myUserColumnAlias"/> from myuser order by user_id
  • resultMap : 검색행을 Java 객체로 생성하여 제공하기 위한 엘리먼트

    • 검색행의 컬럼값을 필드에 저장하기 위해 하위 엘리먼트를 사용
    • 하위 엘리먼트 : constructor, id, result, association, collection, discriminator
    • type 속성 : resultMap 엘리먼트로 제공될 Java 객체의 자료형(클래스)을 속성값으로 설정
    • Java 자료형 대신 typeAlias 엘리먼트의 별칭 사용 가능
    • id 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정
    • <resultMap type="MyUser" id="myUserResultMap">
  • id : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 (Setter 메소드 호출)

    • PK 제약조건이 설정된 컬럼값을 제공받아 필드에 저장하기 위해 사용
    • column 속성 : 검색행의 컬럼명을 속성값으로 설정
    • property 속성 : 클래스의 필드명을 속성값으로 설정
    • <id column="user_id" property="userId"/>
  • result : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 (Setter 메소드 호출)

    • <result column="user_name" property="userName"/>
  • resultMap 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정 (수동 매핑)

    • <select id="selectUserList" resultMap="myUserResultMap">


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill.mapper.MyUserMapper">
	<insert id="insertUser" parameterType="MyUser">
		insert into myuser values(#{userId}, #{userName})
	</insert>
	
	<!-- resultType 속성을 사용하면 resultType 속성값으로 설정된 클래스로 객체를 생성하여
	검색행의 컬럼값을 같은 이름의 객체 필드값으로 자동 저장하여 제공 - 자동 매핑 -->
	<!-- 문제점 : 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 모두 다른
	경우 resultType 속성값으로 설정된 클래스의 객체 대신 NULL 제공 -->
	<!--  
	<select id="selectUserList" resultType="MyUser">
		select * from myuser order by user_id
	</select>
	-->
	
	<!-- 해결방법-1 : 검색행의 컬럼명을 resultType 속성값으로 설정된 클래스의 필드명과 같도록 검색 -->
	<!-- => SELECT 명령에서 Column Alias 기능을 이용하여 검색대상의 별칭을 필드명과 같도록 검색 -->
	<!--  
	<select id="selectUserList" resultType="MyUser">
		select user_id userId,user_name userName from myuser order by user_id
	</select>
	-->
	
	<!-- sql : SQL 명령을 구성하는 일부분의 문장을 등록하기 위한 엘리먼트 -->
	<sql id="myUserColumnAlias">
		user_id userId,user_name userName
	</sql>
	
	<!-- include : sql 엘리먼트로 등록된 문장을 제공받아 SQL 명령에 포함하는 엘리먼트 -->
	<!-- refid 속성 : sql 엘리먼트의 식별자를 속성값으로 설정 -->
	<!--  
	<select id="selectUserList" resultType="MyUser">
		select <include refid="myUserColumnAlias"/> from myuser order by user_id
	</select>
	-->
	
	<!-- 해결방법-2 : mybatis 환경설정 파일(mybatis-config.xml)의 setting 엘리먼트를 사용하여
	스네이크 표기법의 표현된 식별자를 자동으로 카멜 표기법으로 변환되도록 환경설정 변경 -->
	<!--  
	<select id="selectUserList" resultType="MyUser">
		select * from myuser order by user_id
	</select>
	-->
	
	<!-- 해결방법-3 : resultMap 엘리먼트를 사용하여 검색행의 컬럼값이 클래스의 필드에 저장
	되도록 설정 - 수동 매핑 -->
	<!-- resultMap : 검색행을 Java 객체로 생성하여 제공하기 위한 엘리먼트 -->
	<!-- => 검색행의 컬럼값을 필드에 저장하기 위해 하위 엘리먼트를 사용 -->
	<!-- => 하위 엘리먼트 : constructor, id, result, association, collection, discriminator -->
	<!-- type 속성 : resultMap 엘리먼트로 제공될 Java 객체의 자료형(클래스)을 속성값으로 설정 -->
	<!-- => Java 자료형 대신 typeAlias 엘리먼트의 별칭 사용 가능  -->
	<!-- id 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정 -->
	<resultMap type="MyUser" id="myUserResultMap">
		<!-- id : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 - Setter 메소드 호출 -->
		<!-- => PK 제약조건이 설정된 컬럼값을 제공받아 필드에 저장하기 위해 사용 -->
		<!-- column 속성 : 검색행의 컬럼명을 속성값으로 설정 -->
		<!-- property 속성 : 클래스의 필드명을 속성값으로 설정 -->
		<id column="user_id" property="userId"/>	
		<!-- result : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 - Setter 메소드 호출 -->
		<result column="user_name" property="userName"/>	
	</resultMap>
	
	<!-- resultMap 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정 - 수동 매핑 -->
	<select id="selectUserList" resultMap="myUserResultMap">
		select * from myuser order by user_id
	</select>
</mapper>





🐣 매퍼 바인딩 (xml) 요약

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill.mapper.MyUserMapper">
	<insert id="insertUser" parameterType="MyUser">
		insert into myuser values(#{userId}, #{userName})
	</insert>	
	<!-- resultMap : 검색행을 Java 객체로 생성하여 제공하기 위한 엘리먼트 -->
	<!-- type 속성 : Java 객체의 자료형(클래스), id 속성 : resultMap 엘리먼트의 식별자 -->
	<resultMap type="MyUser" id="myUserResultMap">
		<!-- id : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 (PK 제약조건이 설정된 컬럼값) -->
		<!-- column 속성 : 검색행의 컬럼명, property 속성 : 클래스의 필드명 -->
		<id column="user_id" property="userId"/>	
		<!-- result : 검색행의 컬럼값을 필드에 저장하기 위한 엘리먼트 -->
		<result column="user_name" property="userName"/>	
	</resultMap>
	
	<!-- resultMap 속성 : resultMap 엘리먼트의 식별자를 속성값으로 설정 - 수동 매핑 -->
	<select id="selectUserList" resultMap="myUserResultMap">
		select * from myuser order by user_id
	</select>
</mapper>





📘 interface 매퍼 (MyUser)

package xyz.itwill.mapper;

import java.util.List;

import xyz.itwill.dto.MyUser;

public interface MyUserMapper {
	int insertUser(MyUser user);
	List<MyUser> selectUserList();
}





📌 SqlSessionFactory 객체 생성

  • SqlSessionFactory 객체를 생성하여 반환하는 기능을 제공하는 클래스

    • 매퍼를 사용하는 모든 DAO 클래스가 상속받기 위한 부모클래스
    • 상속을 목적으로 작성된 클래스이므로 추상클래스로 선언하는 것을 권장
    • abstract : 생성자가 있어도 객체 생성 불가 싱글톤 패턴과 같이 한번만 실행


package xyz.itwill.dao;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public abstract class AbstractSession {
	private static SqlSessionFactory sqlSessionFactory;
	
	static {
		String resource="mybatis-config.xml";
		InputStream inputStream=null;
		try {
			inputStream=Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
		sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	protected SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}
}






📘 DAO class

  • SqlSessionFactory객체를 생성하는 클래스 AbstractSession 상속
package xyz.itwill.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import xyz.itwill.dto.MyUser;
import xyz.itwill.mapper.MyUserMapper;

public class MyUserDAO extends AbstractSession {
	private static MyUserDAO _dao;
	
	private MyUserDAO() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_dao=new MyUserDAO();
	}
	
	public static MyUserDAO getDAO() {
		return _dao;
	}
	
	public int insertUser(MyUser user) {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyUserMapper.class).insertUser(user);
		} finally {
			sqlSession.close();
		}
	}
	
	public List<MyUser> selectUserList() {
		SqlSession sqlSession=getSqlSessionFactory().openSession(true);
		try {
			return sqlSession.getMapper(MyUserMapper.class).selectUserList();
		} finally {
			sqlSession.close();
		}
	}
}





🐣 DAO 메소드 출력

  • 회원정보 삽입
<%@page import="xyz.itwill.dto.MyUser"%>
<%@page import="xyz.itwill.dao.MyUserDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%	
	MyUserDAO.getDAO().insertUser(new MyUser("abc","홍길동"));
	MyUserDAO.getDAO().insertUser(new MyUser("xyz","임꺽정"));
	MyUserDAO.getDAO().insertUser(new MyUser("opq","전우치"));
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UT0F-8">
<title>MYBATIS</title>
</head>
<body>
	<h1>회원등록</h1>
	<hr>
	<h3>회원정보가 성공적으로 삽입 되었습니다.</h3>
</body>
</html>





  • 회원목록 출력
<%@page import="xyz.itwill.dao.MyUserDAO"%>
<%@page import="xyz.itwill.dto.MyUser"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	List<MyUser> userList=MyUserDAO.getDAO().selectUserList();
	//System.out.println("userList.size() = "+userList.size()); : 3
	//System.out.println("userList.get(0) = "+userList.get(0)); : 컬럼명과 필드명이 다를 경우 객체에 null값이 저장됨 
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MYBATIS</title>
</head>
<body>
	<h1>회원목록</h1>
	<hr>
	<ul>
	<% for(MyUser user:userList) { %>
		<li>아이디 = <%=user.getUserId() %>, 이름 = <%=user.getUserName() %></li>
	<% } %>
	</ul>
</body>
</html>





      
profile
Study Log 📂

0개의 댓글