이번편은 테이블 자동생성입니다.
전편에서 엔티티를 자동생성은 해봤었는데요. Repository, Service역시 자동으로 만들어주죠.
중복코드가 많기에... 제 생각엔 한 80~90%는 중복코드 같습니다. 물론, 테이블이 맵핑. 여러테이블로 구성되어있다면, 편집은 해야하죠.
https://github.com/infott2t/SpringAutoCodeJPAEntity3
GitHub - infott2t/SpringAutoCodeJPAEntity3: Automation Code CRUD. SpringBoot JPA + QueryDSL
Automation Code CRUD. SpringBoot JPA + QueryDSL . Contribute to infott2t/SpringAutoCodeJPAEntity3 development by creating an account on GitHub.
github.com
위의 github을 인텔리제이에, 설치해줌니다. 제가 만든 프로젝트이군요.
전에 엔티티, Repository, Service 클래스의 자동생성은 이 편을 참조해보세요.
[웹 프로그래밍] 스프링부트JPA 1. 데이터를 클래스화 하기. 자동 생성. (tistory.com)
[웹 프로그래밍] 스프링부트JPA 1. 데이터를 클래스화 하기. 자동 생성.
공부해봅시다. 오늘은 클래스 형식으로 데이터 만들어보기 입니다. 스프링부트를 통해서, 엔티티클래스를 만들면, 자동화를 통해 프로그래밍을 더 쉽게 할 수 있습니다. 백엔드와 프론트엔드로
tt2t2am.tistory.com
이번 편은, CRUD의 url. insert, list출력, update, delete... 이런 로직, html들을 자동생성해주는 것이군요~.
@Entity
public class PhoneStr extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PHONE_STR_ID")
private Long id;
//전화번호
private String phoneNumber;
private String isDel;
private LocalDateTime modifiedDate;
private LocalDateTime createdDate;
}
전화번호를 저장하는 엔티티를 예를 들게요. 맨위에는 Long id. 그리고, isDel과 modifiedDate, createDate는 그대로 사용해줘야하고, modefiedDate, createDate는 안적어야 하는 군요.
위 처럼 적고, Extract Redundant.. 버튼을 누르면 파일이 생성됨니다. c:\category에 생성이 되요. 그 파일들을 프로젝트에 붙이면 됨니다. 패키지는 적혀있지 않으니, 적어주시구요.
엔티티를 생성할 때에, isDel, modifiedDate, createdDate. 이 세개의 변수를 잘 적어두어야, 위 처럼 코드생성기를 잘 이용할 수 있습니다.
또, 메소드. 이부분은 따로 생성해줘야합니다. Service클래스에 맞춰서 적어주면됨니다.
@Transactional(readOnly = true)
public Page<AddressStrApiDto> searchAllV2(AddressStrSearchCondition condition, Pageable pageable) {
return addressStrRepository.searchAllV2(condition, pageable);
}
파일들을 경로에 맞게 저장한 뒤 실행...
index.html에 링크 경로를 지정해주구요~.
resource/templates/index.html.
<p><a th:href="@{/administer/instanceurl/phoneStr}">phone 게시판 엔티티 PhoneStr 로 이동</a> </p>
또, Impl파일. QueryDsl검색할 때에, where절을 추가해줌니다. 페이징할 때에 isDel이 N인 것... 지우지 않은 것만 나오게 해줘야하죠.
PhoneStrRepositoryImpl클래스,
@Override
public Page<PhoneStrApiDto> searchAllV2(PhoneStrSearchCondition condition, Pageable pageable) {
List<PhoneStrApiDto> content = queryFactory.
select(Projections.constructor(PhoneStrApiDto.class,
phoneStr.id,
phoneStr.phoneNumber,
phoneStr.isDel,
phoneStr.modifiedDate,
phoneStr.createdDate
)).from(phoneStr)
.where(
searchAllV2Predicate(condition)
).where(phoneStr.isDel.eq("N"))
.orderBy(phoneStr.id.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
long total = queryFactory
.select(phoneStr.count())
.from(phoneStr)
.where(
searchAllV2Predicate(condition)
).where(phoneStr.isDel.eq("N"))
.fetch().get(0);
return new PageImpl<>(content, pageable, total);
}
QueryDsl의 검색기능을 사용하려면, 주석을 풀어주고... 이런 식으로 적어주면 됨니다. 검색할 것이 어떤것이 되는지 생각해보면 되겠습니다. 위의 엔티티의 경우에는, phoneNumber가 되겠죠~.
hasText의 import도 필요합니다.
import static org.springframework.util.StringUtils.hasText;
private BooleanBuilder searchAllV2Predicate(PhoneStrSearchCondition condition){
return new BooleanBuilder()
.and(condS(condition.getField(), condition.getS()))
.and(condSdate(condition.getSdate()))
.and(condEdate(condition.getEdate()));
}
private Predicate condS(String field, String s){
BooleanBuilder builder = new BooleanBuilder();
if(hasText(field) && hasText(s)) {
if(field.equals("phoneNumber")) {
builder.or(phoneStr.phoneNumber.like("%" + s + "%"));
}
}
return builder;
}
private Predicate condSdate( String sdate){
BooleanBuilder builder = new BooleanBuilder();
if(hasText(sdate)){
try {
LocalDateTime localDateTime = LocalDateTime.parse(sdate + "T00:00:00");
builder.or(phoneStr.modifiedDate.goe(localDateTime)); // isrtDate >= sdate
} catch (DateTimeParseException e) {
}
}
return builder;
}
private Predicate condEdate( String edate){
BooleanBuilder builder = new BooleanBuilder();
if(hasText(edate)) {
try {
LocalDateTime localDateTime = LocalDateTime.parse(edate + "T00:00:00");
builder.or(phoneStr.modifiedDate.loe(localDateTime)); // isrtDate <= edate
} catch (DateTimeParseException e) {
}
}
return builder;
}
또, 엔티티에 맞게 검색조건을 바꿨다면.. html파일에 검색 필드 값도 추가해줘야겠죠~.
index, insert, update. 3개의 파일에서 검색조건부분을 변경해줌니다.
<option th:value="id" th:selected="${#strings.trim(param.field) eq 'id'}">id</option>
<option th:value="phoneNumber" th:selected="${#strings.trim(param.field) eq 'phoneNumber'}">전화번호</option>
잘 되는 걸 볼 수 있습니다. 테이블 만들기가 수월해지겠군요.
처음 배우시는 분들은, 인터넷 강의 듣기 추천드려요~. QueryDSL.
중복코드가 치기 싫다... 이러신 분들이라던지, 현업에서 일하시는 분들이라든지... 도움이 되었으면 좋겠습니다.
빠르면, 5초.... 과장해서요. 한 5분정도 걸리는 것 같아요~. 원래 타이핑하려면... 3~4시간.. 혹은 하루의 시간이 걸리는 양이라고 생각해봄니다.
저도 제가 만들고 있는 코드... 이어서 만들어야죠~. 좋은 하루, 좋은 개발되세요.
--
저의 글, 봐 주셔서 감사합니다.
'프로그래밍' 카테고리의 다른 글
[일상] 빠르면 오늘 중에 완성... 스프링부트 JPA + 타임리프... 자동코드. 그렇군요. (0) | 2023.01.22 |
---|---|
[웹앱 디자인] 스프링부트JPA 9. 개발 방식- 앱화면 기초, 템플릿 만들기. -2 (2) | 2023.01.16 |
[웹 프로그래밍] 스프링부트JPA 7-2. QueryDSL설명~. 검색기능. (0) | 2023.01.12 |
[웹앱 디자인] 스프링부트JPA 7. 개발방식, 데이터를 게시판 CRUD화 하기. CRUD프로젝트 생성. (0) | 2023.01.09 |
[웹앱 디자인] 스프링부트JPA 6. 개발 방식- 앱화면 기초, 템플릿 만들기. (0) | 2023.01.08 |