MyBatis
MyBatis는 개발자가 관계형 데이터베이스와 더 쉽게 상호작용할 수 있도록 도와주는 객체-관계형 매핑(ORM) 솔루션을 제공하는 Java 기반 데이터 매핑 프레임워크
- XML 또는 주석을 사용하여 Java 개체를 SQL 문에 매핑하고 사용자 지정 SQL 쿼리를 쉽게 작성하고 실행가능
- 트랜잭션, 캐싱 및 동적 SQL 생성을 지원하므로 Java 애플리케이션에서 데이터베이스 작업을 위한 도구
기존
1단계~6단계 모두 구현
- 드라이버 로딩
- DB연결
Dto.id=DB.id dto.getId(rs.getString(2)) dto.getName(rs.getString(3))
- 쿼리준비
- 쿼리실행
- 쿼리결과받기
- DB닫기
MyBatis
작업지시서 (환경설정)
- configuration.xml : 전체적인 작업 메뉴얼
- sqlMapper.xml : SQL쿼리작성
- DB.properties : driver,url,user,password
- 작업자 생성(SqlMapConfig.java)
- sqlSessionFactory 객체 구해주는 작업
- sqlSession 객체 (insert(),selectList(),selectOne(),update(),delete()
DAO가 간단해짐 -> 처음부터 구조를 설계하고 시작
reader Resource -> configuration.xml을 읽는 resource 생성
Exploring Mapped SQL Statements
<?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="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
select태그
id: 태그의 이름
resultType : 결과를 담을 타입
Blog blog = session.selectOne(
"org.mybatis.example.BlogMapper.selectBlog", 101);
101 : 전달 파라미터
#{id}에 101전달
mybatis라이브러리
com.hk.config - SqlMapConfig
configuraion.xml을 읽는 reader를 Resources.getResourceAsReader를 통해 얻고
factoryBuilder로 부터 reader를 build하는 객체생성
sql패키지(3),config패지키는 다른 프로젝트를 할 때도 재사용
Dao에서 namespace private 멤버필드 생생 -> namespace + queryId를 사용하기 위해
sqlMapconfig상속받아 사용하려는 메서드에 sqlSessionFactory로부터 sqlSession객체를 구해서 쿼리실행
sql쿼리 BoardMapper.xml에 따로 저장
Dao반복
SqlSession sqlSession=null;
//1.sqlSessionFactory객체 구해야 됨 -> SqlSession객체를 쓸 수 있다
SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
//2.sqlSession객체 구하기
sqlSession=sqlSessionFactory.openSession();//autocommit =true로 설정
--->
SqlSession sqlSession=null;
sqlSession=getSqlSessionFactory().openSession(true);
글여러개 삭제 처리는 아래와 같은 형태로 IN을 사용
- SqlMapper에서 제공하는 foreach사용
- 배열을 map에 담아서 전달
<delete id="mulDel" parameterType="Map" > DELETE FROM HKBOARD WHERE SEQ IN <foreach collection="seqs" item="seq" separator="," open="(" close=")"> #{seq} </foreach> </delete>
Building SqlSessionFactory from XML
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
<?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>
<!-- DB접속정보 파일의 경로 설정 -->
<properties resource="sql/db.properties"/>
<!-- dto객체의 변수설정 -->
<typeAliases>
<typeAlias type="com.hk.dtos.HkDto" alias="hkDto"/>
</typeAliases>
<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="sql/BoardMapper.xml"/>
</mappers>
</configuration>
- 이때 property로 들어가는 value값(EL태그)은 db.properties파일안의 변수명과 일치해야한다
- 가독성을 위해서 typeAliases를 사용하는 것이 좋음
MyBatis실습
DB를 관리하는 프레임워크기 때문에 기존의 실습파일의 DAO쪽만 바꿔주면된다
자바소스관리 폴더에
sql패키지-db.properties
sql패키지-other-xml File-BoardMapper.xml
myBatis Building SqlSessionFactory from XML에서 불러오기
DB접속정보 파일의 경로 설정
- Configuration.xml에서 관련 부분 불러오기 - configuration하위 properties에 sql/db.properties추가
dto객체의 변수설정 - typeAliases사용
쿼리가 작성되어 있는 mapper.xml의 경로설정 - mapper를 통해 resourse 경로 설정
SqlMapConfig.java(환경세팅)
package com.hk.config;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class SqlMapConfig {
//작업을 하기 위한 객체를 선언
private SqlSessionFactory sqlSessionFactory;
//작업을 하기 위한 객체를 구하는 메서드
public SqlSessionFactory getSqlSessionFactory() {
//환경설정 내용이 작성되어 있는 파일의 경로 설정
String resource="sql/Configuration.xml";
try {
//Reader: 작업매뉴얼 , Resources : 작업메뉴얼을 만드는 객체
Reader reader=Resources.getResourceAsReader(resource);
sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactory;
}
}
HkDao.java
글목록조회
public List<HkDto> getAllList(){
List<HkDto> list=new ArrayList<>();
SqlSession sqlSession=null;
try {
//1.sqlSessionFactory객체 구해야 됨 -> SqlSession객체를 쓸 수 있다
SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
//2.sqlSession객체 구하기
sqlSession=sqlSessionFactory.openSession();//autocommit =true로 설정
//3.쿼리실행
list=sqlSession.selectList(namespace+"getAllList");
} catch (Exception e) {
e.printStackTrace();
}finally {
sqlSession.close();
}
return list;
}
글상세조회
public HkDto getBoard(int seq){
HkDto dto=new HkDto();//row하나를 담을 객체
SqlSession sqlSession=null;
try {
sqlSession=getSqlSessionFactory().openSession(true);
dto=sqlSession.selectOne(namespace+"getBoard",seq);
} catch (Exception e) {
System.out.println("JDBC실패:해당클래스는 "+getClass());
e.printStackTrace();
} finally {
}
return dto;
}
글추가
public boolean insertBoard(HkDto dto) {
int count=0;
SqlSession sqlSession=null;
try {
sqlSession=getSqlSessionFactory().openSession(true);
count=sqlSession.insert(namespace+"insertBoard",dto);
} catch (Exception e) {
System.out.println("JDBC실패:해당클래스는 "+getClass());
e.printStackTrace();
}finally {
}
return count>0?true:false;//삼항연산자
}
글수정
public boolean updateBoard(int seq, String title , String content) {
int count=0;
SqlSession sqlSession=null;
Map<String,Object>map=new HashMap<>();
map.put("seq", seq);
map.put("title", title);
map.put("content", content);
try {
sqlSession=getSqlSessionFactory().openSession(true);
count=sqlSession.update(namespace+"updateBoard",map);
} catch (Exception e) {
System.out.println("JDBC실패:updateBoard():"+getClass());
e.printStackTrace();
}finally {
//기본타입 : 0 , 0.0 , 참조타입: null
}
return count>0?true:false;
}
글삭제
public boolean delBoard(String seq) {
int count=0;
SqlSession sqlSession=null;
try {
sqlSession=getSqlSessionFactory().openSession(true);
count=sqlSession.delete(namespace+"delBoard",seq);
} catch (Exception e) {
System.out.println("JDBC실패:delBoard():"+getClass());
e.printStackTrace();
}finally {
}
return count>0?true:false;
}
글여러개삭제
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="com.hk.board">
<select id="getAllList" resultType="hkDto">
SELECT SEQ, ID, TITLE, CONTENT, REGDATE FROM HKBOARD
ORDER BY REGDATE DESC
</select>
<select id="getBoard" parameterType="int" resultType="hkDto">
SELECT SEQ, ID, TITLE, CONTENT, REGDATE
FROM HKBOARD WHERE SEQ=#{seq}
</select>
<insert id="insertBoard" parameterType="hkDto">
INSERT INTO HKBOARD VALUES(null,#{id},#{title},#{content},SYSDATE())
</insert>
<update id="updateBoard" parameterType="Map">
UPDATE HKBOARD SET TITLE=#{title}, CONTENT=#{content},REGDATE=SYSDATE()
WHERE SEQ=#{seq}
</update>
<delete id="delBoard" parameterType="String" >
DELETE FROM HKBOARD WHERE SEQ=#{seq}
</delete>
</mapper>
- mapper는 파일의 위치를 나타내기 떄문에 정의를 미리 해두는 게 편함
- #{}괄호내부에 들어가는 것은 자바쪽에서 파라미터로 전달해준값을 의미
기타참고
- Dao에서 sql쿼리문에 값을 전달할때 두개 이상이면 Map객체를 생성해야한다
SqlSession객체에서 제공하는 메서드
- selectList("namespace"+DAO메서드",param): param(Map, DTO,int/string ) 값한개
- selectList("namespace"+DAO메서드",Map): 값여러개 한번에 보내기
BoardMapper.xml
param받을 때 #{id} , 이때 id라는 이름은 Map의 저장된 값의 key와 동일
동적 쿼리 (map에 담아서 전달)
자주쓰는 sql문 (BoardMapper.xml)
<sql id="isSeq"> WHERE SEQ=#{seq} </sql> <delete id="delBoard" parameterType="int" > DELETE FROM HKBOARD <include refid="isSeq"></include> </delete>
'back-end > 기타' 카테고리의 다른 글
(Python) 웹 크롤링 (0) | 2023.05.02 |
---|