0. 프로젝트 생성과 작업환경 설정
pom.xml
pom.xml은 Maven의 빌드 정보를 담고 있는 파일로, POM(Project Object Model)을 설정하는 부분으로 프로젝트 내 빌드 옵션을 설정하는 부분
<?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>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>JpaCrud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>JpaCrud</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- spring boot starter web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot starter tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- spring boot starter test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- jstl :자바 서버 페이지 표준 태그 라이브러리 웹 개발 플랫폼을 위한 컴포넌트 모음 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- Tomcat Embed Jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- Spring boot devtool : Spring boot에서 제공하는 개발 편의를 위한 모듈 // 코드가 변경되면 자동으로 어플리케이션을 재구동한다. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.0.6</version>
</dependency>
<!-- mybatis : SQL 매퍼(Mapper) 프레임워크 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
# 서버 port번호 설정
server.port = 8083
# jsp파일은 Springboot의 templates폴더 안에서 작동하지 아니함
# view단의 경로및 기본 확장자 지정
spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
# Spring MVC HiddenMethod // delete, put 등 메서드를 사용할 수 있다.
spring.mvc.hiddenmethod.filter.enabled=true
# JDBC연동관련
spring.datasource.driverClassName = org.mariadb.jdbc.Driver
spring.datasource.url = jdbc:mariadb://localhost:3306/db01
spring.datasource.username = root
spring.datasource.password = 1234
# spring.jpa.hibernate.ddl-auto : JPA의 Database 초기화 전략
#update : 변경된 스키마를 적용
spring.jpa.hibernate.ddl-auto=update
# application.properties를 사용할경우 true
spring.jpa.properties.hibernate.format_sql=true
# Hibernate가 DB에 수행하는 모든 쿼리문을 콘솔에 출력
spring.jpa.properties.hibernate.show-sql=true
# logging.level.{패키지 경로}를 통해 로깅 레벨을 결정할 수 있음
logging.level.org.hibernate.type.descriptor.sql=DEBUG
logging.level.org.hibernate.SQL=DEBUG
lombok (롬복) 설치
프로젝트 > Properties > Project Fecets
자바 버전 확인
1. MVC 구조
- 클라이언트 : 앞단을 담당하는 jsp와
- Controller : 요청을 받아 알맞은 결과값을 처리하고 결과를 리턴
- Repository (Interface) : JpaRepository<MemberEntity클래스를 통해 DB와 소통을 가능케 하고 관련된 메서드를 제공한다.
- Entity : Model, 애플리케이션을 구성 하는 데이터의 자료형을 규정, 해당코드에서는 컬럼값에 대한 정의를 한다.
1_1. MemberController
package com.example;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/")
public class MemberController {
@Autowired
private final MemberRepository memberRepository ;
@PersistenceContext
private EntityManager entityManager;
// == UPDATE
@GetMapping("update")
public String updateMember(@RequestParam(value = "name") String name, @RequestParam(value = "pwd") String pwd) {
if(memberRepository.findById(name).isEmpty()) { // 값 존재여부 확인
return "입력한 " + name + "이 존재하지 않습니다";
} else {
memberRepository.save(MemberEntity.builder().name(name).pwd(pwd).build());
return name + "의 비밀번호를 " + pwd + "로 변경 완료";
}
}
//==== DELETE
@GetMapping("delete")
public String deleteMember(@RequestParam(value = "name") String name) {
if(memberRepository.findById(name).isEmpty()) { // 값 존재여부 확인
return "입력한 " + name + "이 존재하지 않습니다";
} else {
memberRepository.delete(MemberEntity.builder().name(name).build());
return name + " 삭제 완료";
}
}
// === CREATE
@GetMapping("insert")
public String insertMember(@RequestParam(value = "name") String name, @RequestParam(value = "pwd") String pwd) {
if(memberRepository.findById(name).isPresent()) {
return "동일한 이름이 이미 있습니다";
} else {
MemberEntity entity = MemberEntity.builder().name(name).pwd(pwd).build();
memberRepository.save(entity);
return "이름 : " + name + " 비밀번호 : " + pwd + "으로 추가 되었습니다";
}
}
// ==== READ ====
@GetMapping("search")
public String searchAllMember() {
return memberRepository.findAll().toString();
}
@GetMapping("searchParam")
public String searchParamMember(@RequestParam(value = "name") String name) {
List resultList = entityManager.createQuery("select pwd from member where name=:name")
.setParameter("name", name)
.getResultList();
return resultList.toString();
}
//
// @GetMapping("searchParamRepo")
// public String searchParamRepoMember(@RequestParam(value = "name") String name) {
// return memberRepository.searchParamRepo(name).toString();
// }
}
1_2. MemberRepository
package com.example;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface MemberRepository extends JpaRepository<MemberEntity, String> {
@Query(value = "select name, id, pwd from member where name = :name", nativeQuery=true)
List<MemberEntity> searchParamRepo(@Param("name") String name);
}
1_3. MemberEntity
package com.example;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Entity(name="member")
public class MemberEntity {
@Id
@Column(nullable = false, unique = true)
private String name;
@Column(nullable = false, unique = true)
private int id;
@Column(nullable = false)
private String pwd;
}
2. 기능 별(CRUD)
2_1. R (Select)
read는 클라이언트의 요청에 따라, DB의 정보를 조회하여 결과값을 반환한다.
index(Client)
<!-- READ -->
<h3>READ</h3>
<a href="search">All serach</a><br/><br/>
<a href="searchParam?name=AAA">AAA의 비밀번호 찾기</a><br/><br/>
// ==== READ ====
@GetMapping("search")
public String searchAllMember() {
return memberRepository.findAll().toString();
}
@GetMapping("searchParam")
public String searchParamMember(@RequestParam(value = "name") String name) {
List resultList = entityManager.createQuery("select pwd from member where name=:name")
.setParameter("name", name)
.getResultList();
return resultList.toString();
}
findAll()
DB에 접근하여 관려한 모든 값을 데이터로 가져와 반환한다.
https://wakestand.tistory.com/754
https://data-make.tistory.com/614
2_2 Create (insert)
index.jsp
<!-- CREATE -->
<h3>CREATE</h3>
<a href="insert?name=AAA&pwd=33">AAA넣기</a><br/><br/>
<a href="insert?name=GGG&pwd=33">GGG넣기</a><br/><br/>
<a href="insert?name=CCC&pwd=33">CCC 넣기</a><br/><br/>
<a href="insert?name=강물이&pwd=33">강물이넣기</a><br/><br/>
Controller.jsp
// === CREATE
@GetMapping("insert")
public String insertMember(@RequestParam(value = "name") String name, @RequestParam(value = "pwd") String pwd) {
if(memberRepository.findById(name).isPresent()) {
return "동일한 이름이 이미 있습니다";
} else {
MemberEntity entity = MemberEntity.builder().name(name).pwd(pwd).build();
memberRepository.save(entity);
return "이름 : " + name + " 비밀번호 : " + pwd + "으로 추가 되었습니다";
}
}
findbyId()
https://velog.io/@eden/JPA-%EC%97%90%EC%84%9C-getById-vs-findById
https://bcp0109.tistory.com/325
isPresent()
https://sin0824.tistory.com/25
save()
https://minkukjo.github.io/framework/2020/07/05/Spring-130/
2_3. Update (update)
index.jsp
<!-- UPDATE -->
<h3>UPDATE</h3>
<a href="update?name=AAA&pwd=11">AAA비밀번호 바꾸기</a><br/><br/>
<a href="update?name=AAA&pwd=99">AAA 비밀번호 바꾸기</a><br/><br/>
// == UPDATE
@GetMapping("update")
public String updateMember(@RequestParam(value = "name") String name, @RequestParam(value = "pwd") String pwd) {
if(memberRepository.findById(name).isEmpty()) { // 값 존재여부 확인
return "입력한 " + name + "이 존재하지 않습니다";
} else {
memberRepository.save(MemberEntity.builder().name(name).pwd(pwd).build());
return name + "의 비밀번호를 " + pwd + "로 변경 완료";
}
}
2_4.Delete (Delete)
index.jsp
<!-- DELETE -->
<h3>READ</h3>
<a href="delete?name=CCC">CCC 삭제</a><br/><br/>
//==== DELETE
@GetMapping("delete")
public String deleteMember(@RequestParam(value = "name") String name) {
if(memberRepository.findById(name).isEmpty()) { // 값 존재여부 확인
return "입력한 " + name + "이 존재하지 않습니다";
} else {
memberRepository.delete(MemberEntity.builder().name(name).build());
return name + " 삭제 완료";
}
}
delete()
https://hwanchang.tistory.com/7
isEmpty()
https://hianna.tistory.com/531