반응형

다음에는 회원번호를 사용하여 PathVariable을 사용하여 

/users/{id} 이런식으로 데이터를 받아

2번이면 

id : 2

name : seok

 

이런식으로 데이터를 받아와보자 

우선 서비스 객체를 보자 

    public User findOne(int id){
        for(User user : users){
            if(user.getId() == id){
                return user;
            }
        }
        return null;
    }

 

save라는 메소드를 사용했다. 

우선 id를 비교하여 데이가 있다면 해당 user를 비교하여 데이터가 있다면

user를 리턴해준다.

만약 데이터가 없다면 null을 반영한다. 

 

@GetMapping("/users/{id}")
public User retrieveUser(@PathVariable int id){
    return service.findOne(id);
}

 

그 후 pathvariable을 사용하여 int를 서비스로 넘겨 비교한 후 클라이언트에게 

가져온 아이디를 리턴한다. 

 

2번 데이터를 리턴해보자 

 

 

이렇게 포스트맨으로  2번 데이터를 받아올 수 있다. 

만약 없는 데이터가 오면 null이 올것이다. 

 

다음에는 글 등록을 해보자

반응형
반응형

Rest API을 연습해보고자 한다

현재는 Get + POST만 사용했는데

Put과 Delete를 쓰려고 한다. 

 

 한번 사용해보자 

 

우선 데이터베이스를 쓰지 않고 메모리에 저장하는 형식으로 사용해보고자 한다. 

import java.util.Date;

@Data
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private Date joinDate;
}

우선 모델객체를 생성해주고 Lombok을 사용하려고 한다. 

 

그 후 service 객체를 생성해보자 

 

그 후 데이터 베이스를 사용하지 않기 떄문에 

실행과 동시에 반영이 가능한 static 변수를 사용하여 

List 타입을 만들고 id 1,2,3을 만들어서 기본 데이터 모델을 사용하려고 한다. 

public class UserDAOService {
    private static List<User> users = new ArrayList<>();
    private static int usersCount = 3;

    static {
        users.add(new User(1,"Moon", new Date()));
        users.add(new User(2,"Seok", new Date()));
        users.add(new User(3,"Huyn", new Date()));
    }

먼저 findAll 이라는 생성하여 위 데이터를 Rest api 방식을 사용하여 출력을 하여보자 

 

    public List<User> findAll(){
        return users;
    }

그 다음 컨트롤러를 사용해보자 

 

@RestController
public class userController {
    @Autowired
    private UserDAOService service;

    @GetMapping("/users")
    public List<User> retrieveAllusers(){
        return service.findAll();
    }

리스트 타입으로 GET방식으로 받아보자 

 

다음은 포스트 맨으로 

locallhost:8989/users 로 접속을 해보자

 

이런식으로 데이터를 잘 받아 오는 것을 알 수 있다. 

 

반응형
반응형

 

 

이전 버전에서 무료 버전인 IntelliJ Community 버전을 설치 해보았다.

Community 버전과 Ultimate 버전은 다음과 같이 기능 차이가 있다.

 

 


기능이 풍부한 Ultimate 버전을 사용하려면 유료 라이센스를 구입해야 한다.

다만 아직까진 학생들에게는 무료로 사용할 수 있는 라이센스를 제공하고 있다.

학생 인증을 통하여 무료로 사용할 수 있다고 하여 학생 인증방법을 포스팅 해보려 한다.

 

 

 

 

1. 인증 페이지 접속

▶ 1. JetBrains 사이트 접속

※ Jet Brains의 학생 인증 관련 계속 바뀌고 있고, 앞으로도 UI는 바뀔 수 있으니 다음 url로 직접 접속 하여 인증 하기 클릭 하도록 하자.

www.jetbrains.com/community/education/#students

 

 - 하단으로 내려가 "Apply now" 클릭

 

 

 

▶ 2. 정보 입력 및 신청

 - 인증을 위한 정보를 입력한다.

 - Email address에 학교 이메일 계정 입력 (ex id@ssu.ac.kr)

 

 

 - 다음과 같은 화면과 함께 학교 이메일주소로 인증 메일을 받아 볼 수 있다.

 

 

 

2. 학생 인증 처리

▶ 1. 학교 이메일 확인

 - 입력한 학교 이메일 주소로 로그인하여 인증메일을 확인 한다.

 - "Confirm Request" 클릭 

 

 

▶ 2. JetBrains 최종 인증

 - "JetBrains Account" 사이트 창이 열리고, 맨 아래로 스크롤 후 활성화된 "I Accept"를 클릭한다.

 

 

 

 - 회원 가입이 되어있지 않은 경우 우측 하단에 이메일을 입력 후 "Sign Up"을 클릭하여 회원 가입을 진행 한다.

 

 

 

- 회원 가입 완료 문구를 확인 후 가입한 이메일을 확인해 보자.

 

 

- 이메일 내용중 "Confirm your account" 클릭

 

 

 - 나머지 정보를 입력하여 회원 가입을 마무리 한다.

 

 

 - 이후 로그인 하여 확인 해 보면 학생 인증이 완료, 라이센스가 발급 된 것을 확인할 수 있다.

 

 

3. 다운로드 및 실행

▶ 1. IntelliJ IDEA 다운로드

 - 다운로드 사이트 접속

  https://www.jetbrains.com/idea/download/#section=windows

 - Ultimate 버전 다운로드 하여 설치 한다. (또는 Zip 파일로 다운로드하여 압축 해제 한다.)

 

 

 - 설치 방법은 다음 포스팅 참고

  https://goddaehee.tistory.com/195

 

▶ 2. 최종 실행 및 인증

 - 설치 또는 압축 해제 하여 IntelliJ를 실행 하자.

 - 최초 인증 계정 정보만 입력하면 인증이 완료 된다.

 

 

 

이로써 인텔리제이 학생 인증이 완료 되었다.

 

혹시라도 학교 E-mail에서 Jetbrains의 자동 메일이 필터 되어 걸러진다면, 

GitHub 학생인증이 되어있다면, 연동하여 인텔리 제이 학생인증을 완료할 수도 있다.

 

반응형
반응형

1) TREE

 

예를 들면 이런 조직도를 생각해보자 

예를들면 사장님도 있고 이사도 있고 뭐 경영지원팀이나 기타 등등이 있을 것이다. 

어떤 조직의 형태를  컴퓨터 프로그래밍 적으로 나타내는 것을 트리라고 한다. 

 

 

또다른 예로는 디렉토리가 있을것이다.

최상위 디렉토리 > 디렉토리 > 계속 반복 이다.

 

2) SET

 

한국어로는 집합이다. 

예전 수학시간에 배웠던

프로그래밍에서 집합은 추상적이기만 한게 아니고 주적이다. 

대학교에서 모임이라고 생각해보면 

각각의 농구 축구 등등 이것은 교집합이라고 생각하면 편 할 것같다. 

 

내가 생각할때 자료구조에서 가장 중요한 것은

 

 

예를 들어 책이 있다고 하자

 

책이 한권 일때는 관리가 필요 없다.

만약 책이 100권이라면 

내가 필요한 책을 찾으려면 엄청난 시간이 걸릴 것이다.

 

주제별 가나다 순으로 정리할 것이다.

 

이렇게 보관 하면 빠른속도로 찾을 수 있다는 장점이 있다. 

 

컴퓨터의 자료구조는

예를 들어 정리정돈의 진화 인거 같다. 

 

파일 > 책 > 책장 > 도서관 > 소셜인터넷 등 

이런식으로 말이다. 

 

 

반응형
반응형

이번에는 CRUD의 마지막 기능인

수정이다. 

 

수정은 데이터를 넘기는 방식이 너무 어려웠다. 

리엑트는 너무 새로운 방식이라 

 

여러가지 방법을 시도해보면 정말 공부를 많이 했다. 

 

우선 리엑트부터 보자

 

    return(
        <>
    <div>
        글번호 : {props.board.id}
    </div>
    <div>
        제목 : {props.board.title}
    </div>
    <div>
        내용 : {props.board.content}
    </div>
    <div>
        <button onClick={()=>{
            axios.get(`/board/delete?id=${props.board.id}`)
            alert('삭제완료');
            window.location.href ="/";
        }}>삭제</button> 
        <button><Link to={`/modify/${props.board.id}`}>수정</Link></button>
    </div>
        </>
    )
}

링크태그를 이용하여 /modify/글번호 로 이동시킨다. 

 

그 후 

 

 <form onSubmit={submitHandler}>
        <div>
            <input name='id' value={props.board.id} readOnly/>
        </div>
        <div>
            <input name='title' value={title} onChange={onChangeTitle}/>
        </div>
        <div>
            <textarea name='content' value={content} onChange={onChangeContent}></textarea>
        </div>
        <div>
        <button type="submit" onClick={()=>{
            alert("수정 완료");
            window.location.href = "/";
        }}>수정</button>
        </div>
    </form>

요론 수정.js를 생성해준다. 

그 후 메인에서 

 

      <Route path='/detail/:id' element={<Detail board={board}/> } />
      <Route path='/modify/:id' element={<Modify board={board}/> } />

이렇게 전달해준다. 

 

그럼 props로 데이터 전달이 가능하다. 

 

한가지 예외상황이 나왔다

 

리엑트에서는 input에 value를 쓰면 수정이 안된다...

수정을 해주려면 onchange속성을 써서 다시 값을 설정해주어야한다. 

 

    const [title, setTitle] = useState(props.board.title);
    const [content, setContent] = useState(props.board.content);

    const onChangeTitle = useCallback(e => {
        setTitle(e.target.value);
    },[])

    const onChangeContent = useCallback(e => {
        setContent(e.target.value);
    },[])

이런식으로 따로 설정을 해주었다. 

JSP나 타임리프에서는 그냥 됬는데 .. 리엑트 너란녀석 참 복잡하다. 

 

그렇게 한 후 원래는 form태그 안에 action 태그를 사용하여 데이터를 보냈지만 이렇게 하면 바로 

url로 타고가서 따로 페이지를 만들어주고 거기서 또 페이지 전환을 시켜줘야하기 떄문에 너무 번거롭다

이번엔 그래서 onsubmit 타입을 이용해서 변경해보자 .

 

    const submitHandler = (e) =>{
        e.preventDefault();
        console.log(props.board.id)
        console.log(title)
        console.log(content)

        const params = new URLSearchParams();

        params.append('id',props.board.id);
        params.append('title',title);
        params.append('content',content)

        axios.post('/board/modify',params)
        
    }

일단 e.preventDefault로 기능을 죽여준다. 

그 후 console.log로 각 데이터가 잘 오는지 확인 꼭 확인 할 필요는 없지만 나는 확인 .,. 

그 후 parmas라는 변수로 URLSearchParams를 객체로 선언해준다. 

 

그 후 위에 데이터를 append시켜 추가해준다. 

 

이것은 axios 공식홈페이지에서 나온 방법이다.

 

그후 post방식으로 url에 태워 보내면 form태그 적용 끝이다.

 

그 후 스프링부트를 보자 

 

    @PostMapping("/board/modify")
    public Integer modify(Board board){
        System.out.println(board.getId());
        System.out.println(board.getContent());
        return boardService.modify(board);
    }

이렇게 선언 해 준뒤 서비스객체를 보자

 

    public Integer modify(Board board){
        return boardRepository.save(board).getId();
    }

원래는 변경감지나 머지를 써야한다고 한다. 

나중에 한번 다시 해보자 

 

이렇게 하면 우선 끝이다.

 

작동을 시켜보자 

 

 

 

 

 

이렇게 수정이 완료되었다. 

 

이제는 페이징이랑 검색기능만 남았다 

 

이번주중으로 끝내고 다른거 공부해보자 

 

파이팅!

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 18 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

이번에 알아볼건 CRUD에서 정말 간단한 삭제이다.

나는 솔직히 데이터베이스에서 삭제를 하는것을 좋아하지않는다. 

왜냐하면 데이터는 항시 보존되어야한다고 생각한다.

그렇기떄문에 전에 프로젝트를 할 때도 타입을 주던가 y/n 이런식으로 구분을 했다.

하지만 아직 나는 JPA가 익숙하지 않아 그냥 아이디를 이용해 간단하게 삭제 처리를해보자. 

 

import axios from "axios";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { Routes, Route, Link } from 'react-router-dom'
function Detail(props){

    let {id} = useParams();


    return(
        <>
    <div>
        글번호 : {props.board.id}
    </div>
    <div>
        제목 : {props.board.title}
    </div>
    <div>
        내용 : {props.board.content}
    </div>
    <div>
        <button onClick={()=>{
            axios.get(`/board/delete?id=${props.board.id}`)
            alert('삭제완료');
            window.location.href ="/";
        }}>삭제</button> 
        <button><Link to={`/modify/${props.board.id}`}>수정</Link></button>
    </div>

detail.js를 보면 

버튼을 클릭했을때 이벤트함수인 onClick을 사용하여 

axios로 넘겨준다.

 

그 후 컨트롤러와 통신한다. 

 

    @GetMapping("/board/delete")
    public void delete(Integer id){
    boardService.delete(id);
        System.out.println("완료");
    }

정말 간단하게 GetMapping으로 해보자 

원래 restful 방식인 Delete를 써야하지만 스프링부트 설정을 해주는 방법은 다음에 알아보도록하자 

설정을 하지않으면 put과 delte를 사용할 수없다 .

 

    public void delete(Integer id){
        boardRepository.deleteById(id);
    }

서비스에서 id를 지목하면 된다. id는 entity에 있는 id로 진행하면된다. 

 

실행화면 

 

글 번호 14번 게시물을 삭제하려고 한다 .

 

삭제 완료 라는 경고창과 함께

2022-05-26 01:52:52.935 DEBUG 908 --- [io-8090-exec-10] org.hibernate.SQL                        : 
    delete 
    from
        board 
    where
        id=?

인텔리제이 콘솔창에도 실행 되었다고 나오는것 같다. 

 

14번 게시물은 삭제되었다. 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 18 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

저번에는 글쓰기를 알아보았다

CRUD를 진행하면서 리엑트는 좀 어려운거같다 

자바스크립트나 제이쿼리의 DOM 방식이 익숙해졌는데 

리엑트의 방식은 나에게 너무 크게 다가왔다.

 

오키 등 다른 곳에 질문을 올려서 꾸역꾸역 해가고 있다.

점점 성장하는거같다 기쁘다.

 

 

먼저 리엑트부분부터 살펴보자 

 

 <Routes>
      <Route path='/' element={
      <div>메인페이지
        <a href='/Write'>글쓰기</a>
        <h1>List</h1>
        <table>
        <tr>
          <th>번호</th>
          <th>제목</th>
        </tr>
      {
        list.map(function(a,i){
          return(
            <>
                <tr>
                  <td>{list[i].id}</td>
                  <td><Link to={`/detail/${list[i].id}`} onClick={
                    () => {
                      axios.get(`/board/detail/${list[i].id}`).then( res =>{   
                        Setboard(res.data)})
                  }
                  }>{list[i].title}</Link></td>
                </tr>
              </>
          )
        })
    }
    </table>
      </div>}>
        
      </Route>
      <Route path="/write" element={ <Write/> } />
      <Route path='/detail/:id' element={<Detail board={board}/> } />
    </Routes>
      
    </div>


  );
}

우선 테이블 태그로 리스트를 가볍게 그려주자 

그리고 link태그를 사용하여 list의 글번호를 가게하자 

즉 /detail/1 이런식으로 보내진다. 

 

그 다음 axios로 get요청을 보낸다. 

그 후 데이터베이스에서 받아온 내용을 res라는 함수에 저장하여 

Setboard에 저장한다. 

 

그 후 라우터를 통해 board를 props로 담아서 보내준다.

 

※ 주의사항 ※

 

나는 계속 res를 setboard에다 담고 console찍어 보면

계속 이전 값이 나온다 . 

 

그래서 해결책을 찾았다

 

State의 값 변경은 렌더링을 유발시키는 이유로 변경사항을 모아뒀다가 렌더링 주기마다 한번에 처리하기때문에 값이 바로 변경되지 않습니다.

값변경의 감지는 useEffect 훅을 사용하셔야합니다

 

useEffect(() => {
  console.log(board);
}, [board]);

을 추가하면 된다. 

 

다음으로 

 

디데일.js를 보자

 

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

function Detail(props){

    let {id} = useParams();


    return(
        <>
    <div>
        <input name='id' value={props.board.id}/>
    </div>
    <div>
        <input name='title' value={props.board.title}/>
    </div>
    <div>
        <textarea name='content' value={props.board.content}></textarea>
    </div>
        </>
    )
}

export default Detail;

 

그 후 props로 뿌려주면 끝난다. 

 

이제 스프링을 보자 

 

 

    @GetMapping("/board/detail/{id}")
    public Board detail(@PathVariable Integer id){
        return boardService.boardView(id);
    }

 

우선 간단하게 /{id}를 붙였으니

pathvariable로 해준다. 

 

그다음 서비스에서 받은 값을 리턴보내면 컨트롤러의 역활을 끝이다. 

 

서비스를 보면서 이해해보자 

 

    public Board boardView(Integer id){
        return boardRepository.findById(id).get();
    }

id를 보내서 id를 찾는다. 

 

https://github.com/MoonSeokHyun/Vegan-Recipe-WebSite

 

GitHub - MoonSeokHyun/Vegan-Recipe-WebSite

Contribute to MoonSeokHyun/Vegan-Recipe-WebSite development by creating an account on GitHub.

github.com

 

반응형
반응형

간단하게 글쓰기를 구현해보고자 한다. 

 

우선 리엑트에서는

 

import { useEffect, useState } from 'react';
import axios from 'axios';


function Write(){

    const [id, Setid] = useState();
    const [title, SetTitle] = useState("");
    const [content, SetContent] = useState("");

    
    return(
    


    <div>
        <form method='post' action='/board/insert'>
            <div>
                <input name='title'></input>
            </div>
            <div>
                <textarea name='content'></textarea>
            </div>
            <button type='submit'>글 작성a</button>
        </form>
    </div>
        )
    }

export default Write;

이런 간단한 컴포넌트를 하나 만들었다

 

 <a href='/Write'>글쓰기</a>

메인 컴포넌트에서 글쓰기를 누르면 위의 컴포넌트로 이동한다. 

<Route path="/write" element={ <Write/> } />

라우터를 사용하였다. 

라우터쓰는 방법은 많이 나와있으니 참고바란다. 

 

리엑트에서도 form을 써도 되나 싶긴하지만 아직은 리린이라 그냥 진행해보자 

 

스프링부트로 넘어가보자

 

    @PostMapping("/board/insert")
    public void boardinsert(Board board){
        boardService.insert(board);
    }

우선 컨트롤러를 보자면 리엑트에서 폼으로 데이터를 넘긴다 

이때 board 형식으로 받아준다. 

board는 enfity에 있다 즉 vo와 비슷함 

 

@Entity
@Data
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //

    private Integer id;
    private String title;
    private String content;


}

단 3줄짜리 entity이다 나중에 id로 페이징도 할것이다. 

내용과 제목 끝 정말 간단하다.

 

그리고 레포지토리를 등록하자

 

@Repository
public interface BoardRepository extends JpaRepository<Board,Integer> {
}

이부분은 jpa 시간에도 많이 했던거라 생략한다. 

 

그리고 서비스를 작성하자

 

   public void insert(Board board){
        boardRepository.save(board);
    }

jpa의 함수 save(객체)를 써서 간단하게 글 등록을 마칠 수 있엇다. 

 

글 등록을 해보자 

 

글쓰기를 누르면 

 

 

블로그 테스트용~ 으로 글을 남겼다. 글 작성을 누르면 

아래와 같이 등록이된다. 

 

 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 18 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

 

저번시간에는 디비로부터 데이터를 끌어와 리엑트로 보여주는 것을 해봤다

오늘은 뷰에서 직접 파라미터를 받아 서버로 데이터를 보내보자 

 

별거 없었다 또 괜히 2일동안 고민한거 같다. 

 

 

시작해보자 

 

const [id, Setid] = useState();
const [title, SetTitle] = useState("");

우선 아이디와 콘텐트 이 2개를 usestate에 빈값으로 남겨 놓자 

그리고 메인컴포넌트에서 

 

    <input  onChange={(e)=>{
      Setid(e.target.value);
    }}/>
       <input onChange={(e)=>{
      SetTitle(e.target.value);
    }}/>

이렇게 인풋값을 2개를 만들어준다.

하나는 숫자가 들어갈 인풋 다른 하나는 숫자든 상관없다.

 

이제 전송버튼을 살펴보자

 

    <button
      onClick={
        ()=>{
          axios.get('/board/insert',{
            params:{
              id : id,
              title : title
            }
          }).catch(function(){
            console.log('실패함')
          })
        }}
    >전송</button>

우선 온클릭이벤트로 값을 만들어 준다. 

그 후로 axios로 보낼 url값 즉 파라미터에 getMapping값을 적어준뒤 뒤에 params에는

오브젝트형식으로 위에 변수를 적어준다. 

 

 

    @GetMapping("/board/insert")
    public void boardinsert(@RequestParam Integer id, @RequestParam String title){
        System.out.println(id);
        System.out.println(title);
    }
    }

 

그리고 GetMapping으로 위에 파라미터를 받아준다.

 

이제 테스트를 해보자

위에 처럼 적고 전송버튼을 누르면

 

스프링부트로 전달이 아주 잘됬다.

이제 이걸로 간단한 회원가입페이지를 만들어보자

 

반응형
반응형

한 2일을 고민했다. 

블로그도 찾아보고 리엑트랑 스프링부트랑 연결도 하고 이제 데이터베이스에서 뿌려주는 것만 하면 

프로젝트  준비는 거의 끝낫다. 

 

리엑트에서 axios를 활용하여 컨트롤러에 접근하여 가져온 디비의 내용을 출력하면 된다. 

 

https://devofroad.tistory.com/84?category=972234 

 

JPA를 사용한 게시판 만들기(2) 리스트작업 {타임리프,스프링부트}

저번에는 글쓰기에 대해서 알아보았다. 이제 쓴 글을 리스트화 시키는 방법에 대해서 스프링 부트와 jpa 방법으로 알아보고자 한다. 이렇게 됬다 공부중이라 디자인은 생략한다. 자 이제 시작해

devofroad.tistory.com

데이터는 이것을 썻다.

 

const [list , SetList] = useState([]);

useEffect(()=> {
  axios.get('/board/list').then((res)=>{
    SetList(res.data)
    console.log(list)
  })
},[])

우선 useState로 리스트에 받아올 값을 넣어주기 위해 변수로 선언해 준다.

그다음 페이지가 로딩된 다음에 use이펙트를 통해 axios로 컨트롤러에 접근을 한다. 

 

이떄 뒤에 [] (빈 배열)을 넣어주지 않으면 무한로딩이 되기 떄문에 조심하자. 

 

    public List<Board> boardList(Model model){
        return boardService.boardList();
    }

컨트롤러는 다음과 같다. 

service에서 리턴한 값을 그대로 리엑트로 쏴준다. 

 

그럼 console.log로 res를 확인 해 보았을때 data가 약 120개 정도 나온다.

 

이 떄 이것을 이제 화면에다 뿌려주면된다. 

 

function App() {

const [list , SetList] = useState([]);

useEffect(()=> {
  axios.get('/board/list').then((res)=>{
    SetList(res.data)
    console.log(res)
  })
},[])
  
  return (
    <div className="App">

      <h1>List</h1>
      {
        list.map(function(a,i){
          return(
            <div>
            <div>{list[i].id}</div>
            <div>{list[i].title}</div>
            <div>{list[i].content}</div>
            </div>
          )
        })
      }

      
    </div>


  );
}

이제 컴포넌트 안에 {}를 선언해주고 map을 써주면 된다. 

 

jsp에 el태그와 비슷하다.

즉 파라미터 문법으로 

a를 i만큼 반복한다는 뜻이다.

즉 반복문 같은 거라 

list[i].id는 

res.data[0~120].id 라는 소리 이것을 120번 반복한다. 

 

이렇게 뿌려주면

 

이렇게 나온다. 

 

테이블 태그를 쓰지않아서 .. 한줄로 나오지만 a태그를 넣고 하면 간단한 게시판 형식이 나올 것 같다. 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 17 repositories available. Follow their code on GitHub.

github.com

 

반응형

+ Recent posts