새소식

Daily Record

7월 2주차 학습 내용 정리

Spring - RedirectAttributes, Responsebody

 

@Controller
public class SampleController4 {

	// localhost/doE -> localhost/doF로 redirect -> doF.jsp로 forward

	@RequestMapping(value = "/doE", method = RequestMethod.GET)
	public String doE(RedirectAttributes rttr) { 
		rttr.addFlashAttribute("msg", "hello");
		// 게시판 실습 때 Controller에서 session.setAttribute("msg", "hello")
		// -> View에서 session.removeAttribute("msg") 했던 것과 같음
		// localhost/doE 로 doF.jsp 화면이 나온 이후 새로고침하면 msg값이 사라짐

		return "redirect:/doF";
	}

	@RequestMapping(value = "/doF", method = RequestMethod.GET)
	public void doF() { 

	}

}

 

@Controller
public class SampleController5 {

	// JSONObject와 같은 기능
	// localhost/doJSON
	@RequestMapping(value = "/doJSON", method = RequestMethod.GET)
	@ResponseBody // JSON형식 사용을 위한 애너테이션
	public ProductVo doJSON() {
		ProductVo vo = new ProductVo("샘플 상품", 30000);
		return vo; 
		// 그냥 return하면 원래 사용하던 데이터 리턴,
		// ResponseBody를 사용하면 JSON 타입으로 리턴함
	}
	
	// JSONArray와 같은 기능
	// localhost/doJSONList
	@RequestMapping(value = "/doJSONList", method = RequestMethod.GET)
	@ResponseBody 
	public List<ProductVo> doJSONList() {
		List<ProductVo> list = new ArrayList<>();
		for (int i = 1; i <= 10; i++) {
			ProductVo vo = new ProductVo("샘플 상품 - " + i, (i * 10000));
			list.add(vo);
		}
		return list; 
	}
}

 

 

 

Spring - 데이터베이스 연동(mybatis)

 

@Repository // Spring에게 이 객체가 Dao라는 것을 알림
public class MemberDaoImpl implements MemberDao {
	
	private static String NAMESPACE = "com.kh.ex01.memberMapper.";
	
	@Autowired
	private SqlSession sqlSession; // root-context.xml에 등록해놓음

	@Override
	public String readTime() throws Exception {
		String time = sqlSession.selectOne(NAMESPACE + "getTime"); 
		// 결과가 하나일 때 select"One" 사용
		// com.kh.ex01.memberMapper.getTime과 같음
		
		return time;
	}

	@Override
	public void createMember(MemberVo vo) throws Exception {
		int count = sqlSession.insert(NAMESPACE + "insertMember", vo);
		// vo를 memverMapper.xml에 넘겨줘야함
		// memberMapper.xml에 넘겨줘야할 파라미터타입이 있는 경우 insert(string, object) 사용
		System.out.println("count:" + count);
	}

	@Override
	public MemberVo readMember(String userid) throws Exception {
		MemberVo memberVo = sqlSession.selectOne(
				NAMESPACE + "selectMember", userid);
		
		return memberVo;
	}

	@Override
	public MemberVo readWithPw(String userid, String userpw) 
			throws Exception {
		MemberVo memberVo = new MemberVo();
		memberVo.setUserid(userid);
		memberVo.setUserpw(userpw);
		memberVo = sqlSession.selectOne(
				NAMESPACE + "selectMemberWithPw", memberVo);
		return memberVo;
	}

}

 

public interface MemberDao {

	public String readTime() throws Exception;
	
	public void createMember(MemberVo vo) throws Exception;
	
	public MemberVo readMember(String userid) throws Exception;
	
	public MemberVo readWithPw(String userid, String userpw) throws Exception;
	
}

 

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class MemberVo {
	String userid;
	String userpw;
	String username;
	String email;
	Timestamp regdate;
	Timestamp updatedate;
}

 

 

 - memberMapper.xml

<?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="com.kh.ex01.memberMapper">
	<!-- com.kh.ex01.memberMapper.getTime -->
	<!-- 실행할 쿼리문장 작성 -->
	<select id="getTime" resultType="string">
		select to_char(sysdate, 'RRRR/MM/DD HH24:MI:SS') from dual
	</select>
	
	<!-- vo의 createMember -->
	<insert id="insertMember" parameterType="com.kh.ex01.vo.MemberVo">
	<!-- parameterType은 생략해도 됨(파라미터명을 동일하게 작성해야 함) -->
		insert into tbl_member(userid, userpw, username, email)
		values
			(#{userid}, #{userpw}, #{username}, #{email, jdbcType=VARCHAR})
		<!-- com.kh.ex01.vo.MemberVo.userid -->
		<!-- jdbcType : null값으로 들어왔을 때 처리할 타입을 작성 -->
	</insert>
	
	<!-- readMember -->
	<select id="selectMember" resultType="com.kh.ex01.vo.MemberVo">
		select * from tbl_member 
		where userid = #{userid}
	</select>
	
	<!-- readWithPw -->
	<select id="selectMemberWithPw" resultType="com.kh.ex01.vo.MemberVo">
		select * from tbl_member
		where userid = #{userid} and userpw = #{userpw}
	</select>
</mapper>

 

 - root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
	<!-- Connection Pool 등록 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" 
			value="oracle.jdbc.driver.OracleDriver"/>	
		<property name="url" 
			value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="username" value="spring"/>
		<property name="password" value="1234"/>
	</bean>
	
	<!-- 커넥션풀로 설정파일 읽는 빈 등록 -->
	<bean id="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/> <!-- ref="커넥션풀 아이디" -->
		<property name="mapperLocations" 
			value="classpath:mappers/*Mapper.xml"/>
	</bean>
	
	<!-- try~catch 할 빈 등록 -->
	<bean id="sqlSessionTemplate"
		class="org.mybatis.spring.SqlSessionTemplate"
		destroy-method="clearCache">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>	
	</bean>
</beans>

 

 

Spring - 게시판 CRUD, 페이징, 검색

 

1. java 코드

 - BoardDao.java

@Repository
public class BoardDao {
	
	private final String NAMESPACE = "com.kh.ex02.BoardMapper.";

	@Autowired
	private SqlSession sqlSession;
	
	public void create(BoardVo boardVo) throws Exception {
		sqlSession.insert(NAMESPACE + "create", boardVo);
	}

	public List<BoardVo> listAll(PagingDto pagingDto) throws Exception {
		List<BoardVo> list = sqlSession.selectList(
				NAMESPACE + "listAll", pagingDto);
		return list;
	}

	public BoardVo read(int bno) throws Exception {
		BoardVo boardVo = sqlSession.selectOne(NAMESPACE + "read", bno);
		return boardVo;
	}

	public void update(BoardVo boardVo) throws Exception {
		sqlSession.update(NAMESPACE + "update", boardVo);
	}

	public void delete(int bno) throws Exception {
		sqlSession.delete(NAMESPACE + "delete", bno);
	}
	
	public int getCount(PagingDto pagingDto) throws Exception {
		int count = sqlSession.selectOne(NAMESPACE + "getCount", pagingDto);
		return count;
	}

}

 

 

 - BoardVo.java

@Data
public class BoardVo {
	private int bno;
	private String title;
	private String content;
	private String writer;
	private Timestamp regdate;
	private int viewcnt;
}

 

 - BoardService.java

@Service // 서비스에 붙이는 애너테이션
public class BoardService {
	
	@Autowired
	private BoardDao boardDao;

	public void create(BoardVo boardVo) throws Exception {
		boardDao.create(boardVo);
	}

	public List<BoardVo> listAll(PagingDto pagingDto) throws Exception {
		List<BoardVo> list = boardDao.listAll(pagingDto);
		return list;
	}

	public BoardVo read(int bno) throws Exception {
		BoardVo boardVo = boardDao.read(bno);
		return boardVo;
	}

	public void update(BoardVo boardVo) throws Exception {
		boardDao.update(boardVo);
	}

	public void delete(int bno) throws Exception {
		boardDao.delete(bno);
	}
	
	public int getCount(PagingDto pagingDto) throws Exception {
		return boardDao.getCount(pagingDto);
	}

}

 

 - BoardController.java

@Controller
@RequestMapping("/board") 
// 클래스에 전체 경로 지정. 클래스 내 메서드에 지정한 requestmapping은 /board/xxx로 지정됨
public class BoardController {
	
	PagingDto tempDto = null;
	
	@Autowired
	private BoardService boardService;
	
	@RequestMapping(value = "/register", method = RequestMethod.GET)
	// localhost/board/register
	public void registGet() { // get방식으로 처리
		System.out.println("registGet() called");
	}
	
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	// localhost/board/register
	public String registPost(BoardVo boardVo, 
			RedirectAttributes rttr) throws Exception { // post방식으로 처리
	// 1. getter&setter가 있고 2. jsp에서 설정한 name과 이름이 같으면 자동으로 boardVo 데이터 처리됨
		
		System.out.println(boardVo);
		boardService.create(boardVo);
		rttr.addFlashAttribute("msg", "SUCCESS");
		
		return "redirect:/board/list";
	}
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String list(
//			@RequestParam(value = "page", defaultValue = "1") int page, 
			PagingDto pagingDto, Model model) throws Exception { 
		// @RequestParam은 생략해도 가능. 가독성을 위해 사용
		// value값이 넘어오지 않았다면 defaultValue 적용
		
		int count = boardService.getCount(pagingDto);
		
		System.out.println("pagingDto:" + pagingDto);
		pagingDto = new PagingDto(
				pagingDto.getPage(), pagingDto.getPerPage(), count, 
				pagingDto.getSearchType(), pagingDto.getKeyword());
		tempDto = pagingDto;
		System.out.println("pagingDto:" + pagingDto);
		List<BoardVo> list = boardService.listAll(pagingDto);
		model.addAttribute("list", list);
		model.addAttribute("pagingDto", pagingDto);
		return "board/list";
	}
	
	@RequestMapping(value = "/read", method = RequestMethod.GET)
	public String read(int bno, 
			Model model) throws Exception { // spring이 파라미터 값 자동으로 가져와줌 
		BoardVo boardVo = boardService.read(bno);
		model.addAttribute("boardVo", boardVo);
		System.out.println("pagingDto in read:" + tempDto);
		model.addAttribute("pagingDto", tempDto);
		return "board/read";
	}
	
	// 수정
	@RequestMapping(value = "/mod", method = RequestMethod.POST)
	public String update(BoardVo boardVo) throws Exception {
		boardService.update(boardVo);
		return "redirect:/board/read?bno=" + boardVo.getBno();
	}
	
	// 삭제
	@RequestMapping(value = "/delete", method = RequestMethod.GET)
	public String delete(int bno) throws Exception {
		System.out.println("pagingDto in delete:" + tempDto);
		boardService.delete(bno);
		if (tempDto != null) {
			return "redirect:/board/list?page=" + tempDto.getPage() 
			+ "&perPage=" + tempDto.getPerPage()
			+ "&searchType=" + tempDto.getSearchType()
			+ "&keyword=" + tempDto.getKeyword();
		} else {
			return "board/list";
		}
	}
}

 

 - PagingDto

@NoArgsConstructor
@Data
public class PagingDto {
	
	private int page = 1; 		// 현재 페이지
	private int startRow; 		// 시작 행번호(rownum between A and B에서 A에 해당)
	private int endRow; 		// 끝 행번호(rownum between A and B에서 B에 해당)
	private int startPage; 		// 페이지 리스트의 첫 페이지. 1 2 3 ... 9 10에서 1
	private int endPage; 		// 페이지 리스트의 마지막 페이지. 1 2 3 ... 9 10에서 10
	private int perPage = 10; 	// 한 페이지 당 게시글 수(게시글 n개씩 보기)
	private int totalCount; 	// 전체 데이터 개수
	private int totalPage; 		// 전체 페이지 수
	private final int PAGE_BLOCK_COUNT = 10; 
	private String searchType;
	private String keyword;
	
	public PagingDto(int page, int perPage, 
			int count, String searchType, String keyword) {
		this.page = page;
		this.perPage = perPage;
		this.totalCount = count;
		this.searchType = searchType;
		this.keyword = keyword;
		calc();
	}
	
	public void calc() {
		this.endRow = this.page * this.perPage;
		this.startRow = this.endRow - (this.perPage - 1);
		
		endPage = (int)(Math.ceil(page / (double)PAGE_BLOCK_COUNT)) * PAGE_BLOCK_COUNT;
		startPage = endPage - (PAGE_BLOCK_COUNT - 1);
		
		totalPage = (int)Math.ceil(totalCount / (double)perPage);
		if (endPage > totalPage) {
			endPage = totalPage;
		}
	}

}

 

2. xml 코드

 - BoardMapper.xml

<?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="com.kh.ex02.BoardMapper">
	<!-- 
		namespace 값은 다른 mapper와 겹치지 않는 이름으로 지어주면 됨.
		sql 쿼리 id가 중복될 때 namespace로 구분하는 용도
	 -->
	<!-- 글쓰기 -->
	<insert id="create">
		insert into tbl_board (bno, title, content, writer)
		values (seq_board_bno.nextval, #{title}, #{content}, #{writer})
		<!-- #{} : mybatis가 알 수 있는 데이터를 사용 --> 
	</insert>
	<!-- 전체조회 -->
	<!-- 페이징 - 한페이지에 해당하는 글 조회 -->
	<select id="listAll" resultType="BoardVo">
		select * 
		from (select rownum rnum, a.*
		      from (select * from tbl_board 
					<include refid="search"/>
		            order by bno desc) a)
		where rnum between #{startRow} and #{endRow}
	</select>
	
	<!-- 페이징 - 전체 글 개수 -->
	<select id="getCount" resultType="int">
		select count(*) from tbl_board
		<include refid="search"/>
	</select>
	
	<!-- 검색 조건 -->
	<sql id="search">
	 <if test="keyword != null">
		<choose>
       		<when test="searchType == 't'.toString()"> 
       		<!-- 여기서 ''안에 문자를 쓰면 char처리됨 -> toString() 필요 -->
         	 	where title like '%' || #{keyword} || '%'
       		</when>
       		<when test="searchType == 'c'.toString()">
         	 	where content like '%' || #{keyword} || '%'
       		</when>
       		<when test="searchType == 'w'.toString()">
          		where writer like '%' || #{keyword} || '%'
       		</when>
       		<when test="searchType == 'tc'.toString()">
				where title like '%' || #{keyword} || '%'
				or content like '%' || #{keyword} || '%'
       		</when>
       		<when test="searchType == 'tcw'.toString()">
				where title like '%' || #{keyword} || '%'
				or content like '%' || #{keyword} || '%'
				or writer like '%' || #{keyword} || '%'
       		</when>
       	</choose>
       	</if>
	</sql>
		
	<!-- 특정글 조회 -->
	<select id="read" resultType="BoardVo">
		select * from tbl_board 
		where bno = #{bno}
	</select>
	
	<!-- 글 수정 -->
	<update id="update">
		update tbl_board
		set title = #{title},
			content = #{content},
			writer = #{writer}
		where bno = #{bno}
	</update>
	
	<!-- 글 삭제 -->
	<delete id="delete">
		delete from tbl_board
		where bno = #{bno}
	</delete>
	
</mapper>

 

 - mybatis-config.xml

<?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>
	<!-- 클래스/패키지 등의 단위로 별칭 지정. alias로 짧게 줄여쓸 수 있음 -->
	<typeAliases> 
		<!-- 클래스 단위 -->
<!-- 		<typeAlias type="com.kh.ex02.vo.BoardVo" -->
<!-- 			alias="BoardVo"/> -->
		<!-- 패키지 단위. 지정한 이름을 기준으로 지정. mapper작성 시 패키지명 제외하고 작성 가능 -->
		<package name="com.kh.ex02.vo"/>
	</typeAliases>
</configuration>

 

3. jsp 코드(bootstrap을 활용한 header와 footer 소스는 생략함)

 - list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ include file="/WEB-INF/views/include/header.jsp" %>

<script>
$(function() {
	var msg = "${msg}";
	if (msg == "SUCCESS") alert("처리가 완료되었습니다.");
	
	$(".page-link").click(function(e) {
		e.preventDefault(); // a태그의 동작을 막음
		var page = $(this).attr("href");
		$("input[name=page]").val(page); // input 중 name이 page인 것의 값을 page로 변경
		// 검색결과가 총 2페이지가 나왔을 때 1페이지에서 2페이지로 이동 시 바뀐 page를 반영하기 위함 
		var form = $("#frmPaging");
		form.submit();
	});
	
	// 수정, 삭제 후 목록으로 가면 보던 페이지 유지 - 수업 때 한 방법
	// form 태그로 파라미터를(전달할 데이터 전체) 다음 페이지로 전달
	// 내가 했던 방식과 차이를 보려면 드라이브에 업로드된 파일 참고
// 	$(".a_title").click(function(e) { 
// 		e.preventDefault();
// 		alert("ddd");
// 		var bno = $(this).attr("href");
// 		$("input[name=bno]").val(bno);
// 		$("#frmPaging").attr("action", "/board/read");
// 		$("#frmPaging").submit();
// 	});
	
	$("#perPage").change(function() { <%-- 값이 바뀔 때 --%>
		var perPage = $(this).val();
		console.log("perPage:", perPage);
		location.href="/board/list?perPage=" + perPage;
	});
	
	$("#btnSearch").click(function() {
		var searchType = $("#searchType").val();
		var keyword = $("#keyword").val();
		location.href="/board/list?searchType=" + searchType + "&keyword=" + keyword;
	});
	<%-- 여기에 쓰다 만 코드가 있어서 script 내 함수가 제대로 작동하지 않는 에러가 있었음 --%>
});
</script>
<style>
	ul.pagination {
		margin-left: 600px;
		margin-right: auto;
	}
	li.page-item {
 		display:block;	 
	}
</style>

<!-- 각 페이지 링크에 파라미터 설정(어떤 조건이든 페이징이 잘 되도록 하기 위함) -->

<%@ include file="/WEB-INF/views/include/frmPaging.jsp" %>

<div class="container-fluid">
	<div class="row">
		<div class="col-md-12">
			<div class="jumbotron">
				<h2>글 목록</h2><br>
				<p><a href="/board/register" class="btn btn-success">글쓰기</a></p>
				<%-- a링크로 이동 : get방식 --%>
			</div>
			
			<div class="row" style="margin-bottom:30px;">
				<!-- n줄씩 보기 -->
				<div class="col-md-2">
					<select name="perPage" id="perPage">
						<c:forEach var="v" begin="5" end="30" step="5">
							<option value="${v}"
								<c:if test="${pagingDto.perPage eq v}">
									selected
								</c:if> 
							>${v}줄씩 보기</option>
						</c:forEach>
					</select>
				</div>
					
				<!-- 검색 -->
				<div class="col-md-10">
					<select name="searchType" id="searchType">
						<option value="t"
							<c:if test="${pagingDto.searchType == 't'}">
								selected
							</c:if>
						>제목</option>
						<option value="c"
							<c:if test="${pagingDto.searchType == 'c'}">
								selected
							</c:if>
						>내용</option>
						<option value="w"
							<c:if test="${pagingDto.searchType == 'w'}">
								selected
							</c:if>
						>작성자</option>
						<option value="tc"
							<c:if test="${pagingDto.searchType == 'tc'}">
								selected
							</c:if>
						>제목+내용</option>
						<option value="tcw"
							<c:if test="${pagingDto.searchType == 'tcw'}">
								selected
							</c:if>
						>제목+내용+작성자</option>
					</select>
					<input type="text" name="keyword" id="keyword" 
						value="${pagingDto.keyword}">
					<button type="button" id="btnSearch">검색</button>
				</div>
				
			</div>
			
			<!-- 게시글 목록 -->
			<div class="row">
				<div class="col-md-12">
					<table class="table">
						<thead>
							<tr>
								<th>#</th>
								<th>제목</th>
								<th>작성자</th>
								<th>작성일</th>
								<th>조회수</th>
							</tr>
						</thead>
						<tbody>
							<c:forEach var="boardVo" items="${list}">
								<tr>
									<td>${boardVo.bno}</td>
									<td><a href="/board/read?bno=${boardVo.bno}">${boardVo.title}</a></td>
<%-- 									<td><a class="a_title" href="${boardVo.bno}">${boardVo.title}</a></td> --%>
									<td>${boardVo.writer}</td>
									<td>${boardVo.regdate}</td>
									<td>${boardVo.viewcnt}</td>
								</tr>
							</c:forEach>
						</tbody>
					</table>
				</div>
			</div>
		</div>
	</div>
	
	<!-- 페이징 -->
	<div class="row">
		<div class="col-md-12">
			<nav>
				<ul class="pagination justtify-content-center">
					<li class="page-item">
						<c:if test="${pagingDto.startPage != 1}">
							<a class="page-link" href="${pagingDto.startPage - 1}">&laquo;</a>
						</c:if>
					</li>
					<c:forEach var="v" begin="${pagingDto.startPage}" end="${pagingDto.endPage}">
						<c:choose>
							<c:when test="${pagingDto.page == v}">
								<li class="page-item active">
							</c:when>
							<c:otherwise>
								<li class="page-item">
							</c:otherwise>
						</c:choose>
						<a class="page-link" href="${v}">${v}</a>
					</li>
					</c:forEach>
					<li class="page-item">
						<c:if test="${pagingDto.endPage < pagingDto.totalPage}">
							<a class="page-link" href="${pagingDto.endPage + 1}">&raquo;</a>
						</c:if>
					</li>
				</ul>
			</nav>
		</div>
	</div><!-- /페이징 -->
</div>	

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

 - read.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<script>
$(function() {
	$("#btnModify").click(function() {
		<!-- prop: 값이 true/false. 단독으로 사용되는 경우 ex) checked / 그 외: attr  -->
		$(".readonly").prop("readonly", false);
		$("#btnModifyFinish").fadeIn(1000);
		$(this).fadeOut(1000);
	});
	
	$(".goToList").click(function(e) {
		e.preventDefault();
		if (${pagingDto != null}) {
			$("input[name=page]").val("${pagingDto.page}");
			$("input[name=perPage]").val("${pagingDto.perPage}");
			$("input[name=searchType]").val("${pagingDto.searchType}");
			$("input[name=keyword]").val("${pagingDto.keyword}");
			var form = $("#frmPaging");
			form.submit();
		} else {
			location.href="/board/list";
		}
	});
});
</script>
<%@ include file="/WEB-INF/views/include/frmPaging.jsp" %>

<div class="container-fluid">
	<div class="row">
		<div class="col-md-12">
			<div class="jumbotron">
				<h2>글 상세보기</h2><br>
<!-- 				<p><a href="/board/list" class="btn btn-success">글 목록으로 이동</a></p> -->
				<p><a class="btn btn-success goToList">글 목록으로 이동</a></p>
				<%-- a링크로 이동 : get방식 --%>
			</div>
			<form role="form" action="/board/mod" method="post">
				<input type="hidden" name="bno" value="${boardVo.bno}">
				<div class="form-group">
					<label for="title">제목</label> 
					<%-- lable for: id랑 같게 맞춤 --%>
					<input type="text" class="form-control readonly"
						id="title" name="title" value="${boardVo.title}" readonly/>
				</div>
				<div class="form-group">
					<label for="content">내용</label>
					<textarea class="form-control readonly" 
						id="content" name="content" readonly>${boardVo.content}</textarea>
				</div>
				<div class="form-group">
					<label for="writer">작성자</label>
					<input type="text" class="form-control readonly" 
						id="writer" name="writer" value="${boardVo.writer}" readonly/>
				</div>
				<button type="button" class="btn btn-warning" id="btnModify">
					수정
				</button>
				<button type="submit" class="btn btn-primary" 
					id="btnModifyFinish" style="display:none;">
					수정완료
				</button>
				<a href="/board/delete?bno=${boardVo.bno}" class="btn btn-danger">
					삭제
				</a>
			</form>
		</div>
	</div>
</div>	

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

 - register.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/views/include/header.jsp" %>

<div class="container-fluid">
	<div class="row">
		<div class="col-md-12">
			<div class="jumbotron">
				<h2>글쓰기 양식</h2><br>
				<p><a href="/board/list" class="btn btn-success">글 목록으로 이동</a></p>
				<%-- a링크로 이동 : get방식 --%>
			</div>
			<form role="form" action="/board/register" method="post">
				<div class="form-group">
					<label for="title">제목</label> 
					<%-- lable for: id랑 같게 맞춤 --%>
					<input type="text" class="form-control" 
						id="title" name="title"/>
				</div>
				<div class="form-group">
					<label for="content">내용</label>
					<textarea class="form-control" 
						id="content" name="content"></textarea>
				</div>
				<div class="form-group">
					<label for="writer">작성자</label>
					<input type="text" class="form-control" 
						id="writer" name="writer"/>
				</div>
				<button type="submit" class="btn btn-primary">
					작성완료
				</button>
			</form>
		</div>
	</div>
</div>	

<%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

 - frmPaging.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!-- 각 페이지 링크에 파라미터 설정(어떤 조건이든 페이징이 잘 되도록 하기 위함) -->
<form id="frmPaging" action="/board/list" method="get">
	<input type="hidden" name="bno" value="${param.bno}">
	<input type="hidden" name="page" value="${pagingDto.page}">
	<input type="hidden" name="perPage" value="${pagingDto.perPage}">
	<input type="hidden" name="searchType" value="${pagingDto.searchType}">
	<input type="hidden" name="keyword" value="${pagingDto.keyword}">
</form>

 

 - board.sql

create table tbl_board(
    bno number primary key,
    title varchar2(200) not null,
    content varchar2(4000),
    writer varchar2(50) not null,
    regdate timestamp default sysdate,
    viewcnt number default 0
);

select * from tbl_board;
Contents

Copied URL!

Liked this Posting!