728x90

때때로 정리를 했었는데 막상 다시하려니 무엇부터 봐야 할지 고민되네요.

다시 정리해 봅니다. 

무척 돌아가는 정리가 될것 같네요.

파일럿 서비스로 동작유무 정도의 목적으로 기존 생각을 정리 목적 정도 되겠네요.

 

가. 설치 : 필요 항목들 설치 ( 2023.4 최신 LTS 버전 기준으로 검토 )

나. 목표 화면 : spring boot 3.0 으로 테스팅 화면 

2023.04.21 - [프로그램/Web] - spring boot vscode로 oracle table 조회 실행해보기(2023.4)

다. 백앤드는 spring boot 기존 사용했던 것을 restFull api 추가해서 json 형태로 조회

화면 라우팅은 nextjs 13 기본으로 사용

 

게시판 관련해서 이전에 만든것을 확인하고 react 로 만들어 봅시다. 

jsp 로 간단하게 보여준 내용

예제를 좀더 신경써야 겠지만 테스트 화면이라. 일단 주요 동작만 확인용입니다.

nextjs 13 프로젝트 생성하면 기본으로 들어가있는 css 가 "tailwindcss 3.3.1"이 공부가 필요한 상황이네요.

layouts 이 기본적으로 사용할수 있고 랜더링도 layouts 에 설정되어 있는 부분별로 관리를 할 수 있다고 하네요.

그래서 만들어진 내용부터 보고 코드를 봅시다.

 

next.js 13 react 

1. /app/pages.tsx , /app/Layout.tsx :  layout 적용

더보기

/app/Layout.tsx

import './globals.css'
import { Layout } from "@/app/layouts/Layout"


export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <Layout>
          {children}
        </Layout>
      </body>
    </html>
  )
}

 /app/pages.tsx 

import './globals.css'
import Link from 'next/link';

export default function Home() {
  return (
    <div >
      <div >
        <div>
          test text  (app/page.tsx)
          Hello. React! Nextjs !
          <br />
          <Link href="/booklist">list</Link>
        </div>
      </div>
    </div>
  )
}

2. /app/layouts/layout.tsx , /app/layouts/Header.tsx : 레이아웃

더보기

/app/layouts/layout.tsx 

"use client" 

import React from 'react';
import { Header } from './Header'
import styled from "styled-components";

const BodyContainer = styled.div`
display: inline-block;
font-weight : bold;
display: flex;
width : 100%;
margin: 0 auto;
justify-content: center
`;

const LeftMenuContainer = styled.div`
display: inline-block;
float: left;
width : 28%;
display: none;
`;
const RightBodyContainer = styled.div`
float: left;
width : 68%;
`;

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <div id="wrap">
      <div >
        <Header />
      </div>
      <BodyContainer>
        <RightBodyContainer>{children}</RightBodyContainer>
      </BodyContainer>
    </div >
  );
}

/app/layouts/Header.tsx

'use client';

import React from 'react';
import Link from 'next/link';
import styled from "styled-components";

const HeadContainer = styled.div`
font-size: large;
font-weight : bold;
display: flex;
margin: 2em auto;
vertical-align: middle;
width: 100%;
display: block;
text-align: center;
`;

const MenuContainer = styled.div`
display: inline-block;
float: right;
float : right;
`;

const MenuUl = styled.ul`
list-style:none;
margin:0 0 0 0;
padding:0;
display: flex;
`;

const MenuLi = styled.li`
margin: 10px;
padding: 0 0 0 0;
list-style:none;
border : 0;
float: left;
`;

export function Header() {
  return (
    <div id="header-sec">
      <HeadContainer className="inner">
        <div>
          <h1><Link href="/hello">파일럿 게시판 </Link></h1>
        </div>
        <MenuContainer>
          <MenuUl className="utilmenu">
            <MenuLi className="logout"><a href="#">로그아웃</a></MenuLi>
            <MenuLi className="mypage"><Link href="/mypage">마이페이지</Link></MenuLi>
          </MenuUl>
        </MenuContainer>
      </HeadContainer>
    </div>
  );

}

3. /app/booklist/page.tsx , /ui/Bookboard.tsx, /ui/Bookboard-tr.tsx : 게시판

더보기

/app/booklist/page.tsx

import { Bookboard } from '@/ui/Bookboard';


export default function Page() {
  return (
    <div className="relative overflow-x-auto shadow-md sm:rounded-lg">
       <Bookboard >test com</Bookboard>
      
      <a href="/">홈</a>
    </div>
  );
}

/ui/Bookboard.tsx

'use client';

import * as React from 'react';
import PropTypes from 'prop-types';

import {Bookboardtr} from "@/ui/Bookboard-tr"
import styled from "styled-components"

export const Bookboard = ({
  children
}: {
  children: React.ReactNode;
}) => {
  const [loading, setLoading] = React.useState(true);
  const [booklist, setBooklist] = React.useState<any[]>([]);
  const getBooklist = async ()=>{
    const json = await(
      await fetch("http://localhost:8082/api/list")
    ).json();
    console.log(json.data.booklist);
    setBooklist(json.data.booklist);
    setLoading(false);
  };
  React.useEffect(()=>{
    getBooklist();
  },[]);
  
  return (
    <div>
      <table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
        <thead className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
          <tr>
            <th scope="col" className="px-6 py-3">번호</th>
            <th scope="col" className="px-6 py-3">글쓴이</th>
            <th scope="col" className="px-6 py-3">제목</th>
            <th scope="col" className="px-6 py-3">설명</th>
          </tr>
        </thead>
        <tbody>
              {
                booklist.map((Book)=>(
                  <Bookboardtr key={Book.myname}
                  myno={Book.myno}
                  myname={Book.myname}
                  mytitle={Book.mytitle}
                  mycontent={Book.mycontent}/>
                  ))
                }
        </tbody>
      </table>

    </div>
  );

/ui/Bookboard-tr.tsx 

import * as React from 'react';

export const Bookboardtr = ({
  myno,
  myname,
  mytitle,
  mycontent
}: {
  myno: number;
  myname: string;
  mytitle: string;
  mycontent: string;
}) => {
  return (
    <tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
        <td scope="row" className="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
          <a href="/booklist/${myno}">{myno}</a></td>
        <td className="px-6 py-4">{myname}</td>
        <td className="px-6 py-4">{mytitle}</td>
        <td className="px-6 py-4">{mycontent}</td>
    </tr>
  );
};

이번 목표는 조회조건이나 기타 조건은 일단배제하고 단순 API호출해서 데이터를 정상적으로 보여주는 것으로 했다.

빠른 테스트를 위해 데이터는 Bookboard.tsx에서 가져왔지만 app/api 폴더에 데이터를 가져오는 모듈을 만들고 /app/booklist/page.tsx 에서 조회 모듈 또는 스토어에서 검색조건을 가져와서 조회하여 결과를 Bookboard.tsx으로 넘겨주는 구조로 수정하면 좋을 것으로 보인다. 

 

 여기까지가 실제 코딩 부분이고 아래쪽은 설치와 라이브러리 검토내역입니다. 

 개발을 하게 된다면 next js 13 렌더링(클라이언트/서버/하이브리드 랜더링)과 css 부분에 대해서는 시간을 투자하는 것이 좋을 것 같네요.

 

spring boot api 추가부분 , 조회 결과를 json array 로 처리하는 부분과 크로스서버(CORS:Cross-Origin Resource Sharing) 문제 대응해 놓았습니다. 개인적으로 json 결과값 넘기는 것이 라이브러리에 종속적이라 시간이 더 걸린것 같네요. ( 여러 상황이 발생할 수 있깅에 에러 메시지를 항상 확인하길 바랍니다. )

더보기

.../ controller / RestBoardController.java

package com.board.spbt2.board.controller;

import com.board.spbt2.board.model.biz.MyBoadBiz;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.Gson;
import com.google.gson.JsonObject;

@CrossOrigin(origins="http://localhost:3005")
@RestController
public class RestBoardController {
  @Autowired
  private MyBoadBiz biz;
 Gson gson = new Gson();

  @RequestMapping(value = "/api/list")
  public String selectAllList() {

    JsonObject resultjsonObj = new JsonObject(); // 전상 조회여부와 결과값 전달용
    
    JsonObject jsonObj = new JsonObject();  // 조회값
    jsonObj.add("booklist",gson.toJsonTree(biz.selectList()));
   
    resultjsonObj.addProperty("status","ok");
    resultjsonObj.addProperty("status_message","Query was successful");
    resultjsonObj.add("data", jsonObj);
    
    return resultjsonObj.toString();
  }
}

--------- 설치 --------------------

가장 기본이 되는 Node.js, React, Express 는 필요하다면 공홈을 보시길 추천합니다.

node.js 에 react.js 라이브러리를 올리면 프론트 express를 올리면 백앤드 정도로 생각하면 될 것입니다. 

 

 react 프로젝트라고 하지만 다양한 라이브러리를 상황에 맞춰 레고처럼 조립한다고 생각해야 합니다.

 그리고 Open Source라고 생각하고 마구 사용하면 나중에 문제가 될수 있기 때문에 라이브러리별로 꼭 라이센스를 확인해야 합니다.

 여기서 중요한 점!! 젊은 언어는 버전업이 빠르기 때문에 프로젝트에서 사용하는 시점에 개선된부분을 참고해서 버전 선택도  중요합니다. ( 호환성이 깨지는 경우가 드물다고 해도 발생할 수 있으니 버전별 호환성 테스트는 필요합니다. )

 

 react 프로젝트는 일단 목업으로 만들고 백앤드와 연결하는 방식으로 개발하면 됩니다. 데이터 스토어는 리덕스와 리코일을 사용해 봤는데, 정리용으로 만드는 제한이 없으니 페이스북에서 만들었다는 상태관리 라이브러리인 recoil를 사용해 보겠습니다.


우선 지난번 정리 링크입니다. 다시시작하는 사람입장에서 2022년에 정리했던 것인데 올해도 다시 하네요.

2022.06.14 - [프로그램/react] - 리액터 스타트(2022.06.14)

 

리액터 스타트(2022.06.14)

react 초기 설정 공유 합니다. 개발툴 VSCODE NODE.JS HTTPS://nodejs.org/ko ( LTS 버전 16.15.1 LTS ) 리액트홈페이지 : https;//ko.reactjs.org/ git 2.36.1 https://git-scm.com/download/win --- testapp 생성해보기 npx create-react-app my-

jsi0.tistory.com

컴퓨터에 지난번에 설치한 node v16이 설치되어 있네요.

1. node 개발 버전 선택 및 해당버전 설치

  - LTS버전이 현재 v18.16이니 업데이트 해야 겠네요.

     현재는 window11에서는 고생하지 마시고 공홈에서 설치본 받아서 설치하는 것을 추천합니다.

   a. 설치본으로 재설치 : 제일 깔끔한건 윈도우는 설치본 재설치 일것 같습니다. 

   b. npm으로 n 패키지 설치하여 버전업하기 <-- 윈도우11버전에서 정상동작을 안하네

   c. nvm 를 통한 버전 업데이트 <-- npm으로 설치시 정상 동작 안합니다. 

b. n 패키지를 사용하기
# 우선 캐시 정리
> npm cache clean -f

# nodejs 버전관리하는 n 이라는 모듈 설치
> npm install -g n   // 현재 버전은 9.1.0인데 win32만 지원한다고 나오네요.
( windows 11 버전 지원이 안되나 보네요 )
npm ERR! notsup Unsupported platform for n@9.1.0: wanted {"os":"!win32"} (current: {"os":"win32","arch":"x64"})

# 명시된 버전으로 설치 
> n llatest   // 최신버전
> n lts       // lts 버전
> n stable    // 안정버전

# npm  업데이트
> npm i -g npm 

c. nvm 설치
https://github.com/coreybutler/nvm-windows

# npm 으로 nvm 설치
>npm install -g nvm
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
npm WARN deprecated nvm@0.0.4: This is NOT the correct nvm. Visit https://nvm.sh and use the curl command to install it.

# 정상동작이 안되네요. 삭제
>npm uninstall -g nvm

# node 버전 업데이트 // 결국 못해봤네요.
> nvm use newest   // 노드 최신버전으로 업데이트

결국 선택 window 설치본 언인스톨 후 msi 설치본으로 설치했습니다. 

https://nodejs.org/en/download

 

Download | Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

Chocolatey 선택체크했더니 자동으로 관리자 모드로 PowerShell 실행해서 필요한 모듈들을 다운 받아집니다. 

C:\Users\laneb>npm -v
9.5.1

C:\Users\laneb>node -v
v18.16.0

 인스톨하면서 나오는 메시지를 보니 아직은 window11은 개발 환경으로 사용하는 것을 말리고 싶네요. 최적화가 아직 안되어 있습니다. ( 2023.04 )

 안되는 것들이 많네요. 

 이번에 파일럿으로 게시판 만드는 것이 안되면 개발 환경을 dorker에 올려봐야 겠네요.

 아니면 window10에서 해봐야 겠네요. 일단 도전. window11 환경입니다.

---- 테스트 중

※ plugin 확인 beauty : Ctrl + A -> Ctrl + Shift + B 웹기반언어(html,css,javascript 등) 코드 자동정렬, 줄 맞춤


 이제 사용할 라이브러리 검토중....

2023.04.24 - [프로그램/react] - react 플젝 라이브러리 검토 ( 2023.4 )

2023.04.24 - [프로그램/react] - nextjs 13 검토 ( 2023.4 )

 

 


※ nextjs 구조를 선택해서 구조를 잡아 봅시다. 100% 활용은 당장을 힘들어도 확장성을 고려해서 구조를 선택했습니다.

 

참고 react notice board 프로젝트 생성 ( 프로젝트 베이스 설정을 react로 하는 경우 )

더보기
> npx create-react-app ranb-app

> cd ranb-app

> npm start

프로젝트 생성 ( next.js 13 )

> 버전 조건 : Node.js 16.8 or later. 
> 현재 설치 버전 : v18.16.0

# 프로젝트를 바로 생성하는거 
> npx create-next-app@latest next13test-app
> npx create-next-app@latest next13test-app
√ Would you like to use TypeScript with this project? ... No / Yes
√ Would you like to use ESLint with this project? ... No / Yes
√ Would you like to use Tailwind CSS with this project? ... No / Yes
√ Would you like to use `src/` directory with this project? ... No / Yes
√ Would you like to use experimental `app/` directory with this project? ... No / Yes
? What import alias would you like configured? » @/*

Installing dependencies:
- react
- react-dom
- next
- typescript
- @types/react
- @types/node
- @types/react-dom
- tailwindcss
- postcss
- autoprefixer
- eslint
- eslint-config-next

그럼 package.json 파일이 자동생성됩니다.

더보기
{
  "scripts": {
    "dev": "next dev",        // 개발 모드로 시작합니다.
    "build": "next build",    //실가동용 어플리케이션을 빌드합니다.
    "start": "next start",    //Next.js 실가동 서버를 기동합니다.
    "lint": "next lint"       //Next.js의 내장 ESLint 구성을 설정합니다.
  },
    "dependencies": {
    "@types/node": "18.16.0",
    "@types/react": "18.0.38",
    "@types/react-dom": "18.0.11",
    "autoprefixer": "10.4.14",
    "eslint": "8.39.0",
    "eslint-config-next": "13.3.1",
    "next": "13.3.1",
    "postcss": "8.4.23",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.1",
    "typescript": "5.0.4"
  }
}

그리고 절대 경로 관련해서 프로젝트 생성시 입력한 것이 설정파일에 반영되어 있습니다. ( tsconfig.json )

더보기
...
    "paths": {
      "@/*": ["./*"]
    }
...

[ /next.config.js ]  /app 폴더 사용시 추가, 프로젝트 생성시 추가해서 자동생성되어 있음.

더보기
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
};

module.exports = nextConfig;

 [ /app/layout.tsx ] <html> 와 <body> tags 가 필요함. 자동생성되어 있음

더보기
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

[ /app/page.tsx ] 자동생성되어 있음

더보기
export default function Page() {
  return <h1>Hello, Next.js!</h1>;
}

app폴더 만들고 layout.tsx 와 page.tsx 파일을 추가하면, 

사용자가 응용 프로그램의 루트를 방문할 때 렌더링됩니다.

 

728x90
728x90

 개발 스펙을 검토중이라면 각 구성항목의 버전별 지원여부와 유무료 정책 및 버전별 특성을 확인하시는 습관을 들이기 바랍니다. 연습하거나 공부용이라면 이점을 확인 안하는 경우가 많아서 막상 필드에서 고민하는 그런점에서 당황하기도 합니다.

 열심히 개발 스펙을 검토 확정된 다음 파일럿 페이지를 구성할 때 참고용으로 적어 봅니다.

 spring boot 3.x, vscode 사용, 메이븐 프로젝트

 

최종 결과

이번에는 단순 조회페이지를 만들어 보겠습니다.

1. 프로젝트 생성

mybatis가 sprint boot 3.1 이하 2.6 이상을 지원하는 관계로 3.06를 선택하였습니다.

생성된 프로젝트 루트 pom.xml 참고하시면 반영된 것을 확인할 수 있습니다.

 

※ 처음에는 jsp를 사용 안하려 했는데 중간 과정에서 사용해보자는 마음에서 시작했는데 역시나 최신버전으로 셋팅하면서 버전문제가 발생하였고 하루라는 시간을 허비하고 삽질을 정리하게 되었네요. 역시 개발을 위한 셋팅은 삽질이네요. spring boot 로 넘어가면서 호환버전 동기화가 좋아졌다고 생각했는데 추천하는 방식을 벗어나면 힘든거네요.

 

※ 샘플 파일럿 세팅 : jsp를 vscode 로 사용해서 테스트에는 war를 추천하네요.

java 17 오라클 사이트에서 설치해도 되고 "amazon openjdk version" 검색해서 설치하셔도 됩니다. 

mvn 3.9  설치는 https://maven.apache.org/download.cgi 여기서 하면됩니다.

mvn 의존성 라이브러리 조회는 https://mvnrepository.com/ 여기서 하면됩니다.

DB는 오라클에서 개발프리로 열어준 것을 사용했습니다.

2023.04.21 - [프로그램/Web] - Oracle23c 도커 설치 후 테스트 계정 생성(2023.4)

 

Oracle23c 도커 설치 후 테스트 계정 생성(2023.4)

테스트 프로그램 만들고 확인할 용으로 적어 봅니다. 2023.04.15 - [프로그램/짜투리상식] - Dorker에 Oracle 설치(2023.04) Dorker에 Oracle 설치(2023.04) 도커 설치 후 오라클 공식 홈페이지에 접속하여 최신

jsi0.tistory.com

설정내용 : jsp 폴더지정, 인코딩, DB접속, DTO 설정

- 리소스 폴더는 css사용용인데 적용은 안했네요.

폴더구조

1. application.properties  

더보기

1. application.properties  

# server
server.port=8082

# view 
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

#encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
server.servlet.encoding.force-response=true
server.servlet.encoding.enabled=true

#resources
spring.mvc.static-path-pattern=/resources/**

#jdbc
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:FREE
spring.datasource.username=tpuser
spring.datasource.password=tpuserpw

# mybatis alias
mybatis.type-aliases-package = com.board.model.dto.MyDto

2. pom.xml

더보기

2. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.6</version>
		<relativePath/>
		<!-- lookup parent from repository -->
	</parent>
	<groupId>com.board</groupId>
	<artifactId>spbt2</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>spbt2</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc8</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!-- JSP -->
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>
<!-- 구버전 jstl 유효값체크에서 에러남
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
-->
		<!-- jstl -->
		<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->

		<dependency>
			<groupId>jakarta.servlet.jsp.jstl</groupId>
			<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
			<version>3.0.0</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
		<dependency>
			<groupId>jakarta.servlet</groupId>
			<artifactId>jakarta.servlet-api</artifactId>
			<version>6.0.0</version>
			<scope>provided</scope>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jakarta.servlet.jsp.jstl</artifactId>
			<version>3.0.1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

 

3. MyBoardController.java

더보기

3. MyBoardController.java

package com.board.spbt2.board.controller;

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 com.board.spbt2.board.model.biz.MyBoadBiz;

//import java.util.List;
//import com.board.spbt2.board.model.dto.MyDto;

@Controller
public class MyBoardController {
    
    @Autowired
    private MyBoadBiz biz;

    @GetMapping("/list")
    public String selectList(Model model){
        model.addAttribute("blist", biz.selectList());
        /*
         * System.out.println("selectList");
         * System.out.printf(" 결과 : %d \n", biz.selectList().size());
         * List<MyDto> list = biz.selectList();
         * System.out.printf(" 결과 : %s \n", list.get(0).getMyno());
         */
        return "boardlist";

    }

    @GetMapping("/")
    public String Welcom(){
        System.out.println("step 000 Welcom");
        return "index";
        
    }
}

 

4. MyBoadBiz.java

더보기

4. MyBoadBiz.java

package com.board.spbt2.board.model.biz;

import java.util.List;

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

import com.board.spbt2.board.model.dto.MyDto;
import com.board.spbt2.board.model.mapper.MyBoardMapper;

@Service
public class MyBoadBiz {

	@Autowired
	private MyBoardMapper mapper;
	
	public List<MyDto> selectList() {
		return mapper.selectList();
	}
	
	public MyDto selectOne(int myno) {
		return mapper.selectOne(myno);
	}
	
	public int insert(MyDto dto) {
		return mapper.insert(dto);
	}
	
	public int update(MyDto dto) {
		return mapper.update(dto);
	}
	
	public int delete(int myno) {
		return mapper.delete(myno);
	}
	
}

 

5. MyDto.java

더보기

5. MyDto.java

package com.board.spbt2.board.model.dto;

import java.util.Date;
import java.io.Serializable;

public class MyDto implements Serializable {
	
	private int myno;
	private String myname;
	private String mytitle;
	private String mycontent;
	private Date mydate;
	
	public int getMyno() {
		return myno;
	}
	public void setMyno(int myno) {
		this.myno = myno;
	}
	public String getMyname() {
		return myname;
	}
	public void setMyname(String myname) {
		this.myname = myname;
	}
	public String getMytitle() {
		return mytitle;
	}
	public void setMytitle(String mytitle) {
		this.mytitle = mytitle;
	}
	public String getMycontent() {
		return mycontent;
	}
	public void setMycontent(String mycontent) {
		this.mycontent = mycontent;
	}
	public Date getMydate() {
		return mydate;
	}
	public void setMydate(Date mydate) {
		this.mydate = mydate;
	}
	
}

 

6. MyBoardMapper.java

더보기

6. MyBoardMapper.java

package com.board.spbt2.board.model.mapper;
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.Select;
import org.apache.ibatis.annotations.Update;

import com.board.spbt2.board.model.dto.MyDto;

@Mapper
public interface MyBoardMapper {
    
    @Select(" SELECT MYNO, MYNAME, MYTITLE, MYCONTENT, MYDATE FROM MYBOARD ORDER BY MYNO DESC ")
	List<MyDto> selectList();
	
	@Select(" SELECT MYNO, MYNAME, MYTITLE, MYCONTENT, MYDATE FORM MYBOARD WHERE MYNO = #{myno} ")
	MyDto selectOne(int myno);
	
	@Insert(" INSERT INTO MYBOARD VALUES(MYNOSEQ.NEXTVAL, #{dto.getMyname}, #{mytitle}, #{dto.mycontent}, SYSDATE) ")
	int insert(MyDto dto);
	
	@Update(" UPDATE MYBOARD SET MYTITLE = #{mytitle}, MYCONTENT=#{mycontent} WHERE MYNO = #{myno}  ")
	int update(MyDto dto);
	
	@Delete(" DELETE FROM MYBOARD WHERE MYNO = #{myno} ")
	int delete(int myno);
}

 

7. boardlist.jsp

더보기

7. boardlist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="com.board.model.dto.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>책목록</title>
        <link rel="stylesheet" href="https://s3.ap-northeast-2.amazonaws.com/materials.spartacodingclub.kr/easygpt/default.css">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
            integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
            crossorigin="anonymous"></script>
        <style>
            .titleRed {
                color: red 
            }
        </style>
    </head>    

<body>

    <table class="table" >
        <thead>
            <tr>
                <th>번호</th>
                <th>글쓴이</th>
                <th>제목</th>
                <th>작성일</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach var="dto" items="${blist}">
                <tr>

                    <td><a href="/myboard/detail?myno=${dto.getMyno()}">${dto.getMyno()}</a></td>
                    <td>${dto.getMyname()}</td>
                    <td>${dto.getMytitle()}</td>
                    <td>${dto.getMycontent()}</td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    <a href="/">홈</a>
</body>
</html>

 

 비주얼하게 바꾸고 싶지만 좀더 다른 언어도 손을 쓰고 싶으니 작업해서 git에 올리고 수준은 그때 올리는 것으로 해볼께요. 

 자 다음은 react 로 동일하게 만들어봅시다. 버전이 또 얼마나 올라갔을지 걱정스럽네요.

 

728x90

+ Recent posts