[구로/가산디지털단지,자바개발자교육학원,스프링File Upload,Spring게시판교육학원.스프링프레임워크3/4 교육학원추천,Spring Framework 게시판 파일업로드, COS.JAR]스프링 게시판 만들기(새글 입력 + 파일 업로드)
1. 시작하기
- 이번에는 게시판 리스트 보기에서 “글쓰기” 버튼을 눌렀을 때 게시물울 입력하는 화면과 함께 글을 저장하는 부분을 개발하자.
2. 새글 입력을 위한 DAO쪽 클래스를 작성하자.
BoardDAO.java 인터페이스, SpringBoardDAO.java 클래스에 새 글 입력을 위한 insertBoard() 메소드를 추가하자.
소스 코드 중 빨강색 부분이 새 글 입력을 위해 추가된 부분
[BoardDAO.java]
package onj.board.dao;
import java.util.List;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import org.springframework.dao.DataAccessException;
public interface BoardDAO {
//게시물 리스트 보기
public List<BoardDTO> boardList() throws DataAccessException;
//게시물 본문 미리보기
public String preView(String seq) throws DataAccessException;
//게시물 본문 읽기
public BoardDTO readContent(String seq) throws DataAccessException;
//읽은 글의 조회수 1증가
public int updateReadCount(String seq) throws DataAccessException;
//Comment저장
public int insertComment(CommentDTO commentDTO) throws DataAccessException ;
//Comment조회
public List<CommentDTO> commentList(String seq) throws DataAccessException;
//게시글 입력
public int insertBoard(BoardDTO board) throws DataAccessException;
}
[SpringBoardDAO.java]
package onj.board.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class SpringBoardDAO implements BoardDAO {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// /게시판 전체 리스트 보기(list.html)
public List<BoardDTO> boardList() throws DataAccessException {
List<BoardDTO> boardList = null;
String sql = "select * from board";
boardList = jdbcTemplate.query(sql, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
BoardDTO board = new BoardDTO();
board.setSeq(rs.getInt("seq"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setTitle(rs.getString("title"));
board.setContent(rs.getString("content"));
board.setFileName(rs.getString("filename"));
board.setRegDate(rs.getString("regdate"));
board.setReadCount(rs.getInt("readcount"));
board.setReply(rs.getInt("reply"));
board.setReply_step(rs.getInt("reply_step"));
board.setReply_level(rs.getInt("reply_level"));
return board;
}
});
return boardList;
}
// 게시물 본문내용 미리보기(/preView)
public String preView(String seq) throws DataAccessException {
String sql = "select * from board where seq = ?";
String preContent = (String) jdbcTemplate.queryForObject(sql,
new Object[] { seq }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
return rs.getString("content");
}
});
return preContent;
}
// 게시판 상세보기, 게시글 읽기
public BoardDTO readContent(String seq) throws DataAccessException {
String sql = "select * from board where seq = ?";
BoardDTO boardDTO = (BoardDTO) jdbcTemplate.queryForObject(sql,
new Object[] { seq }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
BoardDTO board = new BoardDTO();
board.setSeq(rs.getInt("seq"));
board.setName(rs.getString("name"));
board.setPasswd(rs.getString("passwd"));
board.setTitle(rs.getString("title"));
board.setContent(rs.getString("content"));
board.setFileName(rs.getString("filename"));
board.setRegDate(rs.getString("regdate"));
board.setReadCount(rs.getInt("readcount"));
board.setReply(rs.getInt("reply"));
board.setReply_step(rs.getInt("reply_step"));
board.setReply_level(rs.getInt("reply_level"));
return board;
}
});
// 글 조회수 1증가
this.updateReadCount(new Integer(boardDTO.getSeq()).toString());
return boardDTO;
}
// 읽은 글의 조회수를 1증가
public int updateReadCount(String seq) throws DataAccessException {
String sql = "update board set readcount = nvl(readcount,0) + 1 where seq = ?";
Object[] obj = { seq };
return jdbcTemplate.update(sql, obj);
}
// 커맨트 입력
public int insertComment(CommentDTO commentDTO) throws DataAccessException {
String sql = "insert into comment_t(seq, name, comm) values (?, ?, ?)";
Object[] obj = { commentDTO.getSeq(), // 게시글순번
commentDTO.getName(), // 작성자
commentDTO.getComment() }; // 커맨트
return jdbcTemplate.update(sql, obj);
}
// 커맨트 조회
public List<CommentDTO> commentList(String seq) throws DataAccessException {
String sql = "select * from comment_t where seq = ?";
List<CommentDTO> commentList = jdbcTemplate.query(sql,
new Object[] { seq }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
CommentDTO commentDTO = new CommentDTO();
commentDTO.setName(rs.getString("name"));
commentDTO.setComment(rs.getString("comm"));
return commentDTO;
}
});
return commentList;
}
// 글쓰기
public int insertBoard(BoardDTO board) throws DataAccessException {
String sql = "insert into board values(board_seq.nextval , ? , ? , ? , ? , ? , sysdate , 0 , board_seq.currval , 0 , 0)";
if (board.getFileName() == null) {
Object[] obj = { board.getName(), board.getPasswd(),
board.getTitle(), board.getContent(), "" };
return jdbcTemplate.update(sql, obj);
} else {
Object[] obj = { board.getName(), board.getPasswd(),
board.getTitle(), board.getContent(), board.getFileName() };
return jdbcTemplate.update(sql, obj);
}
}
}
3. service 쪽 클래스를 만들어 보자.
소스 코드 중 빨강색 부분이 새 글 입력을 위해 추가된 부분
[BoardService.java]
소스 코드 중 빨강색 부분이 새 글 입력을 위해 추가된 부분
package onj.board.service;
import java.util.List;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
/*
* 게시판에서 구현할 기능을 인터페이스로 정의
*/
public interface BoardService {
//게시판 리스트 보기
public List<BoardDTO> boardList();
//게시물 미리보기
public String preView(String seq);
//게시판 본문 내용보기, 게시글 읽기
public BoardDTO readContent(String seq);
//커맨트 입력
public int insertComment(CommentDTO commentDTO);
//커맨트 조회
public List<CommentDTO> commentList(String seq);
//게시글 입력
public int insertBoard(BoardDTO board);
}
[SpringServiceImpl.java]
package onj.board.service;
import java.util.List;
import onj.board.dao.BoardDAO;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
public class BoardServiceImpl implements BoardService {
private BoardDAO boardDAO;
public void setBoardDAO(BoardDAO boardDAO) {
this.boardDAO = boardDAO;
}
//게시물 리스트 보기
public List<BoardDTO> boardList() {
return boardDAO.boardList();
}
//게시물 본문 내용 미리보기
public String preView(String seq) {
return boardDAO.preView(seq);
}
//게시글 읽기
public BoardDTO readContent(String seq) {
return boardDAO.readContent(seq);
}
//커맨트 입력
public int insertComment(CommentDTO commentDTO) {
return boardDAO.insertComment(commentDTO);
}
//커맨트 조회
public List<CommentDTO> commentList(String seq) {
return boardDAO.commentList(seq);
}
//게시글 입력
public int insertBoard(BoardDTO board) {
return boardDAO.insertBoard(board);
}
}
4. 이번에는 컨트롤러를 수정하자.
소스 코드 중 빨강색 부분이 새 글 입력을 위해 추가된 부분
[BoardMultiController.java]
package onj.board.controller;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
/*
* MultiActionController는 비슷하거나 관련있는 로직을 수행하는
* 다수의 액션을 가지고 있을 때 사용하는 컨트롤러
* 연관된 요청(Request)를 묶을 때 용이함
*/
public class BoardMultiController extends MultiActionController {
private BoardService boardService;
public void setBoardService(BoardService boardService) {
this.boardService = boardService;
}
// 게시판 리스트 보기, 페이징 기능은 구현 안함
public ModelAndView list(HttpServletRequest req, HttpServletResponse res)
throws Exception {
ModelAndView mv = new ModelAndView("list", "list",
boardService.boardList());
return mv;
}
// 게시글 읽기
public ModelAndView read(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
ModelAndView mav = new ModelAndView("read", "read",
boardService.readContent(seq));
// 해당 글의 커맨트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
}
// 커맨트쓰기
public ModelAndView comment(HttpServletRequest req, HttpServletResponse res) {
String seq = req.getParameter("seq");
CommentDTO commentDTO = new CommentDTO();
commentDTO.setSeq(seq);
commentDTO.setName(req.getParameter("name"));
commentDTO.setComment(req.getParameter("comment"));
boardService.insertComment(commentDTO);
return new ModelAndView("redirect:/read.html?seq=" + seq);
}
// 새글(게시글) 입력 화면
public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws Exception {
return new ModelAndView(“write”);"
}
// 새글(게시글) DB 입력
public ModelAndView writeok(HttpServletRequest req, HttpServletResponse res)
throws Exception {
MultipartRequest multi = new MultipartRequest(req, "c:\\java\\project\\onjboard1\\upload",
5 * 1024 * 1024, "euc-kr", newDefaultFileRenamePolicy());
Enumeration formNames = multi.getFileNames();
String formName = (String) formNames.nextElement();
String fileName = multi.getFilesystemName(formName);
String name = multi.getParameter("name");
String passwd = multi.getParameter("passwd");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, fileName);
boardService.insertBoard(board);
return new ModelAndView("redirect:/list.html");
}
}
5. 리스트 보기에서 글쓰기 버튼 클릭시 호출될 write.jsp를 작성하자.
[write.jsp]
<%@ page contentType="text/html; charset=euc-kr" language="java" errorPage="" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>게시물 쓰기</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script language="javascript" type="text/javascript">
function form_check(){
if(document.form.name.value == ""){
alert("이름을 입력하세요.");
document.form.name.focus();
return false;
}
if(document.form.title.value == ""){
alert("제목을 입력하세요.");
document.form.title.focus();
return false;
}
if(document.form.content.value == ""){
alert("내용을 입력하세요.");
document.form.content.focus();
return false;
}
if(document.form.passwd.value == ""){
alert("비밀번호를 입력하세요.");
document.form.passwd.focus();
return false;
}
document.form.submit();
}
function addFileForm(){
var tb1 = document.getElementById("file_table");
if(9 >= tb1.rows.length) {
var idx = getObj().parentElement.rowIndex + 1;
var trow= tb1.insertRow(idx);
var uploadOBJ="<input name='attatch' type='file' class='TEXT_FORM' id='f_id'><a onClick='javascript:addFileForm();'> 추가</a> <a onClick='javascript:deleteRow();'>삭제</a> ";
trow.insertCell(0).innerHTML = uploadOBJ;
} else {
alert("문서파일은 10개 이상 접수할 수 없습니다.");
return;
}
}
function getObj()
{
var obj = event.srcElement
while (obj.tagName !='TD') //TD가 나올때까지의 Object추출
{
obj = obj.parentElement
}
return obj
}
function deleteRow(){
var tb1 = document.getElementById("file_table");
var idx = getObj().parentElement.rowIndex;
if(tb1.rows.length-1 !=0){
var tRow = tb1.deleteRow(idx);
}else{
document.getElementById('f_id').select();
document.selection.clear();
}
}
</script>
</head>
<body>
<H3>오라클자바커뮤니티 프로그래밍 실무교육센터 스프링 게시판 글쓰기</H3>
<div style="width:600px;">
<div style="float:right;">
<!-- /writeok.html 요청의 경우 컨트롤로의 write 메소드가 실행되도록 매핑되어있다 -->
<form name="form" method="post" action="/onjboard1/writeok.html" enctype="multipart/form-data">
<table width="580" height="277" border="1" align="center">
<tr>
<td width="100">* 이 름</td>
<td width="580">: <input name="name" type="text" size="50">
</td>
</tr>
<tr>
<td>* 제 목</td>
<td>:
<input name="title" type="text" size="50"></td>
</tr>
<tr align="center">
<td colspan="2"><textarea name="content" cols="80" rows="10"></textarea></td>
</tr>
<tr>
<td>* 파 일 :</td>
<td><table id="file_table">
<tr>
<td>
<input name="attatch" type="file" class="TEXT_FORM" id="f_id"><a OnClick="javascript:addFileForm();"> 추가</a> <a OnClick="javascript:deleteRow();">삭제</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>* 비밀번호</td>
<td>:
<input type="password" name="passwd"></td>
</tr>
<tr>
<td> </td>
<td><input type="button" name="Submit" value="쓰기" onclick="form_check();">
<input type="button" name="Submit2" value="취소" onclick="history.back();"></td>
</tr>
</table>
</div>
</div>
</form>
</body>
</html>
6. list.jsp 맨 아래 부분 글쓰기 버튼 링크 주소를 변경하자.
[list.jsp]
<%@ page contentType="text/html; charset=euc-kr" language="java" errorPage="" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>오라클자바커뮤니티 프로그래밍 실무학원</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<style type="text/css">
#layer1{
position:absolute;
padding:5px;
filter:alpha(opacity=50);
width:250px; height:150px;
background-color:white;
border:2px #000000 dotted;
visibility:hidden;
}
</style>
<script language="javascript" type="text/javascript" src="/onjboard1/js/createXMLHttpRequest.js"></script>
<script type="text/javascript">
var xmlHttp;
var xmlDoc;
var message;
function contentprev(seq){
var url = "preView?seq="+seq; //미리보기 서블릿 호출
xmlHttp = createXMLHttpRequest();
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.open("get" , url , true);
xmlHttp.send(null);
}
function handleStateChange(){
if(xmlHttp.readyState == 4){
if(xmlHttp.status == 200){
xmlDoc = xmlHttp.responseText;
document.getElementById("layer1").innerHTML = xmlDoc;
}
}
}
function showlayer(id){
if(document.all)
document.all[id].style.visibility="visible";
else if(document.layers)
document.layers[id].style.visibility="visible";
}
function hidelayer(id){
if(document.all)
document.all[id].style.visibility="hidden";
else if(document.layers)
document.layers[id].style.visibility="hidden";
}
function movetip() {
layer1.style.pixelTop=event.y+document.body.scrollTop+10;
layer1.style.pixelLeft=event.x+document.body.scrollLeft+10;
}
document.onmousemove=movetip;
</script>
</head>
<body>
<div id="layer1">
게시물 본문 미리 보기
</div>
<div style="width:500px;">
<div style="float:right;">
<H3>오라클자바커뮤니티 프로그래밍 실무교육센터 스프링 게시판</H3>
<h5>총 ${list.size()}건</h5>
<table width="600" border="1" align="left">
<tr align="left">
<td width="10%" align="center">번호</td>
<td width="40%" align="center">제목</td>
<td width="20%" align="center">이름</td>
<td width="20%" align="center">날짜</td>
<td width="10%" align="center">조회</td>
</tr>
<!-- list를 가져와서 board라 명명 후 개 수 만큼 반복 -->
<c:forEach var="board" items="${list}">
<tr>
<td align="center">
<c:if test="${board.reply_step == 0}">
${board.seq}
</c:if>
<c:if test="${board.reply_step != 0}">
</c:if>
</td>
<td> <!-- 게시물은 덧글에 따른 번호와 덧글 존재 유무로 정렬됨 -->
<c:choose>
<c:when test="${board.reply_step != 0}"><!-- 게시글이 덧글일 경우 -->
<c:forEach var="i" begin="1"end="${board.reply_level}" step="1"><!-- 레벨의 수만큼 글을 뒤로 민다 -->
</c:forEach>
<a href="read.html?seq=${board.seq}" onmouseover="contentprev('${board.seq}');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title}</a>
<!-- 마우스를 올리면 게시물 번호에 따른showlayer(게시물 미리보기 창)가 실행됨 -->
</c:when>
<c:when test="${board.reply_step == 0}">
<a href="read.html?seq=${board.seq}" onmouseover="contentprev('${board.seq}');showlayer('layer1');" onmouseout="hidelayer('layer1');">${board.title}</a>
</c:when>
</c:choose>
</td>
<td align="center">${board.name}</td>
<td align="center">${board.regdate}</td>
<td align="center">${board.readCount}</td>
</tr>
</c:forEach>
<tr>
<td align="center"><input type="button" value="글쓰기" onclick="location.href='write.html'"></td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
</div>
</div>
</body>
</html>
7. action-servlet.xml을 수정하자.
소스 코드 중 빨강색 부분이 커멘트 조회, 입력 기능을 위해 추가된 부분
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<!-- 넘어오는 URL에 따라 컨트롤러에서 실행될 메소드 매핑 -->
<!-- PropertiesMethodNameResolver는 prop key로 넘어오는 url에 대해 실행할 컨트롤러의 메소드
정의 -->
<bean id="userControllerMethodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<!-- list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
<prop key="/list.html">list</prop>
<!-- read.html 요청이 오면 컨트롤러의 read 메소드 실행 -->
<prop key="/read.html">read</prop>
<!-- comment.html 요청이 오면 컨트롤러의 comment 메소드 실행 -->
<prop key="/comment.html">comment</prop>
<!-- writeok.html 요청이 오면 실행 -->
<prop key="/writeok.html">writeok</prop>
<!-- write.html 요청이 오면 메소드 실행 -->
<prop key="/write.html">write</prop>
</props>
</property>
</bean>
<!-- 뷰 리졸버 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- 컨트롤러 매핑 -->
<bean name="/list.html /read.html /comment.html /write.html /writeok.html" class="onj.board.controller.BoardMultiController">
<property name="methodNameResolver">
<ref local="userControllerMethodNameResolver" />
</property>
<property name="boardService">
<ref bean="boardService" />
</property>
</bean>
</beans>
실행결과 및 현재까지 만들어진 이클립스 구조
(게시판 리스트보기 + 게시물 본문내용 미리 보기 + 게시글 상세보기 + 커멘트기능 + 글쓰기)
:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
[write.jsp:최재명]
<%@ page contentType="text/html; charset=euc-kr" %>
<%@ taglib prefix="c" uri="
http://java.sun.com/jsp/jstl/core" %>
<
%@taglib uri="
http://www.springframework.org/tags/form" prefix="form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>게시물 쓰기</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script type="text/javascript" src="/onjboard/js/jquery-1.6.4.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
//add more file components if Add is clicked
$('#addFile').click(function() {
var fileIndex = $('#fileview tr').children().length;
$('#fileview').append(
'<tr><td>'+
' <input type="file" name="files['+ fileIndex +']" />'+
'</td></tr>');
});
});
function form_check(){
if(document.form.name.value == ""){
alert("이름을 입력하세요.");
document.form.name.focus();
return false;
}
if(document.form.title.value == ""){
alert("제목을 입력하세요.");
document.form.title.focus();
return false;
}
if(document.form.content.value == ""){
alert("내용을 입력하세요.");
document.form.content.focus();
return false;
}
if(document.form.passwd.value == ""){
alert("비밀번호를 입력하세요.");
document.form.passwd.focus();
return false;
}
document.form.submit();
}
function getObj()
{
var obj = event.srcElement
while (obj.tagName !='TD') //TD가 나올때까지의 Object추출
{
obj = obj.parentElement
}
return obj
}
function deleteRow(){
var tb1 = document.getElementById("file_table");
var idx = getObj().parentElement.rowIndex;
if(tb1.rows.length-1 !=0){
var tRow = tb1.deleteRow(idx);
}else{
document.getElementById('f_id').select();
document.selection.clear();
}
}
</script>
</head>
<body>
<H3>오라클자바커뮤니티 프로그래밍 실무교육센터 스프링 게시판 글쓰기</H3>
<div style="width:600px;">
<div style="float:right;">
<!-- /writeok.html 요청의 경우 컨트롤로의 write 메소드가 실행되도록 매핑되어있다 -->
<form:form method="POST" action="/onjboard/writeOk.html" name="form"
modelAttribute="uploadFile" enctype="multipart/form-data">
<table width="580" height="277" border="1" align="center">
<tr>
<td width="100">* 이 름</td>
<td width="580">
: <input name="name" type="text" size="50">
</td>
</tr>
<tr>
<td>* 제 목</td>
<td>
: <input name="title" type="text" size="50">
</td>
</tr>
<tr align="center">
<td colspan="2">
<textarea name="content" cols="80" rows="10"></textarea>
</td>
</tr>
<tr>
<td>* 비밀번호</td>
<td>
: <input type="password" name="passwd">
</td>
</tr>
<tr>
<td>* 첨부파일</td>
<td>
<table id="fileview">
<tr>
<td><input name="files[0]" type="file" /></td>
</tr>
<!-- tr>
<td><input name="files[1]" type="file" /></td>
</tr-->
</table>
</td>
</tr>
<!-- tr>
<td>
<input id="addFile" type="button" value="File Add" />
</td>
<td></td>
</tr-->
<tr>
<td> </td>
<td>
<input type="button" name="Submit" value="쓰기" onclick="form_check();">
<input type="button" name="Submit2" value="취소" onclick="history.back();">
</td>
</tr>
</table>
</div>
</div>
</form:form>
</body>
</html>
오라클자바커뮤니티교육센터, 개발자전문교육, 개인80%환급
www.oraclejavacommunity.com평일주간(9:30~18:10) 개강
(7/07)[기업100%환급]C#4.0,WinForm,ADO.NET프로그래밍(7/07)[기업100%환급]Spring ,MyBatis,Hibernate실무과정(7/07)[기업100%환급]자바기초에서 JDBC, Servlet/JSP까지 (7/07)[채용예정교육]오라클자바개발잘하는신입뽑기프로젝트,교육전취업확정(7/14)[기업100%환급]SQL기초에서 Schema Object까지(7/14)[기업100%환급]PL/SQL,ORACLE HINT,TUNING(7/14)[기업100%환급]안드로이드개발자과정평일야간(19:00~21:50) 개강
(7/01)닷넷(C#,Network,ADO.NET,ASP.NET)마스터과정(7/02)Spring3.X, MyBatis, Hibernate실무과정(7/03)웹퍼블리싱 마스터(7/10)JAVA,Network&WEB&Framework(자바기초에서웹스프링까지)(7/15)SQL기초에서실무까지(7/15)안드로이드개발자과정(7/15)MyBatis3.X, Hibernate4.X ORM실무과정(7/22)자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis까지주말(10:00~17:50) 개강
(7/05)자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis까지(7/05)SQL초보에서 Schema Object까지(7/12)MyBatis3.X, Hibernate4.X ORM실무과정(7/12)개발자를위한PLSQL,SQL튜닝,힌트(7/13)C#,ASP.NET마스터(7/19)Spring3.X, MyBatis, Hibernate실무과정(7/19)웹퍼블리싱 마스터(7/19)안드로이드개발자과정주말저녁(18:30~22:20) 개강
(7/19)JAVA,Network&WEB&Framework(8/09)SQL기초에서실무까지