To Do List ํ๋ก์ ํธ
โTodo List - ํ ์ผ ๋ชฉ๋ก UI ๋ง๋ค๊ธฐโ
์คํ ์ข ๋๋ฌ์ฃผ์ธ์
๋ฐฑ์๋ (SpringBoot)
๋ฐ์ดํฐ๋ฒ ์ด์ค
todo ํ
์ด๋ธ
CREATE TABLE `todo` (
`no` int NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`status` int DEFAULT '0',
`reg_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`upd_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`no`)
) COMMENT='ํ ์ผ';
SQL
๋ณต์ฌ
ํ๋ก์ ํธ ๊ตฌ์กฐ
โข
๐ง Server
โฆ
โช
โข
โช
โข
โช
โข
โข
โช
โข
โฆ
โช
โข
โช
โช
โฆ
์ฝ๋ ์์
1.
2.
3.
4.
โข
5.
โข
6.
โข
7.
โข
โข
8.
โข
build.gradle
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.1.6'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.joeun'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
}
tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
}
tasks.named('test') {
useJUnitPlatform()
}
Plain Text
๋ณต์ฌ
application.properties
# ๋ฐ์ดํฐ ์์ค - MySQL
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/joeun?serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&autoReconnection=true&autoReconnection=true
spring.datasource.username=joeun
spring.datasource.password=123456
# Mybatis ์ค์
# Mybatis ์ค์ ๊ฒฝ๋ก : ~/resources/mybatis-config.xml
mybatis.config-location=classpath:mybatis-config.xml
# Mybatis ๋งคํผ ํ์ผ ๊ฒฝ๋ก : ~/๋ฉ์ธํจํค์ง/mapper/**Mapper.xml
mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
๋ณต์ฌ
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- ์ค์ -->
<settings>
<!-- ์ธ๋์ค์ฝ์ด ์ผ์ด์ค์ธ ์ปฌ๋ผ์ ์นด๋ฉ ์ผ์ด์ค๋ก ๋ณํํ๋ ์ค์ -->
<!-- board_no - boardNo -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- ํ์
๋ณ์นญ ์ค์ -->
<typeAliases>
<!-- ํ
์ด๋ธ๊ณผ ๋งคํํ DTO๊ฐ ์๋ ํจํค์ง ๊ฒฝ๋ก ์ง์ -->
<package name="com.joeun.todo.dto"/>
</typeAliases>
</configuration>
XML
๋ณต์ฌ
main-package/mapper
โข
<?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">
<!-- namespace="๋งคํผ ์ธํฐํ์ด์ค ๊ฒฝ๋ก" -->
<mapper namespace="com.joeun.todo.mapper.TodoMapper">
<!-- ํ ์ผ ๋ชฉ๋ก -->
<select id="list" resultType="Todo">
SELECT *
FROM todo
ORDER BY status ASC, no DESC
</select>
<!-- ํ ์ผ ์กฐํ -->
<select id="select" resultType="Todo">
SELECT *
FROM todo
WHERE no = #{no}
</select>
<!-- ํ ์ผ ๋ฑ๋ก -->
<insert id="insert">
INSERT INTO todo( name )
VALUES ( #{name} )
</insert>
<!-- ํ ์ผ ์์ -->
<update id="update">
UPDATE todo
SET name = #{name}
,status = #{status}
,upd_date = now()
WHERE no = #{no}
</update>
<!-- ํ ์ผ ์ญ์ -->
<delete id="delete">
DELETE FROM todo
WHERE no = #{no}
</delete>
<!-- last id -->
<select id="lastId" resultType="int">
select last_insert_id() id
</select>
<!-- ์ ์ฒด ํ ์ผ ์๋ฃ -->
<update id="completeAll">
UPDATE todo
SET status = 1
,upd_date = now()
</update>
<!-- ์ ์ฒด ํ ์ผ ์ญ์ -->
<delete id="deleteAll">
DELETE FROM todo
</delete>
</mapper>
XML
๋ณต์ฌ
mapper
โข
package com.joeun.todo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.joeun.todo.dto.Todo;
@Mapper
public interface TodoMapper {
public List<Todo> list() throws Exception;
public Todo select(int no) throws Exception;
public int insert(Todo todo) throws Exception;
public int update(Todo todo) throws Exception;
public int delete(int no) throws Exception;
public int lastId() throws Exception;
public int completeAll() throws Exception;
public int deleteAll() throws Exception;
}
Java
๋ณต์ฌ
dto
โข
package com.joeun.todo.service;
import java.util.List;
import com.joeun.todo.dto.Todo;
public interface TodoService {
public List<Todo> list() throws Exception;
public Todo select(int no) throws Exception;
public int insert(Todo todo) throws Exception;
public int update(Todo todo) throws Exception;
public int delete(int no) throws Exception;
public int lastId() throws Exception;
public int completeAll() throws Exception;
public int deleteAll() throws Exception;
}
Java
๋ณต์ฌ
service
โข
package com.joeun.todo.service;
import java.util.List;
import com.joeun.todo.dto.Todo;
public interface TodoService {
public List<Todo> list() throws Exception;
public Todo select(int no) throws Exception;
public int insert(Todo todo) throws Exception;
public int update(Todo todo) throws Exception;
public int delete(int no) throws Exception;
public int lastId() throws Exception;
public int completeAll() throws Exception;
public int deleteAll() throws Exception;
}
Java
๋ณต์ฌ
โข
package com.joeun.todo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.joeun.todo.dto.Todo;
import com.joeun.todo.mapper.TodoMapper;
@Service
public class TodoServiceImpl implements TodoService {
@Autowired
private TodoMapper todoMapper;
@Override
public List<Todo> list() throws Exception {
return todoMapper.list();
}
@Override
public Todo select(int no) throws Exception {
return todoMapper.select(no);
}
@Override
public int insert(Todo todo) throws Exception {
int result = todoMapper.insert(todo);
if( result > 0 )
result = todoMapper.lastId();
return result;
}
@Override
public int update(Todo todo) throws Exception {
return todoMapper.update(todo);
}
@Override
public int delete(int no) throws Exception {
return todoMapper.delete(no);
}
@Override
public int lastId() throws Exception {
return todoMapper.lastId();
}
@Override
public int completeAll() throws Exception {
return todoMapper.completeAll();
}
@Override
public int deleteAll() throws Exception {
return todoMapper.deleteAll();
}
}
Java
๋ณต์ฌ
controller
โข
[Extension] Spring Code Generator
๊ฟํ : sp-crud
package com.joeun.todo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.joeun.todo.dto.Todo;
import com.joeun.todo.service.TodoService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@CrossOrigin(origins = "*") // cors ํ์ฉ
@RequestMapping("/todos")
public class TodoController {
@Autowired
private TodoService todoService;
@GetMapping()
public ResponseEntity<?> getAll() {
log.info("list...");
try {
List<Todo> todoList = todoService.list();
log.info("ํ ์ผ ๊ฐ์ : " + todoList.size());
return new ResponseEntity<>(todoList, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/{id}")
public ResponseEntity<?> getOne(@PathVariable Integer id) {
log.info("select...");
log.info("id : " + id);
try {
Todo todo = todoService.select(id);
log.info("todo : " + todo);
return new ResponseEntity<>(todo, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PostMapping()
public ResponseEntity<?> create(@RequestBody Todo todo) {
log.info("insert...");
try {
int result = todoService.insert(todo); // ์๋ก ์์ฑ๋ no ๋ฅผ ์๋ต
todo.setNo(result);
log.info("result : " + result);
if( result > 0 )
return new ResponseEntity<>(todo, HttpStatus.CREATED);
else
return new ResponseEntity<>(todo, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PutMapping()
public ResponseEntity<?> update(@RequestBody Todo todo) {
log.info("update...");
log.info(todo.toString());
try {
int result = 0;
// ์ ์ฒด ์๋ฃ
if( todo.getNo() == -1 ) {
result = todoService.completeAll();
}
else {
result = todoService.update(todo);
}
if( result > 0 )
return new ResponseEntity<>("Update Result", HttpStatus.OK);
else
return new ResponseEntity<>("No Result", HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/{id}")
public ResponseEntity<?> destroy(@PathVariable Integer id) {
log.info("delete...");
log.info("id : " + id);
try {
int result = 0;
// ์ ์ฒด ์ญ์
if( id == -1 ) {
result = todoService.deleteAll();
}
else {
result = todoService.delete(id);
}
if( result > 0 )
return new ResponseEntity<>("Destroy Result", HttpStatus.OK);
else
return new ResponseEntity<>("No Result", HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Java
๋ณต์ฌ
ํ ์คํธ
๊ฒ์๊ธ ๋ชฉ๋ก [GET]
http://localhost:8080/boards
Plain Text
๋ณต์ฌ
๊ฒ์๊ธ ์กฐํ [GET]
http://localhost:8080/boards/1
Plain Text
๋ณต์ฌ
๊ฒ์๊ธ ๋ฑ๋ก [POST]
http://localhost:8080/boards
Plain Text
๋ณต์ฌ
๊ฒ์๊ธ ์์ [PUT]
http://localhost:8080/boards
Plain Text
๋ณต์ฌ
๊ฒ์๊ธ ์ญ์ [DELETE]
http://localhost:8080/boards/1
Plain Text
๋ณต์ฌ