Skip to content

Commit

Permalink
#2 feat: 채용공고 등록/조회 API 개발 (#5)
Browse files Browse the repository at this point in the history
Co-authored-by: kanghoon-choi <[email protected]>
  • Loading branch information
Pokbab and Pokbab authored Jul 28, 2023
1 parent d0c99fb commit 2efcb13
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 12 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,27 @@
import com.example.jehunonboarding.controller.request.*;
import com.example.jehunonboarding.controller.response.CommonResponse;
import com.example.jehunonboarding.controller.response.JobPostingFindDetailResponse;
import com.example.jehunonboarding.controller.response.JobPostingSearchResponse;
import com.example.jehunonboarding.controller.response.JobPostingsSearchResponse;
import com.example.jehunonboarding.domain.JobPosting;
import com.example.jehunonboarding.domain.JobPostingService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
public class JobPostingController {

private final JobPostingService jobPostingService;

@PostMapping("/v1/job-postings")
public ResponseEntity<CommonResponse> register(@RequestBody JobPostingRegisterRequest request) {
public ResponseEntity<CommonResponse> register(@Valid @RequestBody JobPostingRegisterRequest request) {
jobPostingService.register(request.toDomain());
return new ResponseEntity(new CommonResponse(true), HttpStatus.OK);
}

Expand All @@ -27,8 +38,9 @@ public ResponseEntity<CommonResponse> remove(@PathVariable int jobPostingId) {
}

@GetMapping("/v1/job-postings")
public ResponseEntity<JobPostingSearchResponse> search(String keyword) {
return new ResponseEntity(new JobPostingSearchResponse(), HttpStatus.OK);
public ResponseEntity<JobPostingsSearchResponse> search(String keyword, Pageable pageable) {
List<JobPosting> jobPostings = jobPostingService.search(pageable, keyword);
return new ResponseEntity(new JobPostingsSearchResponse(jobPostings), HttpStatus.OK);
}

@GetMapping("/v1/job-postings/{jobPostingId}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package com.example.jehunonboarding.controller.request;

import com.example.jehunonboarding.domain.JobPostingRegisterInfo;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

@Data
public class JobPostingRegisterRequest {
@NotNull
private int companyId;
private String companyName;
private String nation;
private String region;
@NotNull
private String jobPosition;
@NotNull
private long jobCompensation;
@NotNull
private String description;
@NotNull
private String skill;

public JobPostingRegisterInfo toDomain() {
return new JobPostingRegisterInfo(companyId, jobPosition, jobCompensation, description, skill);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.jehunonboarding.controller.response;

import com.example.jehunonboarding.domain.JobPosting;
import lombok.Data;

import java.util.List;
import java.util.stream.Collectors;

@Data
public class JobPostingsSearchResponse {
private List<JobPostingResponse> items;

public JobPostingsSearchResponse(List<JobPosting> jobPostings) {
this.items = jobPostings.stream()
.map(JobPostingResponse::new)
.collect(Collectors.toList());
}

@Data
static class JobPostingResponse {
private int companyId;
private String companyName;
private String nation;
private String region;
private String jobPosition;
private long jobCompensation;
private String skill;

public JobPostingResponse(JobPosting jobPosting) {
this.companyId = jobPosting.getCompanyId();
this.companyName = jobPosting.getCompanyName();
this.nation = jobPosting.getNation();
this.region = jobPosting.getRegion();
this.jobPosition = jobPosting.getJobPosition();
this.jobCompensation = jobPosting.getJobCompensation();
this.skill = jobPosting.getSkill();
}
}
}


20 changes: 20 additions & 0 deletions src/main/java/com/example/jehunonboarding/domain/Company.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.jehunonboarding.domain;

import jakarta.persistence.*;

@Entity
@Table(name = "company")
public class Company {
@Id
@GeneratedValue
private int id;

@Column(nullable = false)
private String companyName;

@Column(nullable = false)
private String nation;

@Column(nullable = false)
private String region;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.example.jehunonboarding.controller.response;
package com.example.jehunonboarding.domain;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Data
public class JobPostingSearchResponse {
@Getter
@AllArgsConstructor
public class JobPosting {
private int companyId;
private String companyName;
private String nation;
private String region;
private String jobPosition;
private long jobCompensation;
private String description;
private String skill;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.example.jehunonboarding.domain;

import jakarta.persistence.*;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "job_posting")
@NoArgsConstructor
public class JobPostingEntity {
@Id
@GeneratedValue
@Column(nullable = false)
private Long id;

@Column(nullable = false)
private int companyId;

@Column(nullable = false)
private String jobPosition;

@Column(nullable = false)
private long jobCompensation;

@Column(nullable = false)
private String description;

@Column(nullable = false)
private String skill;

public JobPostingEntity(int companyId, String jobPosition, long jobCompensation, String description, String skill) {
this.companyId = companyId;
this.jobPosition = jobPosition;
this.jobCompensation = jobCompensation;
this.description = description;
this.skill = skill;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.jehunonboarding.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class JobPostingRegisterInfo {
private int companyId;
private String jobPosition;
private long jobCompensation;
private String description;
private String skill;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.jehunonboarding.domain;

import com.example.jehunonboarding.repository.CompanyRepository;
import com.example.jehunonboarding.repository.JobPostingRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class JobPostingService {

private final JobPostingRepository jobPostingRepository;
private final CompanyRepository companyRepository;

public void register(JobPostingRegisterInfo registerInfo) {
companyRepository.findById(registerInfo.getCompanyId())
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회사입니다."));

jobPostingRepository.save(
new JobPostingEntity(
registerInfo.getCompanyId(),
registerInfo.getJobPosition(),
registerInfo.getJobCompensation(),
registerInfo.getDescription(),
registerInfo.getSkill()
)
);
}

public List<JobPosting> search(Pageable pageable, String keyword) {
return jobPostingRepository.findByKeyword(pageable, keyword);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.jehunonboarding.repository;

import com.example.jehunonboarding.domain.Company;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CompanyRepository extends JpaRepository<Company, Integer> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.jehunonboarding.repository;

import com.example.jehunonboarding.domain.JobPosting;
import com.example.jehunonboarding.domain.JobPostingEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface JobPostingRepository extends JpaRepository<JobPostingEntity, Long> {

@Query("SELECT new com.example.jehunonboarding.domain.JobPosting(c.id, c.companyName, c.nation, c.region, jp.jobPosition, jp.jobCompensation, jp.description, jp.skill) FROM JobPostingEntity jp INNER JOIN Company c ON jp.companyId = c.id WHERE jp.jobPosition LIKE %:keyword% OR c.companyName LIKE %:keyword%")
List<JobPosting> findByKeyword(Pageable pageable, String keyword);
}
1 change: 0 additions & 1 deletion src/main/resources/application.properties

This file was deleted.

17 changes: 17 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
generate-unique-name: false
jpa:
defer-datasource-initialization: true
properties:
hibernate:
format_sql: true
show_sql: true
ddl-auto: create
database-platform: org.hibernate.dialect.H2Dialect
h2:
console:
enabled: true
1 change: 1 addition & 0 deletions src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO company (id, company_name, nation, region) VALUES (1, '제훈테크', '한국', '서울');

0 comments on commit 2efcb13

Please sign in to comment.