본문 바로가기
study/Spring

[Spring] 24. Spring (상품목록 [springmvc1/pom, web, spring-db, list, item, ItemController, ShopService, ItemDao, spring-mvc, oracle_shop])

by 금이패런츠 2022. 5. 3.
728x90
반응형

springmvc1/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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>kr.kic</groupId>
  <artifactId>springmvc1</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>springmvc1 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  	<spring.version>4.3.30.RELEASE</spring.version>
  	<spring.version1>5.3.18</spring.version1>
  	<spring.version2>5.2.19.RELEASE</spring.version2>
  	<spring.version3>4.3.30.RELEASE</spring.version3>
  </properties>
  
  <!-- 원격 저장소 설정 : mvnrepository.com : 기본 원격 저장소 이외의 저장소 사용시 설정 -->
  <repositories>
	<repository>
		<id>oracle</id>
		<name>ORACLE JDBC Repository</name>
		<url>http://maven.jahia.org/maven2</url>
	</repository> 
  </repositories>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	    
	<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-web</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-webmvc</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	
	<!-- spring db 설정 -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-jdbc</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	
	<!-- 오라클 관련 설정 -->
	<dependency>
		<groupId>com.oracle</groupId>
	    <artifactId>ojdbc5</artifactId>
	    <version>11.2.0.2.0</version>
	</dependency>
	
	<!-- jstl 설정 -->
	<dependency>
		<groupId>jstl</groupId>
	    <artifactId>jstl</artifactId>
	    <version>1.2</version>
	</dependency>

	<!-- 유효성 검증 설정 -->
	<dependency>
		<groupId>javax.validation</groupId>
	    <artifactId>validation-api</artifactId>
	    <version>2.0.1.Final</version>
	</dependency>
	<dependency>
		<groupId>org.hibernate</groupId>
	    <artifactId>hibernate-validator</artifactId>
	    <version>6.1.0.Final</version>
	</dependency>
	
	<!-- 파일 업로드 설정-->
	<dependency>
		<groupId>commons-fileupload</groupId>
	    <artifactId>commons-fileupload</artifactId>
	    <version>1.3.3</version>
	</dependency>
	<dependency>
		<groupId>commons-beanutils</groupId>
	    <artifactId>commons-beanutils</artifactId>
	    <version>1.9.3</version>
	</dependency>
	<dependency>
		<groupId>commons-digester</groupId>
	    <artifactId>commons-digester</artifactId>
	    <version>2.1</version>
	</dependency>
	
	<!-- AOP 설정-->
	<dependency>
		<groupId>org.aspectj</groupId>
	    <artifactId>aspectjweaver</artifactId>
	    <version>1.9.6</version>
	</dependency>
	
	<!-- sitemesh 설정-->
	<!-- http://mvnrepository.com/artifact/org.sitemesh/sitemesh -->
	<dependency>
		<groupId>org.sitemesh</groupId>
	    <artifactId>sitemesh</artifactId>
	    <version>3.0.1</version>
	</dependency>
	
  </dependencies>
  
  <build>
    <finalName>springmvc1</finalName>
    <!-- pom.xml의 첫번째 줄에 maven-war-plugin관련 오류 발생시 코딩 -->
    <plugins>
    	<plugin>
    		<artifactId>maven-war-plugin</artifactId>
    		<version>3.2.2</version>
    	</plugin>
    </plugins>
  </build>
</project>

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" 
id="WebApp_ID" version="4.0">
  <display-name>springmvc1</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
<servlet>
   <servlet-name>shop</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>
       classpath:spring-mvc.xml
       classpath:spring-db.xml
     </param-value>
   </init-param>
   <!-- 
   		서버 시작시 서블릿 로드
    -->
   <load-on-startup>1</load-on-startup>
</servlet>
<!-- 
	/ : 모든 요청
 -->
<servlet-mapping>
   <servlet-name>shop</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping> 
<!-- 
	filter란 : request/response 객체를 변경하여 서블릿으로 전달.  
			파라미터 인코딩 기능 : request.setCharacterEncoding("UTF-8")
 -->
<filter>
     <filter-name>CharacterEncoding</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>
</filter>
<filter-mapping>
     <filter-name>CharacterEncoding</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

spring-db.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!-- /src/main/resources/spring-db.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  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.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd">
   <bean id="dataSource"
   		 class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   		 <property name="driverClassName"><value>oracle.jdbc.OracleDriver</value></property>
   		 <property name="url"><value>jdbc:oracle:thin:@localhost:1521:xe</value></property>
   		 <property name="username"><value>kic</value></property>
   		 <property name="password"><value>1234</value></property>
   </bean>
</beans>

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--><!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 --><Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!-- APR library loader. Documentation at /docs/apr.html -->
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector connectionTimeout="20000" port="8088" protocol="HTTP/1.1" redirectPort="8443"/>
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!--
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
    -->

    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine defaultHost="localhost" name="Catalina">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log" suffix=".txt"/>

      <Context docBase="springmvc1" path="/springmvc1" reloadable="true" source="org.eclipse.jst.j2ee.server:springmvc1"/></Host>
    </Engine>
  </Service>
</Server>

<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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>kr.kic</groupId>
  <artifactId>springmvc1</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>springmvc1 Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  	<spring.version>4.3.30.RELEASE</spring.version>
  	<spring.version1>5.3.18</spring.version1>
  	<spring.version2>5.2.19.RELEASE</spring.version2>
  	<spring.version3>4.3.30.RELEASE</spring.version3>
  </properties>
  
  <!-- 원격 저장소 설정 : mvnrepository.com : 기본 원격 저장소 이외의 저장소 사용시 설정 -->
  <repositories>
	<repository>
		<id>oracle</id>
		<name>ORACLE JDBC Repository</name>
		<url>http://maven.jahia.org/maven2</url>
	</repository> 
  </repositories>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	    
	<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-web</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-webmvc</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	
	<!-- spring db 설정 -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-jdbc</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	
	<!-- 오라클 관련 설정 -->
	<dependency>
		<groupId>com.oracle</groupId>
	    <artifactId>ojdbc5</artifactId>
	    <version>11.2.0.2.0</version>
	</dependency>
	
	<!-- jstl 설정 -->
	<dependency>
		<groupId>jstl</groupId>
	    <artifactId>jstl</artifactId>
	    <version>1.2</version>
	</dependency>

  </dependencies>
  <build>
    <finalName>springmvc1</finalName>
    <!-- pom.xml의 첫번째 줄에 maven-war-plugin관련 오류 발생시 코딩 -->
    <plugins>
    	<plugin>
    		<artifactId>maven-war-plugin</artifactId>
    		<version>3.2.2</version>
    	</plugin>
    </plugins>
  </build>
</project>

spring-mvc

<?xml version="1.0" encoding="UTF-8" ?>
<!-- /src/main/resources/spring-mvc.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:websocket="http://www.springframework.org/schema/websocket"
  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.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc.xsd">
   
<mvc:default-servlet-handler /> <!-- css, js, html 웹에서 제공되는 파일의 기본 기능 -->
<!-- 
	http://localhost:8088/springmvc1/item/list
	  => ItemController 클래스를 선택
 -->
<bean class=
"org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />

<!-- controller,logic,dao 패키지를 먼저 scan해서 @Component를 가진 클래스의 객체 생성 -->
<context:component-scan base-package="controller,logic,dao,aop" />

<!-- web 환경에서 객체 주입을 위한 설정 : @Autowired, @Controller... 기능 사용 -->
<mvc:annotation-driven />

<!-- AOP 기능 수행 -->
<aop:aspectj-autoproxy />

<!-- 뷰결정자 : jsp 페이지의 위치 지정 -->
<bean id="viewResolver"
     class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass">
     <value>org.springframework.web.servlet.view.JstlView</value>
  </property>
  <!-- /WEB-INF/view/item/list.jsp : 뷰 지정 -->
  <property name="prefix"><value>/WEB-INF/view/</value></property>
  <property name="suffix"><value>.jsp</value></property>
</bean>  
<!-- 
	파일 업로드 설정 : enctype="multipart/form-data"형식의 요청이 들어오면 구동. 
	maxUploadSize   : 100M. 최대 업로드 가능 크기
	maxInMemorySize : 10M. 10M까지는 메모리에 파일의 내용 저장
--> 
<bean id="multipartResolver" 
	  class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 
	  p:maxUploadSize="104854600" p:maxInMemorySize="10485460">
</bean>
<!-- 
	message 코드값을 저장한 properties 파일을 설정 : message.properties
	message 처리를 위한 설정 
-->
<bean id="messageSource"
	  class="org.springframework.context.support.ResourceBundleMessageSource">
	  <property name="basenames">
	  	<list><value>messages</value></list>
	  </property>
</bean>
<!-- 예외처리 -->
 <bean id="exceptionHandler" 
 	   class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
 	   <property name="exceptionMappings">
 	   		<value>exception.LoginException=exception
 	   			   exception.CartException=exception
 	   			   exception.BoardException=exception</value>
 	   </property>
 </bean>
 <!-- 인터셉터 기능 설정 : 특정 url들은 BoardInterceptor를 태운다.-->
 <mvc:interceptors>
 	<mvc:interceptor>
 		<mvc:mapping path="/board/write"/> <!-- 요청 URL 정보 -->
 		<mvc:mapping path="/board/update"/> <!-- 요청 URL 정보 -->
 		<mvc:mapping path="/board/delete"/> <!-- 요청 URL 정보 -->
 		<mvc:mapping path="/board/reply"/> <!-- 요청 URL 정보 -->
 		<bean class="interceptor.BoardInterceptor" /> <!-- 인터셉터 클래스 객체 -->
 	</mvc:interceptor>
 </mvc:interceptors>
 
</beans>

oracle_shop.sql

create table item (
   id number primary key,
   name varchar2(30),
   price number,
   description varchar2(100),
   pictureUrl varchar2(30)
);
select * from item;
insert into item values (1, '레몬', 50,  '레몬에 포함된 구연산은 피로회복에 좋습니다.   비타민C 도 풍부합니다.','lemon.jpg');
insert into item values (2, '오렌지', 100, '비타민C 가 풍부합니다. 맛도 좋습니다.','orange.jpg');
insert into item values (3, '키위', 200,  '비타민C 가 풍부합니다. 다이어트에 좋습니다.','kiui.jpg');
insert into item values (4, '포도', 300,  '폴리페놀을 다량 함유하고 있어 항산화 작용을 합니다.',  'podo.jpg');
insert into item values (5, '딸기', 800,  '비타민C를 다량 함유하고 있습니다.',  'ichigo.jpg');
insert into item values (6, '귤', 1000,  '시네피린을 다량 함유하고 있어 감기예방에 좋습니다.',  'mikan.jpg');
commit;

CREATE TABLE sale (
   saleid number PRIMARY KEY,
   userid varchar2(10) NOT NULL,
   saledate date
);
CREATE TABLE saleitem (
	saleid number REFERENCES sale(saleid),
	seq number ,
	itemid number REFERENCES item(id),
	quantity number ,
	PRIMARY KEY (saleid, seq)
);

-- create 이후에 외래키 설정 구문 
ALTER TABLE saleitem 
 ADD CONSTRAINT saleitem_itemid_fk FOREIGN KEY(itemid)
 REFERENCES item(id) ;

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" %>
<%-- /WEB-INF/view/item/list.jsp : --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>상품 목록</title>
</head>
<body>
<a href="create">상품등록</a>
<a href="../cart/cartView" style="float:right">장바구니</a>
<table>
	<tr>
		<th width="80">상품ID</th>
		<th width="320">상품명</th>
		<th width="100">가격</th>
		<th width="80">수정</th>
		<th width="80">삭제</th>
	</tr>
	<c:forEach items="${itemList}" var="item">
		<tr>
			<td align="center">${item.id}</td>
			<td align="left"><a href="detail?id=${item.id}">${item.name}</a></td>
			<td align="right">${item.price}</td>
			<td align="center"><a href="updateForm?id=${item.id}">수정</a></td>
			<td align="center"><a href="deleteForm?id=${item.id}">삭제</a></td>
		</tr>
	</c:forEach>
</table>
</body>
</html>

Item.java

package logic;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;

import org.springframework.web.multipart.MultipartFile;

public class Item {
	private int id;
	//@NotEmpty : 해당 파라미터값이 null이 아니거나 ""(빈문자열)이 아닌 경우
	@NotEmpty(message="상품명을 입력하세요.")
	private String name;
	@Min(value=10, message="10원 이상만 가능합니다.")
	@Max(value=100000, message="10만원 이하만 가능합니다.")
	private int price;
	@NotEmpty(message="상품설명을 입력하세요.")
	private String description;
	private String pictureUrl;
	//<input type="file" name="picture"> 태그가 선택한 파일의 내용 저장
	private MultipartFile picture;
	
	//getter, setter, toString
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getPictureUrl() {
		return pictureUrl;
	}
	public void setPictureUrl(String pictureUrl) {
		this.pictureUrl = pictureUrl;
	}
	public MultipartFile getPicture() {
		return picture;
	}
	public void setPicture(MultipartFile picture) {
		this.picture = picture;
	}
	@Override
	public String toString() {
		return "Item [id=" + id + ", name=" + name + ", price=" + price + ", description=" + description
				+ ", pictureUrl=" + pictureUrl + "]";
	}
}

ItemController.java

package controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import logic.Item;
import logic.ShopService;

//Component 기능 : 객체화
//Controller기능 : 요청 처리 기능
@Controller //@Component 기능 + Controller 기능
@RequestMapping("item")
public class ItemController {
	@Autowired //ShopService 객체 주입
	private ShopService service; //service : ShopService 객체 참고
	
	//http://localhost:8088/springmvc1/item/list
	@RequestMapping("list")
	public ModelAndView list() {
		//ModelAndView : 데이터 + view 설정
		ModelAndView mav = new ModelAndView();
		//itemList : item 테이블의 모든 정보 저장
		List<Item> itemList = service.itemList();
		mav.addObject("itemList", itemList); //뷰에 제공한 데이터 설정
		return mav; //view 설정이 없는 경우 : 요청url(/item/list)이 기본 뷰로 설정됨
	}
	//http://localhost:8088/springmvc1/item/detail?id=1
	//int id = Integer.parseInt(request.getParameter("id"));
	@RequestMapping({"detail","deleteForm"})
	public ModelAndView detail(Integer id) { //매개변수의 이름은 요청 파라미터 이름임
		ModelAndView mav = new ModelAndView(); //View를 설정하지 않는 경우 요청 Url에 따라 다른 뷰 선택 가능
		Item item = service.getItem(id);
		mav.addObject("item",item);
		return mav; //view 설정이 없는 경우 : 요청url(/item/detail)이 기본 뷰로 설정됨
	}
	//http://localhost:8088/springmvc1/item/create
	@RequestMapping("create")
	public ModelAndView add() {
		ModelAndView mav = new ModelAndView("item/edit"); //view 이름 설정
		mav.addObject(new Item());
		return mav;
	}
	//http://localhost:8088/springmvc1/item/register
	//매개변수 Item item : item 객체의 set프로퍼티에 같은 이름의 파라미터 값이 저장
	//	item.setName(request.getParameter("name"))
	//					화면에서 입력된 파라미터 정보를 저장하고 있는 객체 
	//@Valid : Item 클래스의 유효성 관련 어노테이션으로 유효성 검증을 함. 결과값을 bresult에 저장 
	//request : 요청객체. 요청정보 필요시 매개변수에 추가하면 요청 객체를 주입해 줌
	@RequestMapping("register")
	public ModelAndView add(@Valid Item item, BindingResult bresult, HttpServletRequest request) {
		ModelAndView mav = new ModelAndView("item/edit"); //입력값 오류 발생시 화면
		if(bresult.hasErrors()) { //유효성 검증시 오류가 존재하는 경우
			mav.getModel().putAll(bresult.getModel()); //오류결과를 뷰의 데이터로 전달하기 위해 저장
			return mav;
		}
		//item : 파라미터값을 저장한 객체
		//item : 화면에서 입력된 값
		//request : 요청객체
		service.itemCreate(item, request);
		//redirect:list : list 요청을 재호출 설정
		mav.setViewName("redirect:list"); //뷰를 설정
		return mav;
	}
	@RequestMapping("updateForm")
	public ModelAndView updateForm(Integer id) { //매개변수의 이름은 요청 파라미터 이름임.
		ModelAndView mav = new ModelAndView("item/update"); 
		Item item = service.getItem(id);
		mav.addObject("item", item);
		return mav;
	}
	/*
	 * 1. 입력값의 유효성 검증
	 * 2. db에 입력된 내용 등록
	 * 3. 등록 후 list 재요청하기
	 */
	@RequestMapping("update")
	public ModelAndView update(@Valid Item item, BindingResult bresult, HttpServletRequest request) {
		ModelAndView mav = new ModelAndView("item/update"); 
		if(bresult.hasErrors()) {
			mav.getModel().putAll(bresult.getModel());
			return mav;
		}
		service.itemUpdate(item, request);
		mav.setViewName("redirect:list"); 
		return mav;
	}
	//id에 해당하는 상품을 db에서 삭제
	//list로 재요청
	@RequestMapping("delete")
	public ModelAndView delete(Integer id) {
		ModelAndView mav = new ModelAndView(); 
		service.itemDelete(id);
		mav.setViewName("redirect:list"); 
		return mav;
	}
}

ShopService.java

package logic;

import java.io.File;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import dao.BoardDao;
import dao.ItemDao;
import dao.SaleDao;
import dao.SaleItemDao;
import dao.UserDao;

@Service
public class ShopService {
	
	@Autowired //ItemDao 객체 주입
	ItemDao itemDao; //itemDao : ItemDao 객체 참조
	@Autowired //UserDao 객체 주입
	UserDao userDao; //userDao : UserDao 객체 참조
	@Autowired
	private SaleDao saleDao;
	@Autowired
	private SaleItemDao saleItemDao;
	@Autowired
	private BoardDao boardDao;
	
	public List<Item> itemList() {
		return itemDao.list();
	}

	public Item getItem(Integer id) {
		return itemDao.selectOne(id);
	}

	//item : 화면에서 입력된 파라미터, 파일의 내용 정보
	//request : 요청 객체
	public void itemCreate(Item item, HttpServletRequest request) {
		if(item.getPicture() != null && !item.getPicture().isEmpty()) { //파일업로드가 존재
			uploadFileCreate(item.getPicture(),request,"img/");
			item.setPictureUrl(item.getPicture().getOriginalFilename()); //업로드 된 파일이름
		}
		//maxid : db에 저장된 item 테이블 레코드의 최대 id값
		int maxid = itemDao.maxId();
		item.setId(maxid+1);
		//item  테이블의 컬럼 : id, name, price, description, pictureUrl
		/*
		 * id : item 테이블에 등록된 최대 id값 + 1
		 * name, price, description : 화면에서 입력된 파라미터 값
		 * pictureUrl : 업로드된 파일 이름
		 */
		itemDao.insert(item);
	}
	private void uploadFileCreate(MultipartFile file, HttpServletRequest request, String upath) {
		//file : 업로드된 파일의 내용 저장
		//request : 요청객체
		//upath : 파일위치
		String orgFile = file.getOriginalFilename(); //업로드된 파일의 원래 이름
		//업로드될 폴더의 절대경로
		String uploadPath = request.getServletContext().getRealPath("/") + upath;
		File fpath = new File(uploadPath);
		if(!fpath.exists()) fpath.mkdirs(); //폴더 생성
		try {
			//transferTo : file(업로드되는 파일내용)을 업로드폴더의 원본파일 이름으로 저장
			file.transferTo(new File(uploadPath + orgFile));
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	public void itemUpdate(Item item, HttpServletRequest request) {
		if(item.getPicture() != null && !item.getPicture().isEmpty()) { 
			uploadFileCreate(item.getPicture(),request,"img/");
			item.setPictureUrl(item.getPicture().getOriginalFilename());
		}
		itemDao.update(item);
	}

	public void itemDelete(Integer id) {
		itemDao.delete(id);
	}

	public void userInsert(User user) {
		userDao.insert(user);
	}

	public User userSelectOne(String userid) {
		return userDao.selectOne(userid);
	}
	/*
	 * sale,saleitem 테이블에 저장하기
	 * 1. sale 테이블의 saleid의 최대값 조회 : 최대값+1
	 * 2. sale 정보 저장 : userid,sysdate
	 * 3. Cart데이터에서 saleitem 데이터 추출. insert
	 * 4. saleitem 정보를 sale 데이터 저장.
	 * 5. sale 데이터 리턴
	 */
	public Sale checkend(User loginUser, Cart cart) {
		//1. sale 테이블의 saleid의 최대값 조회 : 최대값+1
		int maxid = saleDao.getMaxSaleId();
		//2. sale 테이블 등록
		Sale sale = new Sale();
		sale.setSaleid(maxid + 1);
		sale.setUserid(loginUser.getUserid());
		sale.setUser(loginUser);
		saleDao.insert(sale);
		//3. Cart데이터에서 saleitem 데이터 추출. insert
		int seq = 0;
		for(ItemSet is : cart.getItemSetList()) {
			SaleItem saleitem = new SaleItem(sale.getSaleid(), ++seq, is);
			sale.getItemList().add(saleitem);
			saleItemDao.insert(saleitem);
		}
		return sale;
	}

	public List<Sale> salelist(String id) {
		List<Sale> list = saleDao.list(id); //sale 테이블에서 사용자 id에 해당하는 목록 조회
		for(Sale sa : list) {
			//주문번호에 해당하는 주문상품 목록 조회
			List<SaleItem> saleitemlist = saleItemDao.list(sa.getSaleid());
			for(SaleItem si : saleitemlist) {
				Item item = itemDao.selectOne(si.getItemid()); //주문상품의 상품데이터(item) 조회
				si.setItem(item);
			}
			sa.setItemList(saleitemlist);
		}
		return list;
	}

	public void userUpdate(@Valid User user) {
		userDao.update(user);
	}

	public void userChgPassword(String userid, String chgpass) {
		userDao.passwordupdate(userid,chgpass);
	}

	public void userDelete(String userid) {
		userDao.delete(userid);
	}

	public List<User> userlist() {
		return userDao.list();
	}

	public String getSearch(User user, String url) {
		return userDao.search(user, url);
	}

	public int boardcount(String boardid) {
		return boardDao.count(boardid);
	}

	public List<Board> boardlist(Integer pageNum, int limit, String boardid) {
		return boardDao.list(pageNum, limit, boardid);
	}
	//board : 화면에서 입력한 파라미터정보, 업로드된 파일 정보
	public void boardwrite(Board board, HttpServletRequest request) {
		//파일 업로드
		if(board.getFile1() != null && !board.getFile1().isEmpty()) { //업로드된 파일이 존재.
			uploadFileCreate(board.getFile1(), request, "board/file/"); //파일 업로드
			board.setFileurl(board.getFile1().getOriginalFilename());
		}
		//db에 insert
		boardDao.write(board);
	}

	public Board getBoard(Integer num) {
		return boardDao.selectOne(num);
	}

	public void readcntadd(Integer num) {
		boardDao.readcntadd(num);
	}
	public void boardUpdate(Board board, HttpServletRequest request) {
		if(board.getFile1() != null && !board.getFile1().isEmpty()) { //첨부파일이 수정된 경우
			uploadFileCreate(board.getFile1(), request, "board/file/"); //파일 업로드
			board.setFileurl(board.getFile1().getOriginalFilename());
		}
		boardDao.update(board);
	}
	public void boardReply(Board board) {
		boardDao.grpStepAdd(board);
		boardDao.reply(board);
	}

	public void boardDelete(int num) {
		boardDao.delete(num);
	}
}

ItemDao.java

package dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;

import logic.Item;
//http://localhost:8088/springmvc1/item/list
@Repository //@Component + db관련 객체
public class ItemDao {
	//NamedParameterJdbcTemplate : 스프링 프레임워크에서 설정한 jdbc관련 클래스
	private NamedParameterJdbcTemplate template;
	private Map<String,Object> param = new HashMap<String,Object>();
	private RowMapper<Item> mapper = new BeanPropertyRowMapper<>(Item.class);
	public List<Item> list;
	@Autowired //DataSource 객체 주입
	public void setDateSource(DataSource dataSource) { //DriverManagerDataSource 객체
		template = new NamedParameterJdbcTemplate(dataSource);
	}
	public List<Item> list() {
		//query(sql구문,파라미터값,맵퍼) : 여러개의 레코드 조회할 때 사용하는 메서드
		//mapper : 설정클래스(Item, class)의 프로퍼티와 조회된 db의 컬럼 매핑하는 객체. db의 레코드 한개 정보가 Item 객체로 매핑됨
		return template.query("select * from item order by id", param, mapper);
	}
	public Item selectOne(Integer id) {
		param.clear();
		param.put("id", id);
		//queryForObject(sql구문,파라미터값,맵퍼) : 한개의 레코드만 조회될 때 사용하는 메서드. 조회되는 레코드가 여러개인 경우 오류 발생
		//해당 레코드가 없는 경우 EmptyResultDataAccessException 예외 발생
		return template.queryForObject("select * from item where id=:id", param, mapper);
	}
	public int maxId() {
		return template.queryForObject("select nvl(max(id),0) from item ", param, Integer.class);
	}
	/*
	 * item 객체의 등록된 정보
	 * id : item 테이블에 등록된 최대 id값 + 1
	 * name, price, description : 화면에서 입력된 파라미터 값
	 * pictureUrl : 업로드된 파일 이름
	 */
	public void insert(Item item) {
		// item 객체의 프로퍼티 이름을 파라미터로 사용
		// :id => item.getId() 호출
		SqlParameterSource param = new BeanPropertySqlParameterSource(item);
		String sql = "insert into item (id, name, price, description, pictureUrl)"
				+ " values (:id, :name, :price, :description, :pictureUrl)";
		template.update(sql, param); //item 내용 추가
	}
	public void update(Item item) {
		SqlParameterSource param = new BeanPropertySqlParameterSource(item);
		String sql = "update item set name=:name, price=:price, description=:description,"
				+ "pictureUrl=:pictureUrl where id=:id";
		template.update(sql, param); //item 내용 수정
	}
	public void delete(Integer id) {
		param.clear();
		param.put("id",id);
		template.update("delete from item where id=:id", param);
	}
}

oracle_shop.sql

create table item (
   id number primary key,
   name varchar2(30),
   price number,
   description varchar2(100),
   pictureUrl varchar2(30)
);
select * from item;
insert into item values (1, '레몬', 50,  '레몬에 포함된 구연산은 피로회복에 좋습니다.   비타민C 도 풍부합니다.','lemon.jpg');
insert into item values (2, '오렌지', 100, '비타민C 가 풍부합니다. 맛도 좋습니다.','orange.jpg');
insert into item values (3, '키위', 200,  '비타민C 가 풍부합니다. 다이어트에 좋습니다.','kiui.jpg');
insert into item values (4, '포도', 300,  '폴리페놀을 다량 함유하고 있어 항산화 작용을 합니다.',  'podo.jpg');
insert into item values (5, '딸기', 800,  '비타민C를 다량 함유하고 있습니다.',  'ichigo.jpg');
insert into item values (6, '귤', 1000,  '시네피린을 다량 함유하고 있어 감기예방에 좋습니다.',  'mikan.jpg');
commit;

CREATE TABLE sale (			 	 --주문정보
   saleid number PRIMARY KEY,    --주문번호
   userid varchar2(10) NOT NULL, --사용자 아이디
   saledate date				 --주문일자
);

-- saleis	seq
--    1      1
--    1      2
--    1      3
--    2      1
--    2      2
--    2      3
--    2      4

CREATE TABLE saleitem (					   --주문상품
	saleid number REFERENCES sale(saleid), --주문번호
	seq number ,						   --주문상품 번호
	itemid number REFERENCES item(id),	   --주문상품 아이디
	quantity number ,					   --주문상품 수량
	PRIMARY KEY (saleid, seq)			   --기본키 : saleid + seq
);

select * from sale;
select * from saleitem;
-- create 이후에 외래키 설정 구문 
ALTER TABLE saleitem 
 ADD CONSTRAINT saleitem_itemid_fk FOREIGN KEY(itemid)
 REFERENCES item(id) ;
728x90
반응형