DB
-----codes테이블-----
create table codes (
code number not null primary key
,gid number not null
,name varchar2(100) not null
);
-----codes 시퀀스-----
create sequence codes_seq
increment by 1
start with 1
minvalue 1
maxvalue 99999
nocycle
noorder
cache 20;
dispatcher-servlet.xml
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="1"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/" p:suffix=".jsp"/>
pom.xml (lombok, 오라클설정)
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- 오라클 설정 start -->
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
<!-- 오라클 설정 end -->
</repositories>
<dependencies>
<!-- 오라클 설정 start -->
<dependency>
<groupId>ojdbc</groupId>
<artifactId>ojdbc</artifactId>
<version>6-11</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/ojdbc6.jar</systemPath>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- 오라클 설정 end -->
context-datasource.xml
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">
<!-- 테스트 실행용 -->
<!-- <jdbc:embedded-database id="dataSource" type="HSQL"> -->
<!-- <jdbc:script location= "classpath:/db/sampledb.sql"/> -->
<!-- </jdbc:embedded-database> -->
<!-- oracle (POM에서 commons-dbcp, ojdbc(라이센스 사항으로 별도로 배포되지 않음) 관련 라이브러리 설정)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:example" />
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
<!-- hsql (테스트용 메모리 DB)
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="net.sf.log4jdbc.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:hsqldb:hsql://localhost/sampledb"/>
<property name="username" value="sa"/>
</bean>
-->
<!-- Mysql (POM에서 commons-dbcp, mysql-connector-java 관련 라이브러리 설정 )
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/example" />
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
-->
</beans>
ojdbc6.jar 파일 추가
sql-map-config 리소스추가
codeWrite.jsp
- 저장버튼에 onclick 속성을 사용해서 자바스크립트로 유효성검사를 해준다.
- 자바스크립트 == 에 주의
<script type="text/javascript">
function fn_submit() {
if(document.frm.name.value==""){
alert("코드명을 입력해주세요.");
document.frm.name.focus();
return false;
}
document.frm.submit();
}
</script>
코드명을 입력해줘야 action="codeWriteSave.do"을 타고 submit 전송
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
table {
width: 400px;
border-collapse: collapse;
}
th td {
border: 1px solid #cccccc;
padding: 5px
}
</style>
<script type="text/javascript">
function fn_submit() {
if(document.frm.name.value==""){
alert("코드명을 입력해주세요.");
document.frm.name.focus();
return false;
}
document.frm.submit();
}
</script>
</head>
<body>
<table border="1">
<form name="frm" method="post" action="codeWriteSave.do">
<tr>
<th>분류</th>
<td>
<select name="gid">
<option value="1">Job(업무)</option>
<option value="2">Hobby(취미)</option>
</select>
</td>
</tr>
<tr>
<th>코드명</th>
<td>
<input type="text" name="name">
</td>
</tr>
<tr align="center">
<td colspan="2">
<button type="submit" onclick="fn_submit(); return false;">저장</button>
<button type="reset">취소</button>
</td>
</tr>
</form>
</table>
</body>
</html>
CodeVO
package egovframework.example.sample.service;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CodeVO {
private Integer code;
private Integer gid;
private String name;
}
sql-map-config.xml
경로 단순화 시킴
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="egovframework/sqlmap/example/sample/EgovSample_Sample_SQL.xml"/>
<sqlMap resource="egovframework/sample/Code_SQL.xml"/>
</sqlMapConfig>
Code.SQL.xml
시퀀스를 사용할때에는 codes_seq.NEXTVAL 이렇게 사용해준다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Code">
<typeAlias alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
<typeAlias alias="codeVO" type="egovframework.example.sample.service.CodeVO"/>
<insert id="codeDAO.insertCode">
<![CDATA[
insert into codes
values ( codes_seq.NEXTVAL
,#gid#
,#name#)
]]>
</insert>
</sqlMap>
CodeDAO
package egovframework.example.sample.service.impl;
import org.springframework.stereotype.Repository;
import egovframework.example.sample.service.CodeVO;
import egovframework.rte.psl.dataaccess.EgovAbstractDAO;
@Repository("codeDAO")
public class CodeDAO extends EgovAbstractDAO{
public String insertCode(CodeVO vo) throws Exception {
return (String) insert("codeDAO.insertCode", vo);
}
}
CodeService
package egovframework.example.sample.service;
public interface CodeService {
String insertCode(CodeVO vo) throws Exception;
}
CodeServiceImpl
package egovframework.example.sample.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import egovframework.example.sample.service.CodeService;
import egovframework.example.sample.service.CodeVO;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import lombok.extern.slf4j.Slf4j;
@Service("codeService")
@Slf4j
public class CodeServiceImpl extends EgovAbstractServiceImpl implements CodeService {
**@Resource(name = "codeDAO")**
**private CodeDAO codeDAO;**
@Override
public String insertCode(CodeVO vo) throws Exception {
log.info("-----codeService insertCode-----");
return codeDAO.insertCode(vo);
}
@Override
public List<?> selectCodeList(CodeVO vo) throws Exception {
log.info("-----codeService selectCode-----");
return codeDAO.selectCodeList(vo);
}
@Override
public int selectTotalCount() {
return codeDAO.selectTotalCount();
}
}
CodeController
package egovframework.example.sample.web;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import egovframework.example.sample.service.CodeService;
import egovframework.example.sample.service.CodeVO;
import lombok.extern.slf4j.Slf4j;
@Controller
@Slf4j
public class CodeController {
@Resource(name="codeService")
private CodeService codeService;
@RequestMapping(value = "/codeWrite.do")
public String codeWrite() {
log.info("-----codeWriteView-----");
return "code/codeWrite";
}
@RequestMapping(value = "codeWriteSave.do", method = RequestMethod.POST)
public String codeWriteSave(CodeVO vo) throws Exception {
log.info("-----saveCode-----");
String result = codeService.insertCode(vo);
// 정상적으로 insert시 null
log.info("@#@#===>result"+result);
return "";
}
}
그룹명에서 gid값에 따라 다른 문자열을 출력할때 서버쪽, 프론트쪽 2가지 방법이 있다.
서버쪽(DB)에서 값을 변경해주는것이 속도 측면에서 훨씬 더 빠르다.
gid는 insert에서만 사용되기때문에 gid2를 새로만들어서 decode를 사용해줄 수 있다.
decode를 사용할때 별칭ㅇ(as gid2)
gid2는 셀렉트에서만 사용된다.
decode를 사용하려면 타입을 맞춰줘야하기때문에 gid2라는 컬럼을 하나 더 생성한다.
실무에서 많이 사용하는 방법
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Code">
<typeAlias alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
<typeAlias alias="codeVO" type="egovframework.example.sample.service.CodeVO"/>
<insert id="codeDAO.insertCode">
<![CDATA[
insert into codes
values ( codes_seq.NEXTVAL
,#gid#
,#name#)
]]>
</insert>
<select id="codeDAO.selectCodeList" resultClass="codeVO">
select code
,decode(gid,1,'job',2,'hobby') as gid2
,name
from codes
</select>
</sqlMap>
package egovframework.example.sample.service;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CodeVO {
private Integer code;
private Integer gid;
private String name;
private String gid2;
}
decode로 쿼리를 변경하면 db에 정의된 gid의 타입이 integer이기 때문에
오렌지박스안에 있는 이름과 VO와 매핑 된다.
컬럼명과 매핑되는것이 아님!
빠진 번호도 1234로 변경하려면?
쿼리에 rownum을 사용하거나, 프론트단에서 변경할 수 있다.
- 프론트단
<table border="1">
<caption>코드목록</caption>
<tr>
<th>번호</th>
<th>그룹명</th>
<th>코드명</th>
</tr>
<c:set var="count" value="1"/>
<c:forEach items="${resultList}" var="result" varStatus="status">
<tr align="center">
<%-- <td>${result.code}</td> --%>
<td>${count}</td>
<td>${result.gid}</td>
<td>${result.name}</td>
</tr>
<c:set var="count" value="${count+1}"/>
</c:forEach>
</table>
Code_SQL.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Code">
<typeAlias alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>
<typeAlias alias="codeVO" type="egovframework.example.sample.service.CodeVO"/>
<insert id="codeDAO.insertCode">
<![CDATA[
insert into codes
values ( codes_seq.NEXTVAL
,#gid#
,#name#)
]]>
</insert>
<select id="codeDAO.selectCodeList" resultClass="codeVO">
select code
,decode(gid,1,'job',2,'hobby') as gid2
,name
from codes
</select>
<select id="codeDAO.selectTotalCount" resultClass="int">
select count(code) from codes
</select>
</sqlMap>
여기서 forward를 했을때는 404가 뜨고, redirect는 되는거다
리다이렉트는 객체를 초기화하기때문에 get 으로 받아도 괜찮은데
forward는 객체가 post타입인걸 그대로 갖고가는데 받을 때 get으로 받으니 에러가 생긴것,
forward 방식은 서버 내에서 요청을 전달하기 때문에, 요청이 원래의 HTTP 메서드 방식(POST) 그대로 유지됩니다. 따라서 POST 요청이 forward로 전달되어 GET 방식을 처리하는 핸들러 메서드(codeList.do)로 이동하면, GET 방식으로 처리하려 하면서 오류가 발생할 수 있습니다. 이때 오류가 발생하는 이유는 POST 요청을 처리하기 위해 필요한 데이터가 초기화되지 않은 상태로 GET 방식으로 처리를 시도하므로 발생하는 것입니다.
한편, redirect 방식은 클라이언트에게 새로운 URL로 요청하도록 지시하는 방식입니다. 클라이언트는 새로운 GET 요청을 보내게 되고, 이는 서버에서 새로운 요청으로 처리됩니다. 이때 클라이언트와 서버 간의 요청-응답 과정이 일어나며, 서버는 클라이언트의 요청을 받을 때 새로운 객체를 초기화하여 처리합니다. 따라서 redirect 방식을 사용하면 객체 초기화와 관련된 문제가 발생하지 않습니다.
따라서, forward 방식은 POST 요청을 전달할 때 객체 초기화가 이루어지지 않아 오류가 발생할 수 있으며, redirect 방식은 클라이언트에게 새로운 요청을 보내므로 객체 초기화가 이루어져 문제가 없습니다.
'백 > 전자정부프레임워크' 카테고리의 다른 글
전자정부 프레임워크6 - 간단한 게시판 만들기(1) (0) | 2023.07.19 |
---|---|
jsp에서 글 수정시 콤보박스 데이터 받아오는 법 (0) | 2023.07.19 |
전자정부 프레임워크4- update (0) | 2023.07.17 |
전자정부 프레임워크3- select, delete (0) | 2023.07.14 |
전자정부 프레임워크, ibatis에 대해 궁금한 점 gpt에게 묻기 (0) | 2023.07.14 |