2024. 7. 6. 23:17ㆍBE/Spring
0. pdf
읽고 정리하기.
1. ORM이란?
- Object-Relational Mapping
- 데이터베이스와 객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법이다.
2. MyBatis란?
Java Object와 SQL문 사이를 자동으로 Mapping하는 ORM framework.
SQL을 별도의 파일로 분리해서 관리하다.
SQL에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일하지 않아도 된다.
SQL을 전담하는 DBA와 협업이 원활하다.
새로운 DB 프로그래밍 패러다임에 대한 부담 없이, 익숙한 SQL을 그대로 이용하면서 JDBC 코드 작성의 불편함을 줄일 수 있다.
도메인 객체나 VO 객체를 중심으로 개발이 가능하다.
다양한 프로그래밍 언어를 지원한다.
3. 예시
MyBatis를 사용하기 위해서는 3 가지 설정 파일이 필요하다.
- MyBatis의 설정 파일 :
mybatis-config.xml
- SQL을 저장하는 파일 :
XXXMapper.xml
또는XXXMapper.java
- DB 연결을 위한 파일 :
dbinfo.properties
위 파일들은 src/main/resources/mapper/
디렉터리에 위치한다.
가. pom.xml
프로젝트에 MyBatis 라이브러리를 추가한다.
<!-- Maven을 이용하는 경우 -->
<!-- pom.xml -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
나. mybatis-config.xml
라이브러리를 넣은 후에, MyBatis 설정 파일(mybatis-config.xml
)을 만듭니다.
이 파일에는 데이터베이스 접속 정보와 SQL 맵핑 파일 위치를 넣습니다.
mybatis-config.xml
는 작성 순서가 바뀌면 안 된다.
<configuration>
<properties resource="com/company/mybatis/config/dbinfo.properties"/>
<typeAliases>
<typeAlias type="com.company.mybatis.model.MemberDto" alias="memberDto" />
</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="com/company/mybatis/config/MemberMapper.xml"/>
</mappers>
</configuration>
properties
: DB에 연결을 위한 정보. (ip, port, id, pwd 등)typeAliases
:XXXMapper.xml
에서dataType
으로 사용할 수 있는 별칭.environments
: 트랜잭션 관리와 커넥션 풀링을 위한 환경적인 설정을 나타낸다.mappers
: 사용할 SQL과 매핑 정의가 저장된XXXMapper.xml
파일을 등록한다.
다. dbinfo.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/insert_your_schema_name?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8
username=your_id
password=your_pwd
dbinfo.properties
에는 DB 연결을 위한 기본적인 정보를 저장한다.
라. Mapper.xml
마지막으로, SQL 맵핑 파일(MemberMapper.xml
)을 만듭니다.
이 파일에서는 SQL 질의와 그 결과를 연결할 자바 객체를 정의합니다.
<?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.company.mybatis.model.dao.MemberDao">
<insert id="joinMember" parameterType="memberDto">
insert into members (user_id, user_name, user_password, email_id, email_domain, join_date)
values (#{userId}, #{userName}, #{userPwd}, #{emailId}, #{emailDomain}, now())
</insert>
<select id="listMember" resultType="memberDto">
select user_id userId, user_name userName, user_password usePwd, email_id emailId, email_domain emailDomain, join_date joinDate
from members
</select>
</mapper>
namespace
: package + interface 추천.id
: method name 추천.resultType
: dto 추천.
Dto 멤버 변수 이름과 SQL의 column 이름을 일치시켜야 한다.
별칭을 사용하거나 처음부터 똑같이 설정한다.
하지만 별칭을 사용하는 것은 귀찮고, 처음부터 일치시키면 DB의 column 이름이 노출되어 보안에 좋지 않다.
<!-- resultMap 사용하는 방식 -->
<?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.company.mybatis.model.dao.MemberDao">
<resultMap type="memberDto" id="user">
<result column="user_id" property="userId"/>
<result column="user_name" property="userName"/>
<result column="user_password" property="userPwd"/>
<result column="email_id" property="emailId"/>
<result column="email_domain" property="emailDomain"/>
<result column="join_date" property="joinDate"/>
</resultMap>
<insert id="joinMember" parameterType="memberDto">
insert into members (user_id, user_name, user_password, email_id, email_domain, join_date)
values (#{userId}, #{userName}, #{userPwd}, #{emailId}, #{emailDomain}, now())
</insert>
<!--
<select id="listMember" resultType="memberDto">
select user_id userId, user_name userName, user_password usePwd, email_id emailId, email_domain emailDomain, join_date joinDate
from members
</select>
-->
<select id="listMember" resultMap="user">
select *
from members
</select>
</mapper>
그래서 resultMap
을 사용해서 맵핑을 한다.
#{}
와${}
의 차이점:
마. Mapper.java
public interface MemberMapper {
final String joinMember = "insert into members (user_name, user_id, user_password, email_id, email_domain, join_date) values (#{userName}, #{userId}, #{userPwd}, #{emailId}, #{emailDomain}, now())";
final String listMember = "select * from members";
@Insert(joinMember)
void join(MemberDto memberDto);
@Select(listMember)
@Results(value = {
@Result(property = "userId", column = "user_id"),
@Result(property = "userName", column = "user_name"),
@Result(property = "userPwd", column = "user_password"),
@Result(property = "emailId", column = "email_id"),
@Result(property = "emailDomain", column = "email_domain"),
@Result(property = "joinDate", column = "join_date")
})
List<MemberDto> list();
}
xml 대신에 Annotation 기반의 java 파일을 사용할 수 있다.
<!-- before -->
<mappers>
<mapper resource="com/company/mybatis/config/MemberMapper.xml" />
</mappers>
<!-- after -->
<mappers>
<mapper class="com.company.mybatis.config.MemberMapper"/>
</mappers>
mybatis-config.xml
도 수정해야 한다.
바. SqlSessionFactory
이제 MyBatis를 이용해 데이터베이스와 상호작용할 수 있다.
SqlSessionFactory
로 SqlSession
을 만들고, 이를 통해 SQL 질의를 실행한다.
public class SqlMapConfig {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "com/company/mybatis/config/mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
SqlSession
:AutoClosable
이 구현되어 있다.
사. Java code
// 사용하는 방법
public class MemberDaoImpl implements MemberDao {
private final String NAME_SPACE = "com.company.mybatis.model.dao.MemberDao";
@Override
public void joinMember(MemberDto memberDto) throws SQLException {
try(SqlSession sqlSession = SqlMapConfig.getSqlSession()){
sqlSession.insert(NAME_SPACE + ".joinMember", memberDto);
sqlSession.commit();
}
}
@Override
public List<MemberDto> listMember() throws SQLException {
try(SqlSession sqlSession = SqlMapConfig.getSqlSession()){
List<MemberDto> list = sqlSession.selectList(NAME_SPACE + ".listMember");
return list;
}
}
}
sqlSession.insert(NAME_SPACE + ".joinMember", memberDto);
: 첫 번째 인자 =mapper의 namespace
+id
MyBatis
는 내부적으로 JDBC를 사용하며, SQL 쿼리를 실행할 때는 항상PreparedStatement
를 사용한다.sqlSession.commit();
: 참고로 MyBatis의autocommit
기본값은false
다.
메서드 | 설명 |
selectList(String statement) | 주어진 SQL 질의를 실행하고 결과를 리스트로 반환한다. |
selectOne(String statement) | 주어진 SQL 질의를 실행하고 결과를 하나의 객체로 반환한다. |
insert(String statement) | 주어진 SQL 질의를 실행하고 삽입된 레코드의 수를 반환한다. |
update(String statement) | 주어진 SQL 질의를 실행하고 수정된 레코드의 수를 반환한다. |
delete(String statement) | 주어진 SQL 질의를 실행하고 삭제된 레코드의 수를 반환한다. |
commit() | 모든 SQL 질의 변경 사항을 데이터베이스에 영구적으로 반영한다. |
rollback() | 이전 commit() 이후의 모든 SQL 질의 변경 사항을 취소한다. |
사용한 MemeberDto
참고:
package com.company.mybatis.model;
public class MemberDto {
private String userId;
private String userName;
private String userPwd;
private String emailId;
private String emailDomain;
private String joinDate;
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;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getEmailDomain() {
return emailDomain;
}
public void setEmailDomain(String emailDomain) {
this.emailDomain = emailDomain;
}
public String getJoinDate() {
return joinDate;
}
public void setJoinDate(String joinDate) {
this.joinDate = joinDate;
}
@Override
public String toString() {
return "MemberDto [userId=" + userId + ", userName=" + userName + ", userPwd=" + userPwd + ", emailId="
+ emailId + ", emailDomain=" + emailDomain + ", joinDate=" + joinDate + "]";
}
}
'BE > Spring' 카테고리의 다른 글
[Spring] MyBatis-Spring module (0) | 2024.07.06 |
---|---|
[MyBatis] 동적 SQL (0) | 2024.07.06 |
[Spring] Connection Pool (0) | 2024.07.06 |
[Spring] File Upload & Download (0) | 2024.07.06 |
[Spring] ControllerAdvice (0) | 2024.07.06 |