2020년 8월 25일 화요일

스프링프레임워크MVC5, 마이바티스3.5, 오라클12.2 로그인, 게시판(페이징) 실습, Spring MVC5, MyBatis3.5, Oracle12.2, Login, Board Example

  

스프링프레임워크MVC5, 마이바티스3.5, 오라클12.2 로그인게시판(페이징실습, Spring MVC5, MyBatis3.5, Oracle12.2, Login, Board Example


http://ojc.asia/bbs/write.php?w=u&bo_table=LecSpring&wr_id=849&page=



 

n  실습환경

JDK1.8

STS 4.7.1

Spring-Webmvc 5.2.3

MyBatis 3.5

mybatis-spring 2.0

Lombok 1.16.16

Servlet API 3.1.0

Apache Tomcat 9

Oracle 12.2

n  실행화면

 

  

n  프로젝트 구조

 

 

n  DB 스키마(Oracle12.2에 scott 이라는 계정을 만들어 실행)

 

-- 아래는 오라클 12C 이상에서 작성된 스크립트 입니다.

DROP TABLE XUSER;

CREATE TABLE XUSER (

       EMAIL VARCHAR2(100) NOT NULL PRIMARY KEY,

       PASSWORD VARCHAR2(100) DEFAULT '1234'

);

 

DROP TABLE XBOARD;

CREATE TABLE XBOARD (

       ID NUMBER(10,0) GENERATED BY DEFAULT AS IDENTITY,

       WRITER VARCHAR2(100) DEFAULT NULL,

       TITLE VARCHAR2(255) DEFAULT NULL,

       CONTENT VARCHAR2(4000) DEFAULT NULL,

       REG_DATE DATE DEFAULT NULL,

       HIT_COUNT NUMBER(10,0) DEFAULT 0

);

 

INSERT INTO XUSER(EMAIL) VALUES('e1@google.com');

INSERT INTO XUSER(EMAIL) VALUES('e2@naver.com');

INSERT INTO XUSER(EMAIL) VALUES('e3@daum.com');

 

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE1', '내용1', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE2', '내용2', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE3', '내용3', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE4', '내용4', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE5', '내용5', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE6', '내용6', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE7', '내용7', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE8', '내용8', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE9', '내용9', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE10', '내용10', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE11', '내용11', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE12', '내용12', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE13', '내용13', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE14', '내용14', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE15', '내용15', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE16', '내용16', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE17', '내용17', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE18', '내용18', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE19', '내용19', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE20', '내용20', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE21', '내용21', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE22', '내용22', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE23', '내용23', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE24', '내용24', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE25', '내용25', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE26', '내용26', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE27', '내용27', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE28', '내용28', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE29', '내용29', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE30', '내용30', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE31', '내용31', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE32', '내용32', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE33', '내용33', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE34', '내용34', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE35', '내용35', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE36', '내용36', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE37', '내용37', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE38', '내용38', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE39', '내용39', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE40', '내용40', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE41', '내용41', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE42', '내용42', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE43', '내용43', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE44', '내용44', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE45', '내용45', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE46', '내용46', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE47', '내용47', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE48', '내용48', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE49', '내용49', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE50', '내용50', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE51', '내용51', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE52', '내용52', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE53', '내용53', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE54', '내용54', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE55', '내용55', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE56', '내용56', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE57', '내용57', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e2@naver.com', 'TITLE58', '내용58', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e1@google.com', 'TITLE59', '내용59', SYSDATE, 0);

INSERT INTO XBOARD( WRITER, TITLE, CONTENT, REG_DATE, HIT_COUNT) VALUES('e3@daum.com', 'TITLE60', '내용60', SYSDATE, 0);

 

COMMIT;

 

n  pom.xml

 

<project xmlns="http://maven.apache.org/POM/4.0.0"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

       <modelVersion>4.0.0</modelVersion>

       <groupId>board2</groupId>

       <artifactId>board2</artifactId>

       <version>0.0.1-SNAPSHOT</version>

       <packaging>war</packaging>

 

       <properties>

             <springframework-version>5.2.3.RELEASE</springframework-version>

             <oracle.version>12.2.0.1</oracle.version>

             <mybatis.spring.version>2.0.5</mybatis.spring.version>

             <mybatis.version>3.5.5</mybatis.version>

             <jstl.version>1.2</jstl.version>

             <servlets.version>3.1.0</servlets.version>

             <jsp.version>2.3.1</jsp.version>

       </properties>

 

       <dependencies>

             <dependency>

                    <groupId>org.springframework</groupId>

                    <artifactId>spring-context</artifactId>

                    <version>${springframework-version}</version>

             </dependency>

 

             <dependency>

                    <groupId>org.springframework</groupId>

                    <artifactId>spring-webmvc</artifactId>

                    <version>${springframework-version}</version>

             </dependency>

 

             <dependency>

                    <groupId>org.springframework</groupId>

                    <artifactId>spring-tx</artifactId>

                    <version>${springframework-version}</version>

             </dependency>

 

             <dependency>

                    <groupId>org.springframework</groupId>

                    <artifactId>spring-jdbc</artifactId>

                    <version>${springframework-version}</version>

             </dependency>

 

             <dependency>

                    <groupId>org.projectlombok</groupId>

                    <artifactId>lombok</artifactId>

                    <version>1.16.16</version>

                    <scope>provided</scope>

             </dependency>

 

             <dependency>

                    <groupId>com.oracle.jdbc</groupId>

                    <artifactId>ojdbc8</artifactId>

                    <version>${oracle.version}</version>

             </dependency>

 

             <dependency>

                    <groupId>org.mybatis</groupId>

                    <artifactId>mybatis-spring</artifactId>

                    <version>${mybatis.spring.version}</version>

             </dependency>

 

             <dependency>

                    <groupId>org.mybatis</groupId>

                    <artifactId>mybatis</artifactId>

                    <version>${mybatis.version}</version>

             </dependency>

 

             <dependency>

                    <groupId>javax.servlet</groupId>

                    <artifactId>javax.servlet-api</artifactId>

                    <version>${servlets.version}</version>

                    <scope>provided</scope>

             </dependency>

 

             <dependency>

                    <groupId>javax.servlet.jsp</groupId>

                    <artifactId>javax.servlet.jsp-api</artifactId>

                    <version>${jsp.version}</version>

                    <scope>provided</scope>

             </dependency>

            

             <dependency>

                    <groupId>javax.servlet</groupId>

                    <artifactId>jstl</artifactId>

                    <version>${jstl.version}</version>

             </dependency>

            

            

       </dependencies>

 

       <repositories>

             <repository>

                    <id>oracle</id>

                    <name>ORACLE JDBC Repository</name>

                    <url>https://maven.xwiki.org/externals/</url>

             </repository>

       </repositories>

 

       <build>

             <sourceDirectory>src</sourceDirectory>

             <plugins>

                    <plugin>

                           <artifactId>maven-compiler-plugin</artifactId>

                           <version>3.8.1</version>

                           <configuration>

                                 <source>1.8</source>

                                 <target>1.8</target>

                           </configuration>

                    </plugin>

                    <plugin>

                           <artifactId>maven-war-plugin</artifactId>

                           <version>3.2.3</version>

                           <configuration>

                                  <warSourceDirectory>WebContent</warSourceDirectory>

                           </configuration>

                    </plugin>

             </plugins>

       </build>

</project>

n  resources/jdbc.properties

오라클 접속 설정

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver

jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl

jdbc.username=scott

jdbc.password=tiger

n  WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">

  <display-name>board2</display-name>

 

  <context-param>

             <param-name>contextConfigLocation</param-name>

             <param-value>/WEB-INF/spring/root-context.xml</param-value>

       </context-param>

 

       <listener>

             <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

       </listener>

 

       <servlet>

             <servlet-name>appServlet</servlet-name>

             <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

             <init-param>

                    <param-name>contextConfigLocation</param-name>

                    <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>

              </init-param>

             <load-on-startup>1</load-on-startup>

       </servlet>

 

       <servlet-mapping>

             <servlet-name>appServlet</servlet-name>

             <url-pattern>/</url-pattern>

       </servlet-mapping>

 

       <error-page>

             <error-code>404</error-code>

             <location>/404.html</location>

       </error-page>

 

       <filter>

             <filter-name>encoding-filter</filter-name>

             <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

             <init-param>

                    <param-name>encoding</param-name>

                    <param-value>UTF-8</param-value>

             </init-param>

             <init-param>

                    <param-name>forceEncoding</param-name>

                    <param-value>true</param-value>

             </init-param>

       </filter>

 

       <filter-mapping>

             <filter-name>encoding-filter</filter-name>

             <url-pattern>/*</url-pattern>

       </filter-mapping>

</web-app>

n  WEB-INF/spring/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"

          xmlns:tx="http://www.springframework.org/schema/tx"

          xmlns:context="http://www.springframework.org/schema/context"

          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd

             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

 

       <!-- web.xml 정의된 ConterxtLoaderListener 로딩하는

                자바빈(부모컨텍스트) 정의

            DispatcherServlet 로딩하는 자바빈은 자식 컨텍스트임 -->

 

       <context:property-placeholder location="classpath:jdbc.properties" />

 

       <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

             <property name="driverClassName" value="${jdbc.driverClassName}" />

             <property name="url" value="${jdbc.url}" />

             <property name="username" value="${jdbc.username}" />

             <property name="password" value="${jdbc.password}" />

       </bean>

 

       <bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

             <property name="dataSource" ref="dataSource" />

             <property name="configLocation" value="classpath:/mybatis/mybatis-config.xml" />

             <property name="mapperLocations" value="classpath:/mybatis/mapper/**/*.xml" />

       </bean>

 

       <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

             <property name="basePackage"

             value="ojc.board.repository,ojc.user.repository" />

       </bean>

 

       <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"

             destroy-method="clearCache">

             <constructor-arg name="sqlSessionFactory" ref="SqlSessionFactory" />

       </bean>

 

       <bean id="transactionManager"

             class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

             <property name="dataSource" ref="dataSource" />

       </bean>

 

       <tx:annotation-driven transaction-manager="transactionManager" />

</beans>

 

n  WEB-INF/spring/appServlet/servlet-context.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd

             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

 

       <!-- 디스패처 서블릿을 위한 설정 파일

            정의된 자바빈을 디스패처 서블릿이 관리하는 컨텍스트에 로딩한다 -->

 

       <!-- Spring MVC 컴포넌트들을 디폴트 설정을 통해 활성화.

         Spring MVC @Controller 요청을 보내 처리하기 위한

         HandlerMapping HandlerAdapter 빈으로 등록.

                 컨트롤러(@Controller)에서는 @RequestMapping, @ExceptionHandler

                 등과 같은 어노테이션을 통해 해당 기능을 사용할  있도록 한다. -->

       <annotation-driven />

      

       <!-- @Component, @Repository, @Service, @Controller

            어노테이션을 가진 자바빈들을 스캐닝하기 위한 기본 패키지 경로 -->

       <context:component-scan base-package="ojc" />

 

       <resources mapping="/resources/**" location="/resources/" />

 

       <!-- ViewResilver : 접두어접미어로  컨트롤러가 리턴하는 뷰의 이름을 해석 -->

       <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

             <beans:property name="prefix" value="/WEB-INF/views/" />

             <beans:property name="suffix" value=".jsp" />

       </beans:bean>

      

       <!-- 로그인 여부를 확인하기 위한 인터셉터

            게시판쪽으로 들어오는 요청은 로그인이 되지 않았다면

            로그인 화면으로 보낸다. -->

       <interceptors>

             <interceptor>

                 <mapping path="/boards/**" />

                    <beans:bean class="ojc.web.interceptor.LoginInterceptor" />

             </interceptor>

       </interceptors>

 

</beans:beans>

 

n  ojc.board.dto.Page.java

 

package ojc.board.dto;

 

import lombok.Data;

 

/**

 * -------------------------------------

 * STS에서 Lombok 사용하기 위해서는

 * -------------------------------------

 * 1. pom.xml lombok dependency 추가하고

 * 2. .m2 아래 lombok-1.16.16.jar 복사후 lombok.jar 이름 변경

 * 3. SpringToolSuite4.ini 파일의 맨아래에 -javaagent:lombok.jar 추가

 * 4. STS 다시 시작

 * @author jclee

 *

 * 페이징을 위한 클래스

 */

@Data

public class Pager {

       private int page// current page

       private int size// rows per page

       private int bsize// pages per block

 

       private int rows// total elements

       private int pages// total pages

       private int blocks// total blocks

 

       private int block// current block

       private int bspage// current block start page

       private int bepage// current block end page

 

       public Pager(int pageint sizeint bsizeint rows) {

             //현재페이지

             this.page = page;

            

             //한페이지당 게시물개수

             this.size = size;

            

             //블럭당페이지사이즈(기본5 되어 있음)

             //페이지5개씩 한블럭에 표시되고 넘어가면 >> 표시가 나옴

             this.bsize = bsize;

            

             //총게시물건수

             this.rows = rows;

 

             //총페이지

             pages = (int) Math.ceil((doublethis.rows / this.size);

             //총블럭

             blocks = (int) Math.ceil((doublepages / this.bsize);

 

             //현재블럭

             block = (int) Math.ceil((doublethis.page / this.bsize);

             //현재블럭종료페이지

              bepage = block * this.bsize;

             //현재페이지시작페이지

             bspage = bepage - this.bsize + 1;

       }

      

       // 두번째 페이지이고 한페이지에 10개씩 이라면 10 리턴

       public static int seekOffset(int pageint size) {

             if (page > 0) {

                    return (page - 1) * size;

             }

             return 0;

       }

 

       // 두번째 페이지이고 한페이지에 10개씩 이라면 11 리턴

       public static int seekStart(int pageint size) {

             return ((page - 1) * size) + 1;

       }

 

       // 두번째 페이지이고 한페이지에 10개씩 이라면 20 리턴

       public static int seekEnd(int pageint size) {

             return page * size;

       }

}

 

n  ojc.board.model.Board.java

package ojc.board.model;

 

import java.util.Date;

 

import lombok.Data;

 

/**

 * -------------------------------------

 * STS에서 Lombok 사용하기 위해서는

 * -------------------------------------

 * 1. pom.xml lombok dependency 추가하고

 * 2. .m2 아래 lombok-1.16.16.jar 복사후 lombok.jar 이름 변경

 * 3. SpringToolSuite4.ini 파일의 맨아래에 -javaagent:lombok.jar 추가

 * 4. STS 다시 시작

 * @author jclee

 *

 * 오라클쪽의 XBOARD 테이블에 대응하는 모델 클래스

 */

@Data

public class Board {

      private long id;        //게시물ID

      private String writer;  //작성자

      private String title;   //제목

      private String content; //본문내용

      private Date regDate;   //등록일시

      private long hitCount;  //조회수

}

 

n  ojc.board.repository.BoardMapper.java

 

package ojc.board.repository;

 

import java.util.List;

 

import org.apache.ibatis.annotations.Mapper;

import org.apache.ibatis.annotations.Param;

import org.apache.ibatis.annotations.Select;

 

import ojc.board.model.Board;

 

/**

 * 매퍼 클래스

 * board-mapper.xml namespace에 기술됨

 * @author jclee

 *

 */

@Mapper

public interface BoardMapper {

          public int insert(Board board);

          public int update(Board board);

          public int delete(long id);

         

          @Select("SELECT COUNT(*) FROM xboard")

          public int count();

          @Select("SELECT * FROM xboard ORDER BY id DESC")

          public List<Board> selectAll();

         

          public Board selectById(long id);

         

          // 페이지 나누기 쿼리 : page : 현재페이지, size:페이지당 게시물개수

          public List<Board> selectByLimit(@Param("page") int page, @Param("size") int size);

//조회수 증가 쿼리,본인이 쓴 글은 조회수를 증가 안하기 위해 글쓴이(requester)를 넘김

          public int increment(@Param("id") long id, @Param("requester") String requester);

}

n  ojc.login.dto.Login.java

 

package ojc.login.dto;

 

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

 

/**

 * -------------------------------------

 * STS에서 Lombok을 사용하기 위해서는

 * -------------------------------------

 * 1. pom.xml lombok dependency를 추가하고

 * 2. .m2 아래 lombok-1.16.16.jar를 복사후 lombok.jar로 이름 변경

 * 3. SpringToolSuite4.ini 파일의 맨아래에 -javaagent:lombok.jar 추가

 * 4. STS 다시 시작

 *

 * @author jclee

 * 로그인에서 사용되는 DTO

 */

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Login {

           private String email;

           private String password;

           private String error;  //오류 메시지 셋팅위한 것 추가됨

}

 

n  ojc.login.service.LoginService.java

 

package ojc.login.service;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

 

import ojc.login.dto.Login;

import ojc.user.model.User;

import ojc.user.repository.UserMapper;

 

/**

 * 로그인 서비스

 * 사용자 인증

 * @author jclee

 *

 */

@Service

public class LoginService {

          @Autowired

          private UserMapper userMapper;

 

          public void authenticate(Login login) {

                   User user = userMapper.selectByEmail(login.getEmail());

                   if (user == null) {

                             login.setError("Email does not exist.");

                   } else {

                             if (!user.getPassword().equals(login.getPassword())) {

                                      login.setError("Password is not correct.");

                             } else {

                                      login.setError(null);

                             }

                   }

          }

}

 

n  ojc.user.model.User.java

 

package ojc.user.model;

 

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

 

/**

 * -------------------------------------

 * STS에서 Lombok 사용하기 위해서는

 * -------------------------------------

 * 1. pom.xml lombok dependency 추가하고

 * 2. .m2 아래 lombok-1.16.16.jar 복사후 lombok.jar 이름 변경

 * 3. SpringToolSuite4.ini 파일의 맨아래에 -javaagent:lombok.jar 추가

 * 4. STS 다시 시작

 * @author jclee

 *

 * 오라클쪽의 XUSER 테이블에 대응되는 모델 클래스

 */

@Data

@NoArgsConstructor

@AllArgsConstructor

public class User {

      private String email;

      private String password;

}

 

n  UserMapper.java

 

package ojc.user.repository;

 

import java.util.List;

 

import org.apache.ibatis.annotations.Delete;

import org.apache.ibatis.annotations.Insert;

import org.apache.ibatis.annotations.Mapper;

import org.apache.ibatis.annotations.Result;

import org.apache.ibatis.annotations.ResultType;

import org.apache.ibatis.annotations.Results;

import org.apache.ibatis.annotations.Select;

import org.apache.ibatis.annotations.Update;

 

import ojc.user.model.User;

 

/**

 * 매퍼 클래스

 * board쪽고 달리 loign쪽은 매퍼 XML 파일 없이  자바 매퍼에서 쿼리 처리 다함

 * @return

 */

@Mapper

public interface UserMapper {

      @Insert("INSERT INTO xuser(email, password) VALUES(#{email}, #{password})")

      public int insert(User user);

 

      @Update("UPDATE xuser SET password = #{password} WHERE email = #{email}")

      public int update(User user);

 

      @Delete("DELETE FROM xuser WHERE email = #{email}")

      public int delete(String email);

 

      @Select("SELECT COUNT(*) FROM xuser")

      public int count();

 

      @Select("SELECT * FROM xuser ORDER BY email ASC")

      @ResultType(User.class)

      public List<User> selectAll();

 

      @Select("SELECT * FROM xuser WHERE email = #{email}")

      // 선언해 놓으면 다른 메소드에서 @ResultMap("userResultMap") 선언으로 이용할  있다.

      @Results(id = "userResultMap", value = {

                  @Result(property = "email", column = "email"),

                  @Result(property = "password", column = "password") })

      public User selectByEmail(String email);

}

 

n  Ojc.web.controller.BoardController.java

 

package ojc.web.controller;

 

import javax.servlet.http.HttpSession;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.servlet.ModelAndView;

 

import ojc.board.dto.Pager;

import ojc.board.model.Board;

import ojc.board.repository.BoardMapper;

import ojc.user.model.User;

 

/**

 * 게시판 요청 처리를 위한 컨트롤러

 * @author jclee

 *

 */

@Controller

@RequestMapping("/boards")

public class BoardController {

      @Autowired

      private BoardMapper boardMapper;   

     

      /**

       * 게시판 리스트 보기

       * @param page : 조회를 원하는 페이지

       * @param size : 한페이지당 보여지는 게시물 건수

       * @param bsize : 하나의 페이지 블럭에 포함되는 페이지 ( 예제에서는 5개의 페이지를 보인다)

       * @return

       */

      @GetMapping()

      public ModelAndView getBoardsView(

                  @RequestParam(name="page", required=false, defaultValue="1") int page,

                  @RequestParam(name="size", required=false, defaultValue="10") int size,

                  @RequestParam(name="bsize", required=false, defaultValue="5") int bsize) {

            ModelAndView mav = new ModelAndView("board_list");

            mav.addObject("boards", boardMapper.selectByLimit(page, size));

            mav.addObject("pager", new Pager(page, size, bsize, boardMapper.count()));

            return mav;

      }

     

      /**

       * 게시물 상세보기

       * @param id

       * @param session

       * @param model

       * @return

       */

      @GetMapping("/view/{id}")

      public String getBoardView(@PathVariable long id, HttpSession session, Model model) {

            User user = (User) session.getAttribute("user");

            if (user == null) {

                  return session.getServletContext().getContextPath() + "/login";

            }

           

            boardMapper.increment(id, user.getEmail());

            model.addAttribute("board", boardMapper.selectById(id));

            return "board_view";

      }

     

      /**

       * 글쓰기 화면 board_write.jsp 로딩

       * @param session

       * @param model

       * @return

       */

      @GetMapping("/write")

      public String getInsertView(HttpSession session, Model model) {

            User user = (User) session.getAttribute("user");

            if (user == null) {

                  return session.getServletContext().getContextPath() + "/login";

            }

            model.addAttribute("user", user);

            return "board_write";

      }

     

      /**

       * 글쓰고 저장 하기

       * XBOARD 테이블에 INSERT

       * @param board

       * @param session

       * @param model

       * @return

       */

      @PostMapping("/write")

      public String postInsert(Board board, HttpSession session, Model model) {

            User user = (User) session.getAttribute("user");

           

            if (user != null && board != null) {

                  if (user.getEmail().equals(board.getWriter())) {

                        boardMapper.insert(board);

                        return "redirect:/boards";

                  }

            }

            return session.getServletContext().getContextPath() + "/boards";

      }

     

      /**

       * 수정화면 board_update.jsp 로딩

       * @param id

       * @param session

       * @param model

       * @return

       */

      @GetMapping("/update/{id}")

      public String getUpdateView(@PathVariable long id, HttpSession session, Model model) {

            User user = (User) session.getAttribute("user");

            Board board = boardMapper.selectById(id);

           

            if (user != null && board != null) {

                  if (user.getEmail().equals(board.getWriter())) {

                        model.addAttribute("board", board);

                        return "board_update";

                  }

            }

            return session.getServletContext().getContextPath() + "/boards";

      }

     

      /**

       * 수정후 저장하기 XBOARD 테이블 UPDATE 쿼리 실행

       * @param board

       * @param session

       * @param model

       * @return

       */

      @PostMapping("/update")

      public String postUpdate(Board board, HttpSession session, Model model) {

            User user = (User) session.getAttribute("user");

           

            if (user != null && board != null) {

                  if (user.getEmail().equals(board.getWriter())) {

                        boardMapper.update(board);

                        return "redirect:/boards/view/" + board.getId();

                  }

            }

            return session.getServletContext().getContextPath() + "/boards";

      }

     

      /**

       * 게시물 삭제

       * @param id : 게시물 ID

       * @param session

       * @param model

       * @return

       */

      @GetMapping("/delete/{id}")

      public String getDelete(@PathVariable long id, HttpSession session, Model model) {

            User user = (User) session.getAttribute("user");

           

            if (user != null) {

                  Board board = boardMapper.selectById(id);

                 

                  if (user.getEmail().equals(board.getWriter())) {

                        boardMapper.delete(id);

                        return "redirect:/boards";

                  }

            }

            return session.getServletContext().getContextPath() + "/boards";

      }

     

}

 

n  ojc.web.controller.ControllerExceptionHandler.java

 

package ojc.web.controller;

 

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.servlet.ModelAndView;

 

@ControllerAdvice

public class ControllerExceptionHandler {

 

          /**

           * 컨트롤러에서 오류가 발생하면 error.jsp 로딩

           */

          @ExceptionHandler(Exception.class)

          public ModelAndView handleError(Exception e) {

                   ModelAndView mav = new ModelAndView("error/error");

                   mav.addObject("errorMsg", e.getMessage());

                   return mav;

          }

 

}

 

n  ojc.web.controller.HomeController.java

 

package ojc.web.controller;

 

import javax.servlet.http.HttpServletRequest;

 

import org.springframework.stereotype.Controller; 

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

 

/**

 * 최초 localhost:8080 으로 요청이 오는 경우 처리

 * @author jclee

 *

 */

@Controller

@RequestMapping("/")

public class HomeController { 

          @GetMapping

          public String getHomeView(HttpServletRequest request) {

                   return "home";

          }

 

          @GetMapping("/404.html")

          public String get404View() {

                   return "error/404";

          }

 

          @GetMapping("/throw")

          public String testControllerAdvice() {

                   throw new RuntimeException("Error Test In Controller.");

          }

}

 

n  ojc.web.controller.LoginController.java

 

package ojc.web.controller;

 

import javax.servlet.http.HttpSession;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.PostMapping;

 

import ojc.login.dto.Login;

import ojc.login.service.LoginService;

import ojc.user.model.User;

 

/**

 * 로그인 처리용 컨트롤러

 * @author jclee

 *

 */

@Controller

public class LoginController {

          @Autowired

          private LoginService loginService;

 

          @ModelAttribute("active")

          public String active(){

                   return "login";

          }

         

          @GetMapping("/login")

          public String getLoginView() {

                   return "login";

          }

 

          /**

           * 로그인 처리

           * @param login

           * @param model

           * @param session

           * @return

           */

          @PostMapping("/login")

          public String postLogin(Login login, Model model, HttpSession session) {

                   loginService.authenticate(login);

                   if (login.getError() != null) {

                             model.addAttribute("error", login.getError());

                             model.addAttribute("login", login);

                             return "login";

                   } else {

                             User user = new User(login.getEmail(), login.getPassword());

                             session.setAttribute("user", user);

                             return "redirect:/boards";

                   }

          }

 

          @GetMapping("/logout")

          public String getLogout(HttpSession session) {

                   session.invalidate();

                   return "login";

          }

}

 

n  ojc.web.controller.UserController.java

 

package ojc.web.controller;

 

import java.util.List;

 

import javax.servlet.http.HttpSession;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.servlet.mvc.support.RedirectAttributes;

 

import ojc.user.model.User;

import ojc.user.repository.UserMapper;

 

/**

 * 사용자 등록처리  컨트롤러

 * @author jclee

 *

 */

@Controller

@RequestMapping("/users")

public class UserController {

          @Autowired

          private UserMapper userMapper;

         

          @GetMapping

          @ResponseBody

          public Object getUsersView() {

                   List<User> users = userMapper.selectAll();

                   return users;

          }

         

          @PostMapping("/enroll")

          public String postUser(User user, Model model, HttpSession session, RedirectAttributes redirectAttributes) {

                   // 클라이언트 단 또는 서버 단에서 데이터 밸리데이션 체크를 적용하는 것을 권장한다.

                   User duplicatedUser = userMapper.selectByEmail(user.getEmail());

                   if (duplicatedUser == null) {

                             userMapper.insert(user);

                             redirectAttributes.addFlashAttribute("result", "OK");

                   } else {

                             redirectAttributes.addFlashAttribute("result", "FAIL");

                             redirectAttributes.addFlashAttribute("error", "Fail: Email is duplicated.");

                   }

                  

                   return "redirect:/login";

          }

}

 

n  ojc.web.interceptor.LoginInterceptor.java

 

package ojc.web.interceptor;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

 

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

 

import ojc.user.model.User;

 

/**

 * /board** 진입시 로그인 여부를 체크하기 위한 인터셉터

 * 로그인이 안되어 있는 경우 로그인 화면(/login) 으로  보냄

 * @author jclee

 *

 */

@Component

public class LoginInterceptor extends HandlerInterceptorAdapter {

 

       @Override

       public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

                    throws Exception {

            

            

             HttpSession session = request.getSession();

             User user = (User) session.getAttribute("user");

             if (user == null) {

                    String url = session.getServletContext().getContextPath() + "/login";

                    response.sendRedirect(url);

                    System.out.println("LoginInterceptor # preHandle() : NO PASS");

                    return false;

             }

             System.out.println("LoginInterceptor # preHandle() : PASS");

             return true;

       }

}

 

n  resources/mybatis/mybatis-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>

       <settings>

             <setting name="cacheEnabled" value="true"/>

             <setting name="mapUnderscoreToCamelCase" value="true" />

             <setting name="defaultFetchSize" value="100" />

             <setting name="defaultStatementTimeout" value="30" />

       </settings>

 

       <typeAliases>

           <!-- 보통 VO객체여러개이고  패키지내에 존재할  package 사용.

                아래 패키지 아래의 클래스들이 mapper xml에서 type으로 사용됨-->

             <package name="ojc.board.model" />

             <package name="ojc.user.model" />

       </typeAliases>

</configuration>

 

 

n  resources/mybatis/mapper/board-mapper.xml

 

<?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="ojc.board.repository.BoardMapper">

      

       <resultMap type="Board" id="boardResultMap">

             <result property="id" column="ID" />

             <result property="writer" column="WRITER" />

             <result property="title" column="TITLE" />

             <result property="content" column="CONTENT" />

             <result property="regDate" column="REG_DATE" />

             <result property="hitCount" column="HIT_COUNT" />

       </resultMap>

      

       <insert id="insert" parameterType="Board">

             INSERT INTO xboard(writer, title, content, reg_date, hit_count)

             VALUES(#{writer}, #{title}, #{content}, SYSDATE, 0)

       </insert>

      

       <update id="update" parameterType="Board">

             UPDATE xboard SET title=#{title}, content=#{content} WHERE id=#{id}

       </update>

      

       <delete id="delete" parameterType="long">

             DELETE FROM xboard WHERE id=#{id}

       </delete>

      

       <select id="selectById" parameterType="long" resultMap="boardResultMap">

             SELECT * FROM xboard WHERE id=#{id}

       </select>

      

      

       <select id="selectByLimit" resultType="Board">

             <bind name="start" value="@ojc.board.dto.Pager@seekStart(page, size)"/>

             <bind name="end" value="@ojc.board.dto.Pager@seekEnd(page, size)"/>

             <!-- SELECT * FROM (

                    SELECT ROWNUM AS rnum, b.*

                    FROM (

                           SELECT * FROM xboard

                           ORDER BY id DESC

                    ) b

                 WHERE ROWNUM &lt;= #{end}

             ) WHERE rnum &gt;= #{start} -->

            

             -- ORACLE12.1 이상

             -- 9999페이지까지는 SKIP하고  다음 10000번째 페이지의 10 추출

             SELECT *

             FROM   xboard

             ORDER BY id DESC

             OFFSET TO_NUMBER(#{start}) - 1  ROWS FETCH NEXT 10 ROWS ONLY

       </select>

      

       <update id="increment">

             UPDATE xboard SET hit_count=hit_count+1 WHERE id=#{id} and writer!=#{requester}

       </update>

      

</mapper>

 

n  WEB-INF/views/error/error.jsp

n  WEB-INF/views/error/404.jsp

 

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

.bs-example {

       margin20px;

}

</style>

</head>

<body>

       <c:import url="../nav_top.jsp"></c:import>

 

       <div class="bs-example">

             <h1>404 NOT FOUND</h1>

       </div>

</body>

</html>

 

n  WEB-INF/views/board_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"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

.bs-example {

       margin20px;

}

.pagination {

       margin0px !important;

}

</style>

</head>

<body>

       <c:import url="nav_top.jsp"></c:import>

 

       <div class="bs-example">

             <h2>Board</h2>

             <table class="table table-condensed table-hover table-striped">

                    <thead>

                           <tr>

                                 <th class="col-xs-1 col-sm-1 col-md-1 col-lg-1">No</th>

                                 <th class="col-xs-6 col-sm-6 col-md-6 col-lg-6">Title</th>

                                 <th class="col-xs-2 col-sm-2 col-md-2 col-lg-2">Writer</th>

                                 <th class="col-xs-2 col-sm-2 col-md-2 col-lg-2">Date</th>

                                 <th class="col-xs-1 col-sm-1 col-md-1 col-lg-1">Hits</th>

                           </tr>

                    </thead>

                    <tbody>

                           <c:forEach items="#{boards }" var="board">

                                 <tr>

                                        <td>${board.id }</td>

                                        <td><a href="<c:url value='/boards/view/${board.id }'/>">${board.title }</a></td>

                                        <td>${board.writer }</td>

                                        <td><fmt:formatDate pattern="MM-dd hh:mm" value="${board.regDate }" /></td>

                                        <td>${board.hitCount }</td>

                                 </tr>

                           </c:forEach>

                    </tbody>

             </table>

             <div class="row">

                    <div class="col-xs-8 col-sm-8 col-md-8 col-lg-8">

                           <ul class="pagination">

                                 <c:set var="target" value="boards" />

                                 <!-- 게시물이 없는 경우 -->

                                 <c:if test="${pager.rows==0 }">

                                        <li class="active"><a href="#">1</a></li>

                                 </c:if>

                                

                                 <!-- 게시물이 있는 경우 -->

                                 <c:if test="${pager.rows > 0 }">

                                     <!-- common 변수에 한페이지당 레코드건수&블럭당 페이지수 저장 -->

                                        <c:set var="common"

                                               value="size=${pager.size }&bsize=${pager.bsize }" />

                                       

                                        <!-- 블럭시작페이지가 블럭당 페이지수 보다  경우 

                                                 예를들면 6번째 페이지를 보는 경우

                                             Home  이전 << 셋팅. -->

                                        <c:if test="${pager.bspage > pager.bsize }">

                                               <c:set var="home" value="page=1&${common }" />

                                               <c:set var="prev" value="page=${pager.bspage-1 }&${common }" />

                                               <li><a href="${target }?${home }">Home</a></li>

                                               <li><a href='<c:url value="${target }?${prev }"/>'>&laquo;</a></li>

                                        </c:if>

                                        <!-- 5개의 페이지 번호를 표시 -->

                                        <c:forEach var="pno"

                                                   begin="${pager.bspage }"

                                                   end="${pager.bepage }">

                                               <c:if test="${pno==pager.page }">

                                                     <li class="active"><a href="#">${pno }</a></li>

                                               </c:if>

                                               <c:if test="${pno!=pager.page }">

                                                     <c:if test="${pno <= pager.pages }">

                                                            <c:set var="page" value="page=${pno }&${common }" />

                                                            <li><a href='<c:url value="${target }?${page }"/>'>${pno }</a></li>

                                                     </c:if>

                                               </c:if>

                                        </c:forEach>

                                       

                                        <!-- 블럭시작페이지가 전체 페이지수 보다 작은 경우 

                                                 예를들면 전체 페이지수가 6인데 1~5번째 페이지를 보는 경우

                                             Last  이후 >> 셋팅. -->

                                        <c:if test="${pager.bepage < pager.pages }">

                                               <c:set var="next" value="page=${pager.bepage+1 }&${common }" />

                                               <c:set var="last" value="page=${pager.pages }&${common }" />

                                               <li><a href='<c:url value="${target }?${next }"/>'>&raquo;</a></li>

                                               <li><a href="${target }?${last }">Last</a></li>

                                        </c:if>

                                 </c:if>

                           </ul>

                    </div>

                    <div class="col-xs-4 col-sm-4 col-md-4 col-lg-4">

                           <span class="pull-right"> <a href="<c:url value='/boards/write'/>" class="btn btn-primary">Write</a>

                           </span>

                    </div>

             </div>

       </div>

</body>

</html>

n  WEB-INF/views/board_update.jsp

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

.bs-example {

       margin-bottom20px;

       margin-left20px;

       margin-right40px;

       margin-top20px;

}

</style>

</head>

<body>

       <c:import url="nav_top.jsp"></c:import>

      

       <div class="bs-example">

             <form class="form-horizontal" action="<c:url value='/boards/update'/>" method="post">

                    <input type="hidden" name="id" value="${board.id }">

                    <div class="form-group">

                           <label for="title" class="control-label col-xs-2">Title</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="title" name="title" placeholder="Title" required

                                        value="${board.title }">

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="writer" class="control-label col-xs-2">Writer</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="writer" name="writer" placeholder="Writer" required

                                        value="${board.writer }" readonly="readonly">

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="content" class="control-label col-xs-2">Content</label>

                           <div class="col-xs-10">

                                 <textarea class="form-control" rows="20" id="content" name="content" placeholder="Content" required>${board.content }</textarea>

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="regDate" class="control-label col-xs-2">Date</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="regDate" placeholder="Date" required

                                        value="<fmt:formatDate pattern="yyyy-MM-dd hh:mm:ss" value="${board.regDate }" />" readonly="readonly">

                           </div>

                    </div>

                    <div class="form-group">

                           <div class="col-xs-offset-2 col-xs-10">

                                 <a href="<c:url value='/boards'/>" class="btn btn-primary">List</a>

                                 <button type="submit" class="btn btn-primary">Update</button>

                           </div>

                    </div>

             </form>

       </div>

</body>

</html>

n  WEB-INF/views/board_view.jsp

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

.bs-example {

       margin-bottom20px;

       margin-left20px;

       margin-right40px;

       margin-top20px;

}

</style>

</head>

<body>

       <c:import url="nav_top.jsp"></c:import>

      

       <div class="bs-example">

             <form class="form-horizontal" action="/examples/actions/confirmation.php" method="post">

                    <div class="form-group">

                           <label for="title" class="control-label col-xs-2">Title</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="title" name="title" placeholder="Title" required

                                        value="${board.title }" readonly="readonly">

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="writer" class="control-label col-xs-2">Writer</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="writer" name="writer" placeholder="Writer" required

                                        value="${board.writer }" readonly="readonly">

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="content" class="control-label col-xs-2">Content</label>

                           <div class="col-xs-10">

                                 <textarea class="form-control" rows="20" id="content" name="content" placeholder="Content" required

                                        readonly="readonly">${board.content }</textarea>

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="regDate" class="control-label col-xs-2">Date</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="regDate" name="regDate" placeholder="Date" required

                                        value="<fmt:formatDate pattern="yyyy-MM-dd hh:mm:ss" value="${board.regDate }" />" readonly="readonly">

                           </div>

                    </div>

                    <div class="form-group">

                           <div class="col-xs-offset-2 col-xs-10">

                                 <a href="<c:url value='/boards'/>" class="btn btn-primary">List</a>

                                 <c:if test="${not empty user }">

                                        <c:if test="${user.email == board.writer }">

                                               <a href="<c:url value='/boards/delete/${board.id }'/>" class="btn btn-primary">Delete</a>

                                               <a href="<c:url value='/boards/update/${board.id }'/>" class="btn btn-primary">Update</a>

                                        </c:if>

                                 </c:if>

                           </div>

                    </div>

             </form>

       </div>

</body>

</html>

n  WEB-INF/views/board_writer.jsp

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

.bs-example {

       margin-bottom20px;

       margin-left20px;

       margin-right40px;

       margin-top20px;

}

</style>

</head>

<body>

       <c:import url="nav_top.jsp"></c:import>

      

       <div class="bs-example">

             <form class="form-horizontal" action="<c:url value='/boards/write'/>" method="post">

                    <div class="form-group">

                           <label for="title" class="control-label col-xs-2">Title</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="title" name="title" placeholder="Title" required>

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="writer" class="control-label col-xs-2">Writer</label>

                           <div class="col-xs-10">

                                 <input type="text" class="form-control" id="writer" name="writer" placeholder="Writer" required

                                        value="${user.email }" readonly="readonly">

                           </div>

                    </div>

                    <div class="form-group">

                           <label for="content" class="control-label col-xs-2">Content</label>

                           <div class="col-xs-10">

                                 <textarea class="form-control" rows="20" id="content" name="content" placeholder="Content" required></textarea>

                           </div>

                    </div>

                    <div class="form-group">

                           <div class="col-xs-offset-2 col-xs-10">

                                 <a href="<c:url value='/boards'/>" class="btn btn-primary">List</a>

                                 <button type="submit" class="btn btn-primary">Save</button>

                           </div>

                    </div>

             </form>

       </div>

</body>

</html>

n  WEB-INF/views/home.jsp

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

.bs-example {

       margin20px;

}

.logo-small {

    color#f4511e;

    font-size50px;

}

footer .glyphicon {

    font-size20px;

    margin-bottom20px;

    color#f4511e;

}

</style>

</head>

<body id="myPage">

       <c:import url="nav_top.jsp"></c:import>

      

       <br>

       <br>

       <br>

      

       <div id="services" class="container-fluid text-center">

             <h2>스프링MVC5, 마이바티스3.5, 오라클12 연동 게시판</h2>

             <h4>Spring Framework5 + MyBatis3.5 + Oracle12</h4>

             <br>

             <div class="row slideanim">

                    <div class="col-sm-4">

                           <span class="glyphicon glyphicon-off logo-small"></span>

                           <h4>

                                 <c:if test="${not empty user }">

                                        <a href="logout">LOGOUT</a>

                                 </c:if>

                                 <c:if test="${empty user }">

                                        <a href="login">LOGIN</a>

                                 </c:if>

                           </h4>

                           <p>로그인</p>

                    </div>

                    <div class="col-sm-4">

                           <span class="glyphicon glyphicon-heart logo-small"></span>

                           <h4><a href="boards">BOARD</a></h4>

                           <p>스프링,마이바티스 게시판</p>

                    </div>

                    <div class="col-sm-4">

                           <span class="glyphicon glyphicon-lock logo-small"></span>

                           <h4>YOUR TURN</h4>

                           <p>Lorem ipsum dolor sit amet..</p>

                    </div>

             </div>

       </div>

 

       <br>

       <br>

       <br>

      

       <footer class="container-fluid text-center">

             <a href="#myPage" title="To Top"><span class="glyphicon glyphicon-chevron-up"></span></a>

             <p>Made By <a href="#" title="#">have a nice day!</a></p>

       </footer>

</body>

n  </html>WEB-INF/views/login.jsp

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Board</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style type="text/css">

@import url(https://fonts.googleapis.com/css?family=Roboto:300);

 

.login-page {

       width360px;

       padding8% 0 0;

       marginauto;

}

 

.form {

       positionrelative;

       z-index1;

       background#FFFFFF;

       max-width360px;

       margin0 auto 100px;

       padding45px;

       text-aligncenter;

       box-shadow0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24);

}

 

.form input {

       font-family"Roboto", sans-serif;

       outline0;

       background#f2f2f2;

       width100%;

       border0;

       margin0 0 15px;

       padding15px;

       box-sizingborder-box;

       font-size14px;

}

 

.form button {

       font-family"Roboto", sans-serif;

       text-transformuppercase;

       outline0;

       background#4CAF50;

       width100%;

       border0;

       padding15px;

       color#FFFFFF;

       font-size14px;

       -webkit-transitionall 0.3 ease;

       transitionall 0.3 ease;

       cursorpointer;

}

 

.form button:hover, .form button:active, .form button:focus {

       background#43A047;

}

 

.form .message {

       margin15px 0 0;

       color#b3b3b3;

       font-size12px;

}

 

.form .message a {

       color#4CAF50;

       text-decorationnone;

}

 

.form .register-form {

       displaynone;

}

 

.container {

       positionrelative;

       z-index1;

       max-width300px;

       margin0 auto;

}

 

.container:before, .container:after {

       content"";

       displayblock;

       clearboth;

}

 

.container .info {

       margin50px auto;

       text-aligncenter;

}

 

.container .info h1 {

       margin0 0 15px;

       padding0;

       font-size36px;

       font-weight300;

       color#1a1a1a;

}

 

.container .info span {

       color#4d4d4d;

       font-size12px;

}

 

.container .info span a {

       color#000000;

       text-decorationnone;

}

 

.container .info span .fa {

       color#EF3B3A;

}

</style>

<script type="text/javascript">

       $(function() {

             $('.message a').click(function() {

                    $('form').animate({height : "toggle", opacity : "toggle"}, "slow");

                    $('#result').css('display','none');

             });

 

             var result = "${result}";

             if(result){

                    if(result === 'OK'){

                           $("#myModal").modal('show');

                    } else {

                           $('form').animate({height : "toggle", opacity : "toggle"}, "fast");

                    }

             }

       });

</script>

</head>

<body>

 

       <c:import url="nav_top.jsp"></c:import>

      

       <div class="login-page">

             <div class="form">

                    <form class="register-form" action="<c:url value='/users/enroll'/>" method="post">

                           <input type="text" id="email" name="email" placeholder="Email" />

                           <input type="password" id="password" name="password" placeholder="Password" />

                           <button type="submit">create</button>

                           <p class="message">Already registered? <a href="#">Sign In</a></p>

                    </form>

                    <form class="login-form" action="<c:url value='/login'/>" method="post">

                           <input type="text" id="email" name="email" placeholder="Email" value="${login.email }"/>

                           <input type="password" id="password" name="password" placeholder="Password" />

                           <button type="submit">login</button>

                           <p class="message">Not registered? <a href="#">Create an account</a></p>

                    </form>

                    <c:if test="${not empty error }">

                           <br>

                           <span class="label label-danger" id="result">${error }</span>

                    </c:if>

             </div>

       </div>

 

       <div id="myModal" class="modal fade">

             <div class="modal-dialog">

                    <div class="modal-content">

                           <div class="modal-header">

                                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>

                                 <h4 class="modal-title">Completed Membership</h4>

                           </div>

                           <div class="modal-body">

                                 <p>Your registration has been successfully completed.</p>

                                 <p class="text-warning">

                                        <small>Please click the OK button and try logging in.</small>

                                 </p>

                           </div>

                           <div class="modal-footer">

                                 <button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>

                           </div>

                    </div>

             </div>

       </div>

      

</body>

</html>

n  WEB-INF/view/nav_top.jsp

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<nav class="navbar navbar-default">

       <div class="container-fluid">

             <!-- Brand and toggle get grouped for better mobile display -->

             <div class="navbar-header">

                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"

                           data-target="#bs-example-navbar-collapse-1" aria-expanded="false">

                           <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span>

                           <span class="icon-bar"></span>

                    </button>

                    <a class="navbar-brand" href="<c:url value='/'/>">Home</a>

             </div>

 

             <!-- Collect the nav links, forms, and other content for toggling -->

             <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

                    <ul class="nav navbar-nav">

                           <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"

                                 aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>

                                 <ul class="dropdown-menu">

                                        <li><a href="<c:url value='/boards'/>">Board</a></li>

                                        <li><a href="#">Another action</a></li>

                                 </ul>

                           </li>

                    </ul>

                    <ul class="nav navbar-nav navbar-right">

                           <c:if test="${not empty user }">

                                 <li><a href="#"><span class="badge">${user.email }</span></a></li>

                           </c:if>

                           <li class="${active=='login'?'active':'' }">

                                 <c:if test="${not empty user }">

                                        <a href="<c:url value='/logout'/>">Logout</a>

                                 </c:if>

                                 <c:if test="${empty user }">

                                        <a href="<c:url value='/login'/>">Login</a>

                                 </c:if>

                           </li>

                           <li class="${active=='board'?'active':'' }"><a href="<c:url value='/boards'/>">Board</a></li>

                          

                    </ul>

             </div>

             <!-- /.navbar-collapse -->

       </div>

       <!-- /.container-fluid -->

</nav>

<script type="text/javascript">

       // 화면이 갱신되면 효과를 잃어 버린다.

       $('.nav li').click(function(e) {

             $('.nav li').removeClass('active');

             $(this).addClass('active');

       });

</script>


 

댓글 없음:

댓글 쓰기

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...