MyBatis

1. 강의 개요 및 MySQL 서버 설치하기

MyBatis를 mysql을 사용한다고 하신다.
https://velog.io/@alicesykim95/Oracle%EA%B3%BC-MySQL%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90
오라클만배웟으니 차이점을 봐보자
mysql은 무료 dbms이다. sql작성은 비슷하다. 오라클과 차이를 배워보자.

https://dev.mysql.com/downloads/mysql/
커뮤니티 버전 다운로드

기본포트 3306
서비스가면 부팅되면 자동으로 실행되게끔 됫다.

2. 데이터베이스와 사용자 계정 추가하기


db를 만들면서 캐릭터를 설정할 수도앗다.
command line client, workbench등 다양하게 잇다.
show databases;
use sakila;
show tables;
컨트롤 엔터하면 실행된다. cmd보다는 비주얼로 보는게 나으니 wokbench사용하자.

create database newlecutre default character set utf8;
show databases;
데이터베이스 만들가 해서 보면 있다.

ddl명령어로 사용자 추가하기
create user 사용자id; 사용자만추가
create user 사용자id@localhost identified by '비밀번호'; 비밀번호를 함께 설정추가
create user 'userid'@%' identified by 'password'; 외부'%'에서 접근을 허용

sql명령어로 사용자 추가하기
use mysql;
insert into user(Host, User, Password)
values ('localhost', 'userid', password('password'));
insert into user(Host, User, Password)
values ('%', 'userid', password('password'));

특정 ip 설정을 할 수잇다. 그냥사용해도 기본이 %이다.
create user newlec identified by '111';

모든권한 부여하기

create database newlecture default character set utf8;
show databases;

create user newlecuture identified by '111';
grant all privileges on newlecture.* to newlecuture;
grant all privileges on db이름.* to 사용자id;

!!!오류!!!
db를만들고 권한을 부여해야하는데 db가 안보엿다. 오타로 인해서 db이름을 잘못만든거엿고 다른 이름으로 권한을 부여하니 안된거엿음.

3. 테이블 생성하기


오라클과 동일
테이블은 모델링으로 만든다. 그림으로 도식화하고 만든다. 결과물이 결정되면 그대로 만든다. 이것을 인간이 만드는게아니라 도구가 알아서 만든다.

모델 환경에서 알아서 하도록 한다.
sql문을 활용해서 만드는 것 대신
위 메뉴에서 테이블누르고 craete테이블할수도잇고 database누르고 reverse enginering
이 기본도구가 오류가 발생할 수잇으니 그냥 만들어도되지만 사용해보자.
그림을 그려서 테이블을 추가할 수잇다.

pk기본키 nn notnull ai = 1씩증가 등등 설정할수잇다. defualt 기본값
이렇게 만들면 mydb에 메모리상에만 존재하게 되는 것임.
MYSQL Model바에서 mydb의 것을 잘라내기해서 newlecture에 붙여넣기하면 옮겨진다.

이후 foward engeniner 하면 sql이 실행되면서 그린구조가 들어가게 된다.

4. 테이블 관계 제약조건 걸기

member테이블을 만들자. member가 공지사항을 등록하는 것이다.
notice 가 다 member가 1이기ㄸ문에 왼쪽 바에서 1대n을 선택하고 n테이블을 먼저 클릭하고 1테이블을 클릭한다.
comment댓글 테이블을 만들어주자 notice에서 달리고 멤버가 다는 것이기 관계설정을 해준다.
role은 멤버가 여러 역할을 가질 수잇으니 다대다 로 관계설정을 해준다.
그냥 옮기면 관계가 사라진다.

다양한 방식이이삳. 그런데 테이블 명이 소대문자 구별햇는데 대문자로 안바뀌어짐
lower_case_=1로되잇다. 퐌경변수가 그럼. 운영체제에 따라서 다르다. 윈도우는 소대문자 구분을 하지 않기때문임. 할수없이 '_'로 구분하자.

Springboot

17. Admin을 위한 Layout 페이지 만들기


customer처럼 admin페이지를 각각 잘라서 나눈다.

@GetMapping("list") 
public String list(Model model) {
    return "admin.board.notice.list";
}

@GetMapping("detail") 
public String detail() {
    return "admin.board.notice.detail";
}

@GetMapping("reg") 
public String reg() {
    return "admin.board.notice.reg";    
}

잊지 않고 리턴 값도 바꿔주자.
index페이지도 해주자.
<definition name="*" template="/WEB-INF/view/admin/inc/layout.jsp">
이렇게하면 모두가 걸리게 되서 문제가 된다. 폴더명이 없으니 가상으로 하나를 만들어주자.
약속만 지키는 것 이기때문에 가상의 폴더를 만들어준다고 생각하면된다.
<definition name="home.*" template="/WEB-INF/view/admin/inc/layout.jsp">

</definition>
 <definition name="home.*" template="/WEB-INF/view/inc/layout.jsp">
  <put-attribute name="title" value="Tiles tutorial homepage" />
  <put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
  <put-attribute name="main" value="/WEB-INF/view/{1}.jsp" />
  <put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
</definition>

18. Tiles의 추가 기능들

https://tiles.apache.org/framework/tutorial/index.html 가면 기능이잇음.
Tiles Advanced Topics
정의된 layout을 중첩할수잇다.
<put-attribute name="body" value="myapp.homepage.body" />
다른레이아웃인데 이것을 중첩할 수 잇다.

<definition template="/layouts/three_rows.jsp">
    <put-attribute name="one" value="/tiles/headlines.jsp" />
    <put-attribute name="two" value="/tiles/topics.jsp" />
    <put-attribute name="one" value="/tiles/comments.jsp" />
</definition>

<put-attribute name="one" value="/tiles/headlines.jsp" cascade="true" />
<put-attribute name="two" value="/tiles/topics.jsp" cascade="true" />
<put-attribute name="one" value="/tiles/comments.jsp" cascade="true" />

중첩할때 중간에 끼어넣거나 아예따로빼서 작성할 수도 잇다.

또한 레이아웃을 상속할 수도잇다.
우리는 3가지를 정의햇는데 3가지 내용이 다르기 때문이엇음. 근데 정의하니 똑같은 부분이 잇다.
header footer같은 부분 extends 상속할 타일 하면된다.
주소가 아예같다면 그냥 상속만 적어도된다.

<tiles-definitions>
    <definition name="layout.common" template="/WEB-INF/view/inc/layout.jsp">
    <put-attribute name="title" value="Tiles tutorial homepage" />
    <put-attribute name="header" value="/WEB-INF/view/inc/header.jsp" />
    <put-attribute name="footer" value="/WEB-INF/view/inc/footer.jsp" />
  </definition>
  <definition name="home.*" extends="layout.common">
    <put-attribute name="title" value="Tiles tutorial homepage" />
    <put-attribute name="main" value="/WEB-INF/view/{1}.jsp" />
  </definition>

  <definition name="customer.*.*" template="/WEB-INF/view/customer/inc/layout.jsp" extends="layout.common">
    <put-attribute name="title" value="Tiles tutorial homepage" />
    <put-attribute name="visual" value="/WEB-INF/view/customer/inc/visual.jsp" />
    <put-attribute name="aside" value="/WEB-INF/view/customer/inc/aside.jsp" />
    <put-attribute name="main" value="/WEB-INF/view/customer/{1}/{2}.jsp" />
  </definition>
   <definition name="admin.*.*.*" template="/WEB-INF/view/admin/inc/layout.jsp" extends="layout.common">
    <put-attribute name="title" value="Tiles tutorial homepage" />
    <put-attribute name="visual" value="/WEB-INF/view/admin/inc/visual.jsp" />
    <put-attribute name="aside" value="/WEB-INF/view/admin/inc/aside.jsp" />
    <put-attribute name="main" value="/WEB-INF/view/admin/{1}/{2}/{3}.jsp" />
  </definition>
</tiles-definitions>

<definition name="myapp.homepage.body" template="/layouts/variable_rows.jsp">
  <put-list-attribute name="items">
    <add-attribute value="/tiles/banner.jsp" />
    <add-attribute value="/tiles/common_menu.jsp" />
    <add-attribute value="/tiles/credits.jsp" />
  </put-list-attribute>
</definition>

<c:forEach var="item" items="${list}">
  <tiles:insertAttribute value="${item}" flush="true" />
  <br/>
</c:forEach>

foreach로 반복적이라면 리스트로 담아서 할 수도 잇다. 이 리스트도 상속이 가능하다. 정적으로 햇엇는데 api를 담을 수도 잇다.
이외에도 와일드카드(*)찍은것 el태그 등을 할수도잇다. 나중엔 View Preparers같은것도 사용한다.

19. MyBatis 설정하는 방법

사용자 입출력을 위해 구현체가 직접 sql을 거치는게아니라 인터페이스를 통해 활용한다. dao로 서비스를 구현한다.
자바 객체로만 데이터를 가져올 수있게 되는 것이다.

마이바티스가 dao의 반복적인 작업을 반복적인 소모성 코드를 줄여주는 역할을 한다.
mybatis설정 여러가지 설정이잇엇느네 많이 줄어들엇음.
db연결하려면 데이터소스 정보를 가져왓어야하는데 알아서 해줌 ioc담은것도 알아서 담아줌
db계정만 설정하면된다. 멤버 객체를 구현할때 쿼리부분만 얹어주면 끝난다.

20. Service와 Dao 구현체 준비하기

최소한의 기능이 있어야한다.

@Autowired
private NotcieService service;

@GetMapping("list") 
public String list(Model model) {
    List<Notice> list = service.getList();
    return "admin.board.notice.list";
}

notic객체를 리스트로 담아서 getLiset하자.
NotcieService객체를 만들고 여기의 getList를 메소드를 사용할 것이다.
각각 구현할 내용들을 만들어준다.

package com.newlecture.web.entity;

public class Notice {
}

public interface NotcieService {

List<Notice> getList();

//detail페이지 목록가져오기
Notice get(int i); 
}

NotcieService 구현

public class NoticeServiceImp implements NoticeService {

@Autowired
private NoticeDao noticeDao;

@Override
public List<Notice> getList() {
    List<Notice> list = noticeDao.getList();

    return list;
}

@Override
public Notice get(int id) {

    Notice notice = noticeDao.get(id);
    return null;
}}

서비스는 또 직접 하는게 아니라 dao에서 하게 만들어야되서 Dao인터페이스를 또 생성해준다.

public interface NoticeDao {
List<Notice> getList();
Notice get(int id);
}

여기서 dao인터페이스가 제공받은것을 클래스로 구현해야하지만 이 구현하는 것을 마이바티스를 사용하면 직접 클래스를 만들필요가없다.

21. Mapper 객체 만들기

마이바티스를 설정하고 구현해보자. 라이브러리를 추가해야한다.
pom.xml에서 설정해도되지만 스타터즈가 포함되어잇다.
프로젝트 우클릭 - spring - add staters mybatis와 mysql을 추가해주자.


알아서 업데이트 해준다. 이제 마이바티스의 본연의 업무인 NoticeDao를 구현하면되는데 그냥 매핑만 해주면된다.

@Mapper
public interface NoticeDao {

    @Select("select * from notice")
    List<Notice> getList();

    Notice get(int id);

}

구문에따라 @Select @Insert등을 작성해주고 sql문을 넣어주면된다.
그리고 매핑이 되어있음을 알리기위해 @Mapper를 작성해주면된다.
밑에거도 꼭해야하는 것은 아니고 구현하고싶은거만 구현하면된다.
그리고 이 db가 어디에잇고 사용자 게정번호 등이 무엇인지 알려줘야한다.

application.properties으로 가서 설정하면된다.

# mysql settings
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/newlecture
spring.datasource.username=newlecture
spring.datasource.password=111

스프링 xml파일을 설정할때 datasource객체생성하여 DI햇던거랑 비슷하다. spring MVC강의의 23번 보기

이제 이것을 가져다쓰는 방법을 이해해야한다. IOC컨테이너와 DI를 알아야한다.

22. 스프링에서 객체 사용방법(dependency와 injection 그리고 IoC 컨테이너)

Dependency는 Product의 상대적인 이름이다. '의존성' '부품' B->C일때 C가 부품이다. A->B->C하면 상대적인 관계가 되는것이다.
현실적으로 대부분의 프로프램은 Main함수가 없다면 다 부품이라고 할 수 있다.
di부분은 스프링 강의 https://chunpinge.tistory.com/121를 참고하자.

class A
{
private B b;
public A(){
}
public void setB(B b){
this.b = b;
}}

has a관계가 가장 많이 사용된다.
왜냐하면 보통 인터페이스를 이용해서 구현체를 사용하기 때문이다. 아직 구현체가 없어도 꽃으면되기때문에 영향이 없고 구현체가 달라져도 영향이 없어서 편하다.
누군가가 객체를 생성해야하는데 생성자에 꽃으면 이것을 constructor injection이라고 한다. setter를 사용하면 setter injection인터페이스 기반하고 보통 객체꼽는 방법을 한다.
소스코드를 소스로 두지않고 설정으로 두는 경우가 많다. xml지시서 작성 이걸 도와주는게 스프링이다.
스프링은 지시서를 가지고 IOC컨테이너(BEAN 컨테이너)에 담아준다. 이걸 DI하는 해줒는 작업이 컨테이너에서도 결합도 해준다.


그런데 이제 이 지시를 어노테이션으로 작성한다.(배운것)

@Controller를 하면 ioc에 담아주고 injection해주는것이 @Autowired이다.

23. Mapper 객체를 이용해서 공지목록 출력하기

NoitceController로 와서 사용한다.

customer의 NoitceController를 작성해보자.

IOC컨테이너에 NoticeService 가 담겨잇다는 것을 전제로한다. 구현체는 NoticeServiceImp를 사용할 것인데 얘를 컨테이너에 담기위해 어노테이션을 달아주자.
명백히 역할을 구분하기 위해 @Conponent보다는 @Service사용하기

@Service
public class NoticeServiceImp implements NoticeService {

@Autowired
private NoticeDao noticeDao;

@Override
public List<Notice> getList() {
    List<Notice> list = noticeDao.getList();

    return list;
}

@Override
public Notice get(int id) {

    Notice notice = noticeDao.get(id);
    return null;
}
}

이녀석도 NoticeDao를 가져와야한다. 그래서 구현해야하는데 @Mapper를 하면 마이바티스가 알아서 구현해줘서 알아서 IOC컨테이너에 담아주는 역할까지 해준다.
근데 문제가 잇다. Notice필드를 구현안함. 필드 구현해주자.
컬럼데이터를 담아주자.


일단 하나씩 데이터를 추가 해주자. 테이블창에서 컬럼명을 드래그하면 sql작성창에 알아서 다 추가해준다. 이걸이용해서 쉽게 Notice작성하자

package com.newlecture.web.entity;

import java.util.Date;

public class Notice {
    private int id;
    private String title;
    private Date regdate;
    private String content;
    private int hit;
    private boolean pub;
    private int memberId;

    public Notice() {

    }

    public Notice(int id, String title, Date regdate, String content, int hit, boolean pub,
            int memberId) {
        this.id = id;
        this.title = title;
        this.regdate = regdate;
        this.content = content;
        this.hit = hit;
        this.pub = pub;
        this.memberId = memberId;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    public Date getRegdate() {
        return regdate;
    }

    public void setRegdate(Date regdate) {
        this.regdate = regdate;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getHit() {
        return hit;
    }

    public void setHit(int hit) {
        this.hit = hit;
    }

    public boolean isPub() {
        return pub;
    }

    public void setPub(boolean pub) {
        this.pub = pub;
    }

    public int getMemberId() {
        return memberId;
    }

    public void setMemberId(int memberId) {
        this.memberId = memberId;
    }

    @Override
    public String toString() {
        return "Notice [id=" + id + ", title=" + title + "regdate=" + regdate
                + ", content=" + content + ", hit=" + hit + ", pub=" + pub + ", memberId=" + memberId + "]";
    }
}

getter setter 필드 등등
이것을 컨트롤러가 받아오니 뷰단에서는 반복문으로 보여주자.

<%@ taglib "prefix="c" uri="http://java.sun.com/jstl/core" %>반복을 사용해야하니 태그 라이브러리 추가

<c:forEach var="n" items="${list}">
<tr>
<td>${n.id}</td>
<td class="title indent text-align-left"><a href="detail">${n.title}</a></td>
<td>${n.memberId}</td>
<td>
${n.regdate}    
</td>
<td>${n.hit}</td>
</tr>
</c:forEach>    

그냥실행하면 문제가 생긴다. 서버타임존을 정해주지 않았기 때문임.
드라이버를 사용하거나 서버에 지정할 수있다. 개발자가 서버에 지정하는건 적당하지 않고 드라이버 연결존 애플리케이션을 사용해서 지정하는게 바람직하다.
spring.datasource.url=jdbc:mysql://localhost:3306/newlecture?serverTimezone=Asia/Seoul
실행이안되서 mybatis버전을 낮추엇더니 된다. 이유를 알수없다.

2023.01.22 후기

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 태그 잘못넣어서 오류가 발생했다.
쓸데없는 사소한 오타로 오류가 발생해서 고생을 했다. 하나씩 디버깅 해나가는 과정이 필요하다. 단순한 오타가 생기지않도록 잘 보자.

'기초단계 > SPRING' 카테고리의 다른 글

2023.01.25-1 Spring  (0) 2023.01.25
2023.01.24-1 Spring  (0) 2023.01.24
2023.01.21 Spring  (0) 2023.01.22
2023.01.19 Spring  (0) 2023.01.20
2023.01.18 Spring  (0) 2023.01.19

+ Recent posts