기존에 수업 예제는 Mybatis와 MySQL을 연동했다.
Oracle의 프로시저 SQL을 배우면서 MyBatis와 연동하면 기존 MySQL보다 구문이 더 깔끔해 질 것이라고 했다.
기존의 모델은 위쪽의 모델이였다면, 이번엔 아래쪽의 모델로 작성해 볼 계획이다.
✅ 아래쪽의 모델은 개발이 아닌 DB에 중점을 맞추는 작업이다. 위쪽의 모델은 개발이 중점, 빠른 시간 내에 개발을 할 경우에 사용하도록 하고, 아래쪽의 모델은 DB 중점, 오랜 시간 개발해야 하는 프로젝트에 사용된다.
최종 프로젝트의 경우 위쪽으로 진행할 예정이다. 지금 이것은 그냥 스터디!
1. 오라클 접속 확인
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class OracleEx01 {
public static void main(String[] args) {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:xe";
String user = "hr";
String password = "hr";
Connection conn = null;
try {
Class.forName(driver);
System.out.println("jdbc driver 로딩 성공");
conn = DriverManager.getConnection(url, user, password);
System.out.println("오라클 연결 성공");
} catch (ClassNotFoundException e) {
System.out.println("jdbc driver 로딩 실패");
} catch (SQLException e) {
System.out.println("오라클 연결 실패");
}
/*접속 해제 처리*/
try {
conn.close();
System.out.println("연결 해제");
} catch (Exception e) {
System.out.println("해제 오류");
}
conn=null;
}
}
- MySQL과는 다르게 DB 정보가 없다.
- 기존 자신의 주소를 사용할 경우 localhost, 혹은 127.0.0.1 사용
- 포트 번호는 오라클 접속 시에 특별하게 건든 게 없다면 1521 사용
- xe는 SID를 의미
- SID는 sqlplus에서 select name from v$database; 명령어 치면 확인할 수 있다.
접속이 매우 잘 된다!
2. config.xml 수정
<?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>
<!-- Oracle 접속 정보를 지정한다. -->
<properties>
<property name="hostname" value="localhost" />
<property name="portnumber" value="1521" />
<property name="username" value="hr" />
<property name="password" value="hr" />
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@${hostname}:${portnumber}/xe" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 실행할 SQL문을 정의한 Mapper XML의 경로를 지정한다. -->
<mappers>
<mapper resource="study/java/myschool/mapper/DepartmentMapper.xml" />
<mapper resource="study/java/myschool/mapper/ProfessorMapper.xml" />
<mapper resource="study/java/myschool/mapper/StudentMapper.xml" />
</mappers>
</configuration>
- Oracle 접속 방법 확인한 예제처럼, 기존에 MySQL 접속 정보를 지우고 Oracle 접속 정보 설정해 준다.
3. MyBatisMyBatisConnectionFactory.java
package study.java.myschool;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisConnectionFactory {
//데이터베이스 접속객체
private static SqlSessionFactory sqlSessionFactory;
//XML에 명시된 접속 정보 읽어들인다
//클래스 초기화 블럭 : 클래스 변수의 복잡한 초기화에 사용
//클래스가 처음 로딩될 때 한번만 수행
static {
//접속 정보를 명시하고 있는 XML 경로 읽기
try {
Reader reader = Resources.getResourceAsReader("study/java/myschool/config.xml");
//selSessionFactory가 존재하지 않는다면 생성 -> DBHelper의 기능을 대체
if(sqlSessionFactory == null) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//데이터베이스 접속 객체를 통해 db 접속한 세션 리턴
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
이 상태로 Mapper를 건들이지 않고 select문이 들어간 조회 jsp 파일을 실행하게 되면,
java.sql.SQLSyntaxErrorException:ORA-00933: SQL 명령어가 올바르게 종료되지 않았습니다
에러가 발생하게 된다. 이때, 이 에러는 구문 에러로서 보통 MyBatis에서는 세미콜론(;) 때문에 발생한다.
Mapper에 있는 모든 SQL 구문에 세미콜론을 지우면 매우 정상 작동한다!
4. org.apache.ibatis.executor.ExecutorException:Error getting generated key or setting result to parameter object. org.apache.ibatis.executor.result.ResultMapException:Error attempting to get column #1 from result set. java.sql.SQLException:부적합한 변환이 요청됨.
insert 구문에서 발생한 내용인데, MyBatis 에러이다.
MySQL을 사용하면 자동 증가 Autoincrement를 사용하게 되는데, 그 기능에 맞게 MyBatis insert 설정시
이 기능을 사용하게 된다. insert 구문에 있는 이 옵션을 삭제해 줬더니 에러는 사라졌지만....
5. add는 됐지만 add 된 데이터를 불러올 수가 없다
add가 완료된 데이터의 dpetno를 파라미터로 받아와야하는데 읽어오질 않는다...
그리고 웃긴건 다시 리스트로 가면 또 추가는 되어있어서 select로는 조회가 된다..
그래서 삭제하려고 들어가서 삭제를 하려고 했더니
또 9903 ^^....
뭔가 했더니 이 프로젝트는 서로 테이블간의 참조키가 걸려있어서 department를 삭제하려면 연관된 student와 professor을 모두 삭제해야한다. student와 professor의 세미콜론을 모두 지워주도록 하자..
그랬더니 삭제가 깔끔하게 완료되었다.
6. add가 완료되었지만 add_ok에서 list로 안 넘어가는 상황 해결
프로그램 순서가 add.jsp 에서 추가될 정보들을 받고, add_ok.jsp에서 insert 작업을 완료한 다음, deptno 파라미터를 받아와서 list로 넘어가는 형식인데, add_ok에서 넘어가지 않는 것이, deptno를 파라미터로 못 받아오는 상황임을 확인했다.
보통 Oracle에서 sequence 객체에서 nextval 함수로 로 자동 일련번호 증가를 사용하게 되는데, 자동으로 추가된 PK의 값을 확인해야 하는 상황이 올 수 있다. 지금이 딱 그 상황!
이럴 때는 <SelectKey> 태그를 통해 PK의 값을 미리(BEFORE) SQL로 통해서 처리하고, 특정한 이름으로 보관하는 형식을 처리해야 한다.
<insert id="add_department"
parameterType="study.java.myschool.model.Department"
keyProperty="deptno">
<selectKey keyProperty="deptno" order="BEFORE" resultType="int">
select seq_department.nextval from dual
</selectKey>
<!-- "#{변수명}" 으로 표시된 곳에 Beans의 멤버변수가 치환된다. -->
INSERT INTO department (deptno, dname, loc) VALUES (${deptno}, #{dname}, #{loc})
</insert>
그러면 add_ok에서 막히지 않고 아주 잘 돌아가는 현상을 확인 할 수 있다.
'study > TIL🐥' 카테고리의 다른 글
ERP란? (0) | 2021.01.05 |
---|---|
하드디스크 연결 규격 (0) | 2021.01.05 |
컴퓨터 Memory (0) | 2020.12.29 |
MySQL의 마스코트는 왜 돌고래인가? (0) | 2020.12.28 |
파일시스템과 데이터베이스 (0) | 2020.12.28 |