Product. TEST_20220418
package com.example.repository;
import com.example.entity.ProductEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
// crud는 기본적인 것들만 들어있음. Jpa 쓰는게 좋을듯?
public interface ProductRepository extends CrudRepository<ProductEntity, Long> {
}
package com.example.service;
import java.util.List;
import com.example.entity.ProductEntity;
import org.springframework.stereotype.Service;
@Service
public interface ProductService {
public int insertBatch(List<ProductEntity> product);
}
package com.example.service;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import com.example.entity.ProductEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductServiceImpl implements ProductService{
@Autowired EntityManagerFactory emf;
@Override
public int insertBatch(List<ProductEntity> list) {
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
for(ProductEntity prd: list) {
em.persist(prd);
}
em.getTransaction().commit();
return 1;
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
return 0;
}
}
}
ProductRestController.javapackage com.example.restcontroller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.example.entity.ProductEntity;
import com.example.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
// API를 설정하지 않으면 스마트폰 앱으로 만들 경우 앱에서 데이터를 가져갈 수 없음.(포스트맨은 그래도 됨)
@CrossOrigin("*")
@RequestMapping(value = "/api/product")
public class ProductRestController {
@Autowired ProductRepository pRepository;
// 127.0.0.1:9090/ROOT/api/product/insert.json
@PostMapping(
value = "/insert.json",
consumes = { MediaType.ALL_VALUE },
produces = { MediaType.APPLICATION_JSON_VALUE })
public Map<String, Object> insertPOST(
@ModelAttribute ProductEntity product,
// required = false => 이미지 첨부 해도 되고 안해도 된다
@RequestParam(name = "file", required = false) MultipartFile file) {
Map<String, Object> map = new HashMap<String, Object>();
try {
if(file != null) {
if(!file.isEmpty()) {
product.setImagedata(file.getBytes());
product.setImagename(file.getOriginalFilename());
product.setImagetype(file.getContentType());
product.setImagesize(file.getSize());
}
}
pRepository.save(product);
map.put("status", 200);
} catch (Exception e) {
e.printStackTrace();
map.put("status", 0);
}
return map;
}
// 저장소를 이용하지 못함. 서비스를 써야함
@PostMapping(
value = "/insertbatch.json",
consumes = { MediaType.ALL_VALUE },
produces = { MediaType.APPLICATION_JSON_VALUE })
public Map<String, Object> insertbatchPOST(
// 배열은 Modelattribute 못씀
@RequestParam(name = "name") String[] name,
@RequestParam(name = "price") String[] price,
// required = false => 이미지 첨부 해도 되고 안해도 된다
@RequestParam(name = "file") MultipartFile file) {
Map<String, Object> map = new HashMap<String, Object>();
try {
List<ProductEntity> list = new ArrayList<>();
// 서비스를 사용하지 않고 하는 방법
pRepository.saveAll(list);
map.put("status", 200);
} catch (Exception e) {
e.printStackTrace();
map.put("status", 0);
}
return map;
}
@PutMapping(
value = "/update.json",
consumes = { MediaType.ALL_VALUE },
produces = { MediaType.APPLICATION_JSON_VALUE })
public Map<String, Object> updatebatch(
@RequestBody ProductEntity product) {
Map<String, Object> map = new HashMap<String, Object>();
try {
// 1개 꺼내기
ProductEntity product1 = pRepository.findById(product.getNo()).orElse(null);
// 필요정보 변경
product1.setName(product.getName());
product1.setPrice(product.getPrice());
pRepository.save(product1);
map.put("status", 200);
} catch (Exception e) {
e.printStackTrace();
map.put("status", 0);
}
return map;
}
}
ProductEntity.javapackage com.example.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@Data
@Entity
@Table(name = "PRODUCT")
@SequenceGenerator(
name = "SEQ3",
sequenceName = "SEQ_PRODUCT_NO",
allocationSize = 1,
initialValue = 1001
)
public class ProductEntity {
@Id
@GeneratedValue(generator = "SEQ3", strategy = GenerationType.SEQUENCE)
Long no;
@Column(length = 250)
String name;
Long price;
@Lob
@Column(nullable = true)
byte[] imagedata;
String imagename;
String imagetype;
Long imagesize = 0L;
// updatetimestamp => 변경 될때도 날짜 바뀜
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
@UpdateTimestamp // CURRENT_DATE
Date uptdate;
}
package com.example;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
import com.example.entity.ProductEntity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
public class ProductRestControllerTest {
RestTemplate restTemplate;
@BeforeEach
public void setup() {
restTemplate = new RestTemplate();
}
// http://127.0.0.1:9090/ROOT/api/product/insert.json
// @ModelAttribute
@Test
public void insertTest() {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("name", "테스트용");
body.add("price", 1234L);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
ResponseEntity<String> result = restTemplate.exchange("http://127.0.0.1:9090/ROOT/api/product/insert.json",
HttpMethod.POST, entity, String.class);
assertThat(result.getStatusCode().toString()).isEqualTo("200 OK");
}
// http://127.0.0.1:9090/ROOT/api/product/update.json
// @RequestBody
@Test
public void PatchTest() {
ProductEntity product = new ProductEntity();
product.setNo(1001L);
product.setName("솔");
product.setPrice(5353L);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<ProductEntity> entity = new HttpEntity<>(product, headers);
ResponseEntity<String> result = restTemplate.exchange("http://127.0.0.1:9090/ROOT/api/product/update.json",
HttpMethod.PUT, entity, String.class);
assertThat(result.getStatusCode().toString()).isEqualTo("200 OK");
}
}
<template>
<div>
<el-card class="fade-in-left" shadow="always">
<h3>product</h3>
<hr />
<el-form>
<el-form-item label="제품명: " label-width="120px">
<el-input type="text" v-model="state.name" style="width:192px"/>
</el-form-item>
<el-form-item label="가격: " label-width="120px">
<el-input type="text" v-model="state.price" style="width:192px"/>
</el-form-item>
<el-image :src="state.imageUrl" style="width: 50px; margin-left: 120px;" />
<el-form-item label="이미지: " label-width="120px">
<input type="file" style="width:192px" @change="handleImage($event)" />
</el-form-item>
</el-form>
<el-button style="margin-left: 120px" @click="handleInsert" >등록하기</el-button>
</el-card>
<el-card class="fade-in-left" shadow="always">
<div v-for="(tmp, idx) in 2" :key = "tmp" >
<el-form>
<el-form-item label="제품명: " label-width="120px">
<el-input type="text" v-model="state.name1[idx]" style="width:192px"/>
</el-form-item>
<el-form-item label="가격: " label-width="120px">
<el-input type="text" v-model="state.price1[idx]" style="width:192px"/>
</el-form-item>
<el-image :src="state.imageUrl1[idx]" style="width: 50px; margin-left: 120px;" />
<el-form-item label="이미지: " label-width="120px">
<input type="file" style="width:192px" @change="handleImage1($event, idx)" />
</el-form-item>
</el-form>
</div>
<el-button style="margin-left: 120px" @click="handleInsert1" >등록하기1</el-button>
</el-card>
</div>
</template>
<script>
import { reactive } from 'vue'
import axios from 'axios';
export default {
setup () {
const state = reactive({
name : '',
price : '',
imageUrl : require('../assets/logo.png'),
imageFile: null,
name1 : ['', ''],
price1 : ['', ''],
imageUrl1 : [require('../assets/logo.png'), require('../assets/logo.png')],
imageFile1: []
});
const handleImage = (e) => {
if(e.target.files[0]) {
state.imageUrl = URL.createObjectURL(e.target.files[0])
state.imageFile = e.target.files[0];
} else {
state.imageUrl = require('../assets/logo.png');
state.imageFile = null;
}
}
const handleImage1 = (e, idx) => {
if(e.target.files[0]) {
state.imageUrl1[idx] = URL.createObjectURL(e.target.files[0])
state.imageFile1[idx] = e.target.files[0];
} else {
state.imageUrl1[idx] = require('../assets/logo.png');
state.imageFile1[idx] = null;
}
}
const handleInsert = async() => {
const url = `/ROOT/api/product/insert.json`;
const headers = { "Content-Type": "form-data" };
const body = new FormData();
body.append("name", state.name);
body.append("price", state.price);
body.append("file", state.imageFile);
const response = await axios.post(url, body, { headers });
console.log(response.data);
}
const handleInsert1 = async() => {
const url = `/ROOT/api/product/insertbatch.json`;
const headers = { "Content-Type": "form-data" };
const body = new FormData();
for(let i=0; i<state.name1.length; i++) {
body.append("name", state.name1[i]);
body.append("price", state.price1[i]);
body.append("file", state.imageFile1[i]);
}
const response = await axios.post(url, body, { headers });
console.log(response.data);
}
return { state, handleImage, handleImage1, handleInsert, handleInsert1 }
}
}
</script>
<style lang="scss" scoped>
@import url(../assets/css/mystyle.css);
</style>
Reference
この問題について(Product. TEST_20220418), 我々は、より多くの情報をここで見つけました https://velog.io/@gegus1220/Product.-TEST20220418テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol