Spring 강의 day 11

주세환·2023년 5월 12일
0

Spring

목록 보기
11/18

MemberInfo

회원가입(one to one))

CREATE TABLE memberinfo1(
id1 varchar2(50) PRIMARY KEY,
info varchar2(255),
regdate timestamp DEFAULT current_timestamp,
FOREIGN KEY (id1) REFERENCES member1(id)
);

memberinfo1 테이블을 생성한다.

---

```java
@ToString.Exclude
@OneToOne(mappedBy = "member1", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private MemberInfo1 memberInfo1;

entity폴더의 Member1.java에 위 코드를 추가한다.


// one to one
@GetMapping(value="/join1.do")
public String join1GET(){
    try{
        return "/member/join1";
    }catch(Exception e){
        e.printStackTrace();
        return "redirect:/home.do";
    }
}

@PostMapping(value="/join1.do")
public String join1POST(@ModelAttribute Member1 member1,
@ModelAttribute MemberInfo1 memberInfo1){
    try{
        // Member1(id=b11, pw=a, name=b, age=1, regdate=null, memberInfo1=null)
        log.info("{}", member1);
        member1.setMemberInfo1(memberInfo1);

        // MemberInfo1(id=null, member1=null, info=정보, regdate=null)
        log.info("{}", memberInfo1);
        memberInfo1.setMember1(member1);

        m1Repository.save(member1); // 두 개의 테이블에 값이 동시에 추가됨

        return "redirect:/member1/join1.do";
    }catch(Exception e){
        e.printStackTrace();
        return "redirect:/home.do";
    }
}

Member1Controller에 join1을 추가한다.

<body>
    <h3>join1(one to one)</h3>

    <form th:action="@{member1/join.do}" method="post">
        <input type="text" name="id" /><br />
        <input type="text" name="pw" value="a"/><br />
        <input type="text" name="name" value="b" /><br />
        <input type="number" name="age" value="1" /><br />
        <input type="text" name="info" value="정보" /><br />
        <input type="submit" value="회원가입" /><br />
    </form>
</body>

join1.html또한 생성한다.


Menu

@Slf4j
@Controller
@RequestMapping(value = "/menu1")
@RequiredArgsConstructor
public class Menu1Controller {

    final Restaurant1Repository r1Repository;
    final Menu1Repository m1Repository;
    
    @Value("${default.image}") String DEFAULTIMAGE;
    final ResourceLoader resourceLoader;

    @GetMapping(value="/update.food")
    public String updateGET(
        Model model,
        @RequestParam(name="no") long no,
        @RequestParam(name="rno") long rno,
        @RequestParam(name="rphone") String rphone) {
        try {
            Menu1 obj = m1Repository
                .findById(BigInteger.valueOf(no)).orElse(null);
            model.addAttribute("obj", obj);
            model.addAttribute("rno", rno);
            model.addAttribute("rphone", rphone);
            return "/menu1/update";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }

    @Transactional(value = Transactional.TxType.NEVER)
@PostMapping(value="/update.food")
public String updatePOST( 
        @ModelAttribute Menu1 obj, 
        @RequestParam(name="tmpFile") MultipartFile file ) {
    try {
        log.info(obj.toString());
        log.info(file.toString());
        // 기존데이터 읽기
        Menu1 obj1 = m1Repository.findById( obj.getNo() ).orElse(null);

        // 저장하면 자동으로 DB에 변경됨.
        obj1.setName( obj.getName() );
        obj1.setPrice( obj.getPrice() );
        
        // 기존데이터를 읽어서 필요한 부분 변경후 다시 저장하기
        if(file.isEmpty() == false) {
            obj1.setImagedata( file.getBytes() );
            obj1.setImagename( file.getOriginalFilename() );
            obj1.setImagesize( BigInteger.valueOf( file.getSize() ) );
            obj1.setImagetype( file.getContentType() );
        }
        m1Repository.saveAndFlush(obj1);

        return "redirect:/menu1/insert.food?rno=" + obj.getRestaurant1().getNo() 
            + "&rphone=" + obj.getRestaurant1().getPhone();
    } catch (Exception e) {
        e.printStackTrace();
        return "redirect:/home.do";
    }
}

    @PostMapping(value="/delete.food")
    public String deletePOST(
            @RequestParam(name="no") long no,
            @RequestParam(name="rno") long rno,
            @RequestParam(name="rphone") String rphone){
        try {
            m1Repository.deleteById( BigInteger.valueOf(no) );
            log.info("{}",no);
            return "redirect:/menu1/insert.food?rno=" + rno + "&rphone=" + rphone;
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }
    
    // 이미지는 DB에서 꺼내서 url형태로 변경시키야 함.
    // 127.0.0.1:9090/ROOT/menu1/image?no=1
    // <img src="/ROOT/menu1/image?no=????" />
    @GetMapping(value = "/image")
    public ResponseEntity<byte[]> image(@RequestParam(name = "no", defaultValue = "0") long no) throws IOException {
        Menu1ImageProjection obj = m1Repository.findByNo( BigInteger.valueOf(no) );
        HttpHeaders headers = new HttpHeaders();
        if(obj != null) { //이미지가 있는 경우
            if(obj.getImagesize().longValue() > 0) {
                headers.setContentType( MediaType.parseMediaType( obj.getImagetype() ) );
                return new ResponseEntity<>( obj.getImagedata(), headers, HttpStatus.OK );
            }
        }
        //이미지가 없을 경우
        InputStream is = resourceLoader.getResource(DEFAULTIMAGE).getInputStream(); // exception 발생됨.
        headers.setContentType(MediaType.IMAGE_PNG);
        return new ResponseEntity<>( is.readAllBytes(), headers, HttpStatus.OK );
    }



    // 127.0.0.1:9090/ROOT/menu1/insert.food
    @GetMapping(value="/insert.food")
    public String insertGET(Model model, 
            @RequestParam(name="rno") long rno,
            @RequestParam(name="rphone") String rphone) {
        try {

            List<Menu1> list = m1Repository.findByRestaurant1_phone(rphone);
            model.addAttribute("list", list);
            model.addAttribute("rphone", rphone);
            model.addAttribute("rno", rno);
            return "/menu1/insert";
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }


    @PostMapping(value="/insert.food")
    public String insertPOST(
        @ModelAttribute Menu1 obj, 
        @RequestParam(name = "tmpFile") MultipartFile file) {
        try {
            // 파일은 수동으로 obj에 추가하기
            obj.setImagedata( file.getInputStream().readAllBytes() );
            obj.setImagesize( BigInteger.valueOf( file.getSize() ) );
            obj.setImagetype( file.getContentType() );
            obj.setImagename( file.getOriginalFilename() );

            log.info("Menu1 => {}", obj.toString());

            m1Repository.save(obj);
            return "redirect:/menu1/insert.food?rno=" + obj.getRestaurant1().getNo() 
                    + "&rphone=" + obj.getRestaurant1().getPhone();
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/home.do";
        }
    }
}

insert.html

<body>
    <h3>메뉴 관리</h3>
    <a th:href="@{/restaurant1/selectlist.food}"><button>식당목록</button></a><br />
    식당번호    : <label th:text="${rno}"></label><br />
    식당연락처    : <label th:text="${rphone}"></label><br />
    <hr>

    <h3>현재 등록된 메뉴 목록</h3>
    <table border="1">  
            <tr>
                <td>메뉴이미지</td>
                <td>메뉴번호</td>
                <td>메뉴이름</td>
                <td>메뉴가격</td>
            </tr>
            <tr th:each="obj : ${list}">
                <td><img th:src="@{/menu1/image(no=${obj.no})}" style="width:50px;height:50px" /></td>
                <td th:text="${obj.no}"></td>
                <td th:text="${obj.name}"></td>
                <td th:text="${obj.price}"></td>
                <td th:text="${obj.regdate}"></td>
                <td>
                    <a th:href="@{/menu1/update.food(no=${obj.no}, rno=${rno}, rphone=${rphone})}"><button>수정</button></a>
                    <button th:onclick="deleteAction([[${obj.no}]])">삭제</button>
                </td>
            </tr>
    </table>
    <hr>

    <h3>메뉴등록</h3>
    <form th:action="@{/menu1/insert.food}" method="post" enctype="multipart/form-data">
        메뉴명 : <input type="text" name="name"/><br />
        가격 : <input type="number" name="price" /><br />
        식당번호(변경x) : <input type="text" name="restaurant1.no" th:value="${rno}" readonly /><br />
        식당연락처(변경x) : <input type="text" name="restaurant1.phone" th:value="${rphone}" readonly /><br />
        이미지 : <input type="file" name="tmpFile" /><br />
        <input type="submit" value="메뉴등록" />
    </form>

    <form th:action="@{/menu1/delete.food}" method="post" id="form2" style="display:none">
        <input type="hidden" name="no" id="hidden_no" />
        <input type="hidden" name="rno" th:value="${rno}" />
        <input type="hidden" name="rphone" th:value="${rphone}" />
    </form>

    <script th:inline="javascript">
        function deleteAction(no){
            if( confirm('삭제할까요?')){
                document.getElementById('hidden_no').value = no;
                document.getElementById('form2').submit();
            }

        }
    </script>

</body>

insert

메뉴등록에 값들을 입력, 파일을 선책한 후에 메뉴등록을 누르면

이렇게 정상적으로 메뉴가 등록된다.


update

수정 버튼을 눌러서 해당 페이지로 이동한다.

변경할 값과 변경할 이미지를 선택하여 메뉴변경을 누르면

입력한 값과 이미지로 변경된 모습을 볼 수 있다.


delete

삭제를 누르면 삭제할까요? 라는 알림창이 뜬다.

확인을 누르면 삭제된 모습을 볼 수 있다.


Library

DB

시퀀스

CREATE SEQUENCE seq_library2_code START WITH 1 INCREMENT BY 1  NOCACHE NOMAXVALUE;
CREATE SEQUENCE seq_book2_code START WITH 101 INCREMENT BY 1  NOCACHE NOMAXVALUE;
CREATE SEQUENCE seq_admin2_no START WITH 201 INCREMENT BY 1  NOCACHE NOMAXVALUE;
CREATE SEQUENCE seq_checkout2_code START WITH 301 INCREMENT BY 1  NOCACHE NOMAXVALUE;

테이블

CREATE TABLE library2(
	code number(19) DEFAULT seq_library2_code.nextval,
	name varchar2(50),
	address varchar2(200),
	phone varchar2(20),
	regdate timestamp DEFAULT current_timestamp,
	PRIMARY key(code)
);

library2


CREATE TABLE student2(
	email varchar2(100),
	name varchar2(50),
	phone varchar2(20),
	regdate timestamp DEFAULT current_timestamp,
	PRIMARY key(email)
);

student2


CREATE TABLE admin2(
	num number(19) DEFAULT seq_admin2_no.nextval,
	name varchar2(50),
	libcode number(19),
	regdate timestamp DEFAULT current_timestamp,
	PRIMARY key(num),
	FOREIGN key(libcode) REFERENCES library2(code)
);

admin2


CREATE TABLE book2(
	code number(19) DEFAULT seq_book2_code.nextval,
	title varchar2(50),
	price number(19),
	author varchar2(50),
	regdate timestamp DEFAULT current_timestamp,
	libcode number(19),
	PRIMARY key(code),
	FOREIGN key(libcode) REFERENCES library2(code)
);

book2


CREATE TABLE checkout2(
	code number(19) DEFAULT seq_checkout2_code.nextval,
	bkcode number(19),
	stdemail varchar2(50),
	regdate timestamp DEFAULT current_timestamp,
	PRIMARY key(code),
	FOREIGN key(bkcode) REFERENCES book2(code),
	FOREIGN key(stdemail) REFERENCES student2(email)
);

checkout2


vscode

entity 폴더에 library 폴더를 생성하고 그 안에 아래 파일들을 생성하여 추가한다.

@EntityScan(basePackages = { "com.example.entity","com.example.entity.library" }) // 엔티티 위치

Boot20230427Application.java를 수정하고


@Data
@Entity
@Table(name="LIBRARY2")
@SequenceGenerator(name = "SEQ_LIBRARY2_CODE", sequenceName = "SEQ_LIBRARY2_CODE", initialValue = 1, allocationSize = 1)
public class Library2 {
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_LIBRARY2_CODE")
    @Column(name="CODE")
    private BigInteger code;

    private String name;

    private String address;

    private String phone;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    @Column(name="REGDATE", updatable = false)
    private Date regdate;
    
    @ToString.Exclude
    @OneToMany(mappedBy = "libcode", cascade=CascadeType.REMOVE, fetch=FetchType.LAZY)
    private List<Admin2> admin2 = new ArrayList<>();
    
    @ToString.Exclude
    @OneToMany(mappedBy = "libcode", cascade=CascadeType.REMOVE, fetch=FetchType.LAZY)
    private List<Book2> book2 = new ArrayList<>();
}

Library2.java


@Data
@Entity
@Table(name="ADMIN2")
@SequenceGenerator(name = "SEQ_ADMIN2_NO", sequenceName = "SEQ_ADMIN2_NO", initialValue = 1, allocationSize = 1)
public class Admin2 {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ADMIN2_NO")
    private BigInteger num;
    
    private String name;
    
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="LIBCODE", referencedColumnName = "CODE")
    private Library2 libcode;
    
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    @Column(name="REGDATE", updatable = false)
    private Date regdate;
}

Admin2.java


@Data
@Entity
@Table(name="BOOK2")
@SequenceGenerator(name = "SEQ_BOOK2_CODE", sequenceName = "SEQ_BOOK2_CODE", initialValue = 1, allocationSize = 1)
public class Book2 {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_BOOK2_CODE")
    private BigInteger code;
    
    private String title;
    
    private BigInteger price;
    
    private String author;
    
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="LIBCODE", referencedColumnName = "CODE")
    private Library2 libcode;
    
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    @Column(name="REGDATE", updatable = false)
    private Date regdate;
    
    
    @ToString.Exclude
    @OneToMany(mappedBy = "bkcode", cascade=CascadeType.REMOVE, fetch=FetchType.LAZY)
    private List<Checkout2> checkout2 = new ArrayList<>();
    
}

Book2.java


@Data
@Entity
@Table(name="STUDENT2")
public class Student2 {

    @Id
    private String email;
    
    private String name;
    
    private String phone;
    
 
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    @Column(name="REGDATE", updatable = false)
    private Date regdate;
    
    @ToString.Exclude
    @OneToMany(mappedBy = "stdemail", cascade=CascadeType.REMOVE, fetch=FetchType.LAZY)
    private List<Checkout2> checkout2 = new ArrayList<>();
}

Student2.java


@Data
@Entity
@Table(name="CHECKOUT2")
@SequenceGenerator(name = "SEQ_CHECKOUT2_CODE", sequenceName = "SEQ_CHECKOUT2_CODE", initialValue = 1, allocationSize = 1)
public class Checkout2 {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_CHECKOUT2_CODE")
    private BigInteger code;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="BKCODE", referencedColumnName = "CODE")
    private Book2 bkcode;


    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="STDEMAIL", referencedColumnName = "EMAIL")
    private Student2 stdemail;

    
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @CreationTimestamp
    @Column(name="REGDATE", updatable = false)
    private Date regdate;
}

Checkout2.java


이렇게 서로 연동을 시킨다.


0개의 댓글