| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- scanner
- 오버로딩
- 다형성
- Else If
- 상속
- 자바
- Break
- docker
- javascript
- arraylist
- 문자열
- 이클립스
- interface
- 삼항 연산식
- Integer.MAX_VALUE
- 인터페이스
- 중첩for문
- If
- Integer.MIN_VALUE
- 삼항 연산
- 메소드
- 2차원 배열
- 이중 배열
- 배열
- jsp
- for문
- rs.next()
- extends
- 상수
- super()
- Today
- Total
개발로드
★KDT 2024-04-03☆SpringBoot-Maven- SpringSecurity,Test, 계층분리 본문
계층분리
Item.java
package com.cshop.entity;
import com.cshop.constant.ItemSellStatus;
import java.time.LocalDateTime;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
//책은 3ver로 빌려서 해보기
@Getter
@Setter
@ToString
//Entity : 클래스를 데이터베이스 테이블에 대응되는 엔티티로 선언한다. JPA가 관리한다.
@Entity
//Entity와 매핑할 table로 지정해주고, 이 테이블의 이름은 itme이다.
//item table과 매핑한다.
@Table(name = "item")
public class Item {
@Id//기본키 설정, entity로 선언한 클래스는 반드시 기본키가 있어야 한다.
@Column(name = "item_id") //매핑되는 컬럼명, Item 클래스의 id와 item table의 item_id가 매핑된다.
@GeneratedValue(strategy = GenerationType.AUTO)//기본키 설정 전략(생성 방법)
/*
* GenerationType
* AUTO : JPA 구현체(Hibernate)가 자동으로 생성 전략 결정
* IDENTITY : 데이터베이스 니가 알아서 설정하셈
* SEQUENCE : 데이터베이스 sequence object를 이용한 기본키 생성
* TABLE : 키 생성용 테이블을 사용한다.
*/
private Long id; //상품코드
//itemName은 null값 비허용이고, 데이터의 사용 가능한 길이는 50이고 데이터베이스에서의 이름은 item_name이다.
@Column(nullable = false, length = 50, name = "item_name") //null값 비허용, 반드시 입력 받기
// char(50), varchar(50) - length, 즉 길이로 표현하고 length의 특정 길이를 선언하지 않는다면 255자까지 가능하다.
/* @Column(nullable = true) null값 허용, 값 입력은 선택! */
private String itemName; //상품명
@Column(nullable = false, name = "price") //입력 필수, 이름을 똑같이 줄거면 생략해도 ㅇㅋ
private int price; //가격
@Column(nullable = false) //입력 필수
private int stockNumber; //재고수량
@Lob //text, img, videos,... 용량이 큰 데이터를 저장한다.
// DB의 BLOB, CLOB에 대응된다.
@Column(nullable = false)
private String itemDetail; //상품상세설명
@Enumerated(EnumType.STRING) //enum 타입을 썼다는 것을 알려주기 위해서 사용했고, enumtype이 String으로 사용되었음.
@Column
private ItemSellStatus itemSellStatus; //상품판매상태
private LocalDateTime regTime; //등록시간
private LocalDateTime updateTime; //수정시간
}
ItemDTO.java
package com.cshop.dto;
import com.cshop.constant.ItemSellStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
//Dto 따로 만드는 이유
//데이터를 주고 받을 때는 Entity 클래스 자체를 반환하면 안됨
//DTO(Data Transfer Object)를 생성해서 사용 => 데이터 전달 객체
//데이터베이스의 설계를 외부에 노출할 필요도 없으며, 요청과 응답 객체가
//항상 Entity 와 같지 않기 때문
@Setter
@Getter
@ToString
public class ItemDto {
private Long id; //상품코드
private String itemName; //상픔명
private int price; //가격
private int stockNumber; //재고수량
private String itemDetail; //상품 상세 설명
private ItemSellStatus itemSellStatus ; // 상품 판매 상태
private LocalDateTime regTime; //등록시간
private LocalDateTime updateTime; // 수정 시간
}//end of class
DTO와 Entity를 구분하는 이유
엔터티 클래스와 별도로 DTO(데이터 전송 개체)를 생성하는 것은 소프트웨어 개발에서 몇 가지 중요한 목적을 제공합니다.
- 계층 분리
- DTO는 애플리케이션의 다양한 계층, 특히 지속성 계층(엔티티가 있는 곳)과 서비스 계층(일반적으로 비즈니스 논리가 있는 곳)을 분리하는 데 도움이 됩니다.
- DTO를 사용하면 애플리케이션의 상위 계층에서 데이터베이스 구조의 내부 세부 정보를 보호하여 모듈성과 유지 관리 가능성을 높일 수 있습니다.
- 데이터 직렬화
- 애플리케이션이 네트워크나 외부 시스템(예: API)과 통신할 때 데이터를 전송할 수 있는 형식(예: JSON 또는 XML)으로 직렬화해야 하는 경우가 많습니다.
- DTO는 직렬화 및 역직렬화를 위해 이 데이터를 나타내는 깔끔하고 체계적인 방법을 제공하여 관련 데이터만 전송 및 수신되도록 합니다.
- 오버페치 및 언더페치 감소
- 엔터티에는 특정 작업에 필요한 것보다 더 많은 데이터가 포함될 수 있습니다.
- DTO를 사용하면 특정 사용 사례에 필요한 것만 포함하도록 전송되는 데이터를 조정할 수 있습니다.
- 이는 성능 문제로 이어질 수 있는 오버페치(필요한 것보다 더 많은 데이터 검색)와 언더페치(충분한 데이터를 검색하지 않음)를 줄이는 데 도움이 됩니다.
- 데이터 표현의 유연성
- 엔터티는 데이터베이스 스키마를 기반으로 설계되는 경우가 많으며 애플리케이션의 API 또는 사용자 인터페이스 요구 사항과 완벽하게 일치하지 않을 수 있습니다.
- DTO를 사용하면 기본 데이터베이스의 구조에 제약을 받지 않고 특정 사용 사례에 적합한 방식으로 데이터를 표현할 수 있습니다.
- 보안 및 개인 정보 보호
- 엔터티 클래스를 외부 시스템에 직접 노출하면 데이터베이스 스키마 또는 애플리케이션의 내부 작동에 대한 민감한 정보가 노출될 수 있으므로 보안 위험이 발생할 수 있습니다.
- DTO를 사용하면 외부 시스템에 의해 노출되고 조작될 수 있는 데이터를 정확하게 제어할 수 있어 보안 및 개인 정보 보호 조치를 시행하는 데 도움이 됩니다.
- 버전 관리 및 발전
- 애플리케이션이 발전함에 따라 데이터베이스 최적화, 비즈니스 로직 수정 또는 기타 이유로 엔터티의 구조가 변경될 수 있습니다.
- DTO를 사용하면 내부 데이터 모델과 독립적으로 API 또는 외부 데이터 계약을 발전시켜 더 큰 유연성과 이전 버전과의 호환성을 제공할 수 있습니다.
- 전반적으로 DTO를 사용하면 더 깔끔한 아키텍처가 촉진되고 유지 관리성이 향상되며 보안이 향상되고 애플리케이션 내 및 외부 시스템과의 데이터 표현 및 통신에 유연성이 제공됩니다.
Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
//쿼리 메소드 작성하기
//find + (엔티티명) + By + 검색에 사용할 변수명
//상품의 이름을 입력해서 데이터를 조회
List<Item> findByItemName(String ItemName);
//상품 상세 설명을 파라미터로 받아 해당 내용을 삼품 상세 설명에 포함하고 있는 데이터를 조회
//하고 가격이 높은 순으로 정렬해서 조회
@Query("select i from Item as i where i.itemDetail like %:itemDetail% order by i.price desc")
List<Item> findByItemDetail(@Param("itemDetail") String itemDetail);
}//end of interface
TestClass
@SpringBootTest
//#2. application.properties의 내용과 같은 내용이 있다면 application-test.properties에게 더 우선순위 부여하기 위한 내용
@TestPropertySource(locations = "classpath:application-test.properties")
@Slf4j
class ItemRepositoryTest {
//#3. 스프링 빈을 주입
@Autowired
ItemRepository itemRepository;
SaveTest
//#4. 테스트할 메소드 임을 알려주기
@Test
//#5.테스트명을 알려주기
@DisplayName("InsertItem Test")
public void createItemTest() {
Item item = new Item();
item.setItemName("테스트 상품");
item.setPrice(10000);
item.setItemDetail("테스트 상품 상세 설명");
item.setItemSellStatus(ItemSellStatus.SELL);
item.setStockNumber(100);
item.setRegTime(LocalDateTime.now());
item.setUpdateTime(LocalDateTime.now());
//#6. repository의 save()메소드 활용하여 저장
Item saveItem = itemRepository.save(item);
//저장된 내용 출력
log.info(saveItem.toString());
}//end of createItemTest

로깅
c.cshop.repository.ItemRepositoryTest : Item(id=1, itemName=테스트 상품, price=10000, stockNumber=100, itemDetail=테스트 상품 상세 설명, itemSellStatus=SELL, regTime=2024-04-03T16:34:02.520971600, updateTime=2024-04-03T16:34:02.520971600)
상품명 찾기 Test
@Test
@DisplayName("findItemName")
public void findItemName(){
this.createItemList();
List<Item> itemList = itemRepository.findByItemName("테스트 상품3");
for(Item item : itemList){
log.info(item.toString());
}//end of for-each
}//end of findItemName
ItemRepository
//상품의 이름을 입력해서 데이터를 조회
List<Item> findByItemName(String ItemName);

로깅
c.cshop.repository.ItemRepositoryTest : Item(id=3, itemName=테스트 상품3, price=150000, stockNumber=103, itemDetail=테스트 상품 상세 설명3, itemSellStatus=SELL, regTime=2024-04-03T16:35:53.529558, updateTime=2024-04-03T16:35:53.529558)
상품설명 찾기 Test
@Test
@DisplayName("findItemDetail")
public void findItemDetail(){
this.createItemList();
List<Item> itemList = itemRepository.findByItemDetail("테");
for (Item item : itemList){
log.info(item.getItemDetail());
}//end of for-each
}//end of findItemDetail

로깅
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명1
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명2
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명3
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명4
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명5
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명6
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명7
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명8
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명9
2024-04-03T16:37:53.400+09:00 INFO 11676 --- [ main] c.cshop.repository.ItemRepositoryTest : 테스트 상품 상세 설명10
Spring Security
pom.xml에 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
서버 실행시 로그인 화면

Username에는 user
Password에는 서버 실행시 생성되는 비밀번호를 입력

로그아웃 화면

로그아웃 성공

여유가 되신다면 제 GitHub에 오셔서 좋은 코드들을 구경해주세요!

https://github.com/gimpo5975?tab=repositories
gimpo5975 - Overview
gimpo5975 has 6 repositories available. Follow their code on GitHub.
github.com
'JAVA' 카테고리의 다른 글
| ★KDT 2024-04-05☆SpringBoot-Maven- SpringSecurity (0) | 2024.04.05 |
|---|---|
| ☆KDT 2024-04-04★SpringBoot-Maven-암호화, 어노테이션,회원가입 (0) | 2024.04.04 |
| ☆KDT 2024-04-02★SpringBoot-Maven-JpaRepository (0) | 2024.04.02 |
| ★KDT 2024-04-02☆SpringBoot-Maven-Restful,JPA,@RestController (0) | 2024.04.02 |
| ☆KDT 2024-04-01★SpringBoot-Maven-회원CRUD (0) | 2024.04.01 |