2) jar 다운로드
http://mybatis.org > mybatis-3.5.14 > assets > mybatis-3.5.14.zip 다운
3) 압축 풀기
mybatis-3.5.14.jar (build path 대상임)
mybatis-3.5.14.pdf (매뉴얼, https://mybatis.org/mybatis-3/)
4) 이클립스에서 build path
(1) 프로젝트 생성
(2) 2개의 jar 파일 build path
- mysql-connector-j-8.jar (mysql 드라이버)
- mybatis-3.5.14.jar
: JDBC에서 사용했던 4가지 정보를 외부 파일에 저장
-> 파일 추가 - jdbc.properties
-> src 폴더에 저장 (패키지 설정 가능 - com.config)
cf) properties에 저장하는 형식
key = value
key = value
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testdb
jdbc.userid=root
jdbc.passwd=1234
(띄어쓰기 X)
: 최소 2개의 xml 파일이 필요하다
-> *.xml
용도 : JDBC에서 사용했던 SQL 문을 저장하는 파일
테이블 당 하나씩 작성
XXXMapper.xml 형식으로 만들기
com.config 패키지에 저장
예> DeptMapper.xml
<!-- namespace가 패키지같은 역할을 한다 -->
<mapper namespace="com.config.DeptMapper">
<!-- 전체 조회 -->
<select id="findAll" resultType="DeptDTO">
select deptno, dname, loc
from dept
order by deptno desc
</select>
<!-- 조건 조회 select는 꼭 resultType 설정해줘야됨 parameterType은 해시블럭에 들어가는 타입 설정해주는 것-->
<select id="findByDeptno" resultType="DeptDTO" parameterType="int">
select deptno, dname, loc
from dept
where deptno = #{deptno} <!-- mapper는 해시 블럭 #{ } -->
</select>
<!-- 조건 조회 2 -->
<select id="findByDnameOrLoc" resultType="DeptDTO" parameterType="DeptDTO">
select deptno, dname, loc
from dept
where dname = #{dname} or loc = #{loc} <!-- 이 때는 DeptDTO의 변수명으로 써줘야됨 -->
</select>
<!-- 조건 조회 3 -->
<select id="findByDnameOrLoc2" resultType="DeptDTO"
parameterType="hashmap">
select deptno, dname, loc
from dept
where dname = #{x} or loc = #{y} <!-- hashmap은 키값으로 써줘야됨-->
</select>
</mapper>
<mapper namespace="com.config.DeptMapper2">
<!-- 삭제 -->
<delete id="remove" parameterType="int">
delete
from dept
where deptno = #{deptno}
</delete>
<delete id="removeByDname" parameterType="string">
delete
from dept
where dname = #{dname}
</delete>
<!-- 수정 -->
<update id="update" parameterType="DeptDTO">
update dept
set dname = #{dname}, loc = #{loc}
where deptno = #{deptno}
</update>
<!-- 저장 -->
<insert id="save" parameterType="DeptDTO">
insert into dept (deptno, dname, loc)
values (#{deptno}, #{dname}, #{loc})
</insert>
<insert id="save2" parameterType="DeptDTO">
insert into dept (deptno, dname)
values (#{deptno}, #{dname})
</insert>
<!-- 전체 조회 -->
<select id="findAll" resultType="DeptDTO">
select deptno, dname, loc
from dept
order by deptno asc
</select>
</mapper>
<configuration>
<!-- jdbc.properties 등록 (driver, url, userid, passwd) -->
<properties resource="com/config/jdbc.properties"> </properties>
<!-- DTO 별칭 -->
<typeAliases>
<typeAlias type="com.dto.DeptDTO" alias="DeptDTO" />
<typeAlias type="com.dto.EmpDTO" alias="EmpDTO" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.userid}"/>
<property name="password" value="${jdbc.passwd}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper.xml 등록 -->
<mapper resource="com/config/DeptMapper.xml"/>
<mapper resource="com/config/DeptMapper2.xml"/>
<mapper resource="com/config/EmpMapper.xml"/>
</mappers>
</configuration>
: Configuration.xml 파일을 읽는 자바 코드가 필요하다
public class MySqlSessionFactory {
static SqlSessionFactory sqlSessionFactory;
static {
String resource = "com/config/Configuration.xml";
InputStream inputStream=null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}//end static 블럭
// SqlSessionFactory 로부터 SqlSession 얻는 메서드
public static SqlSession getSession() {
// MyBatis는 명시적으로 commit 지정해야 된다
SqlSession session = sqlSessionFactory.openSession(); // openSession(false) 동일
return session;
}
(1) JDBC에서 필요한 API
(2) MyBatis에서 필요한 API
역할 : select 된 결과인 레코드를 자동으로 DTO에 저장한다
단, 연결 고리가 존재한다. 테이블의 컬럼명 (원칙은 컬럼 헤더값)과 DTO의 변수명이 일치해야 된다
예> DeptDTO.java
public class DeptDTO {
int deptno;
String dname;
String loc;
public DeptDTO() {
}
public DeptDTO(int deptno, String dname, String loc) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@Override
public String toString() {
return "DeptDTO [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
}
}
}
cf) parameterType = "전달할 파라미터 타입" 의 종류
https://mybatis.org/mybatis-3/configuration.html#typealiases
예> com.dto.DeptDTO -> DeptDTO (별칭)로 지정
-> Configuration.xml에서 별칭 지정하고 Mapper에서 별칭을 사용한다
문법:
<!-- DTO 별칭 -->
<typeAliases>
<typeAlias type="com.dto.DeptDTO" alias="DeptDTO" />
<typeAlias type="com.dto.EmpDTO" alias="EmpDTO" />
</typeAliases>
-> DeptMapper.xml에 있는 태그를 호출하는 작업
-단일 레코드 반환
DeptDTO dto = session.selectOne("mapper의 id값");
DeptDTO dto = session.selectOne("mapper의 id값", Object obj); // obj는 where절에 사용하는 값
-다중 레코드 반환
List\ list = sessiono.selectList("mapper의 id값"):
List\ list = sessiono.selectList("mapper의 id값", Object): // obj는 where절에 사용하는 값
int n = session.insert("namespace명.mapper의 id값");
int n = session.insert("namespace명.mapper의 id값", Object obj); // obj는 저장할 데이터
int n = session.update("namespace명.mapper의 id값");
int n = session.update("namespace명.mapper의 id값", Object obj); // obj는 수정할 데이터
int n = session.delete("namespace명.mapper의 id값");
int n = session.delete("namespace명.mapper의 id값", Object obj); // obj는 삭제할 데이터
public class MyBatisDeptMain {
public static void main(String[] args) {
// 1. SqlSession 열기
SqlSession session = MySqlSessionFactory.getSession();
// 2. SqlSession의 메서드를 이용해서 DeptMapper.xml과 연동
// DeptMapper.xml의 id값 과 resultType 값 <>
// 1) 전체 조회
List<DeptDTO> list = session.selectList("findAll");
// 2) 조건 조회 1
DeptDTO xxx = session.selectOne("findByDeptno", 10);
// 3) 조건 조회 2
DeptDTO yyy = new DeptDTO();
yyy.setDname("인사과");
yyy.setLoc("인천");
List<DeptDTO> list2 = session.selectList("findByDnameOrLoc", yyy );
// 4) 조건 조회 3 (hashMap 이용)
HashMap<String, String> map = new HashMap<>();
map.put("x", "인사과");
map.put("y", "서울");
List<DeptDTO> list3 = session.selectList("findByDnameOrLoc2", map );
// 3. 출력
System.out.println(list3);
// 4. close 작업
session.close();
}
}
public class MyBatisDeptMain2_DML {
public static void main(String[] args) {
// 1. SqlSession 열기
SqlSession session = MySqlSessionFactory.getSession();
// 데이터 저장
DeptDTO dto = new DeptDTO(3, "개발", "서울");
// 첫 번째엔 mapper 아이디
int n = session.insert("com.config.DeptMapper2.save", dto);
session.commit(); // ************
// 데이터 수정
DeptDTO dto2 = new DeptDTO(1, "백엔드개발", "서울");
int n2 = session.update("com.config.DeptMapper2.update", dto2);
session.commit();
// 데이터 삭제
String dname = "개발";
int n3 = session.delete("com.config.DeptMapper2.removeByDname", dname);
session.commit();
// 전체 조회
List<DeptDTO> list = session.selectList("com.config.DeptMapper2.findAll");
System.out.println(list);
// 4. close 작업
session.close();
}
}
insert into emp (empno, ename, sal)
values (10, 'a', 100), (20, 'b', 200), (),...;
<insert id="multiInsert" parameterType="arraylist">
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values
<foreach item="dto" collection="list" separator=",">
(#{dto.empno},#{dto.ename},#{dto.job},#{dto.mgr}, now(),
#{dto.sal},#{dto.comm},#{dto.deptno})
</foreach>
</insert>
<mappers>
<!-- DeptMapper.xml 등록 -->
<mapper resource="com/config/DeptMapper.xml"/>
<mapper resource="com/config/DeptMapper2.xml"/>
<mapper resource="com/config/EmpMapper.xml"/>
</mappers>
public class MyBatisEmpMain {
public static void main(String[] args) {
EmpDTO dto1 = new EmpDTO(1, "aaa1", "SALESMAN", 7369, null, 700, 0 , 30);
EmpDTO dto2 = new EmpDTO(2, "aaa2", "SALESMAN", 7369, null, 700, 0 , 30);
EmpDTO dto3 = new EmpDTO(3, "aaa3", "SALESMAN", 7369, null, 700, 0 , 30);
List<EmpDTO> list = Arrays.asList(dto1, dto2, dto3);
SqlSession session = MySqlSessionFactory.getSession();
int n = session.insert("com.config.EmpMapper.multiInsert", list);
session.commit();
System.out.println(n + "개가 저장됨");
session.close();
}
}
delete from emp
where sal IN ( 800, 1000, .. );
: 무조건 sal 전달됨
<delete id="remove" parameterType="arraylist">
delete from emp
where sal IN
<foreach item="x" collection="list" open="(" separator="," close=")">
#{x}
</foreach>
: sal 전달안될수도 있는 경우.
<delete id="remove" parameterType="arraylist">
delete from emp
<where>
<foreach item="x" collection="list" open="sal IN (" separator="," close=")">
#{x}
</foreach>
<where>
update emp
set sal = sal +100
where empno in (800, 1000,...);
<update id="update" parameterType="arraylist">
update emp
set sal = sal +100
<where>
<foreach item="X" collection="list" open="empno in (" separator = "," close=")">
#{X}
</foreach>
</where>
</update>
: 어떤 컬럼을 수정할지 잘 모르는 경우
update emp
set sal = 값
set ename = 값
set sal = 값, ename = 값
where empno = 값;
update emp
sal=#{sal},
ename=#{ename}
where empno = 값
job 이 'MANAGER' 인 경우 sal > 1500 조회
job 이 'SALESMAN' 인 경우 sal > 2500 조회
모두 아니면 sal > 3000 조회
select
from emp
<where>
<choose>
<when test="job == 'manager'"> sal>1500 </when>
<when test="job == 'salesman'"> sal>2500 </when>
<otherwise> sal>3000 </otherwise>
</choose>
</where>
select count(*)
from emp;
rs.next();
rs.getInt(1); // rs.getInt("cnt")
<select id="cnt" resultType="int">
int cnt =session.selectOne("cnt");
<select id="paging" resultType="EmpDTO">
select empno, ename, sal
from emp
order by empno desc
</select>
예>
int curPage = 2;
int perPage = 3; // 페이지당 보여줄 레코드 개수
int skip = (curPage-1) * perPage;
List<EmpDTO> list7 = session.selectList("com.config.EmpMapper.paging", null,
new RowBounds(skip, perPage));
cf) CDATA 섹션
: XML 문법
: CDATA (Character DATA) 표현식
<![CDATA[
SQL문
]]>
<!-- 참고 -->
> : >
< : <
공백:
" : "