2022-03-22(화)

14.1 자바 스크립트 템플릿 엔진 도입 : Handlebars 템플릿 엔진 적용

Handlebars 자바스크립트 라이브러리 추가 (/src/main/resources/static)

14.1 자바스크립트 템플릿 엔진

javascript template engine 검색

MyBatis는 SQL template engine

https://colorlib.com/wp/top-templating-engines-for-javascript/

/Users/nana/git/bitcamp-study/mylist-boot/app/src/main/resources/static

https://handlebarsjs.com/installation/#npm-or-yarn-recommended

npm install handlebars

dist : distribution

<script src="../node_modules/handlebars/dist/handlebars.min.js"></script>

↑ 이 자바스크립트 파일에 Handlebars 라는 이름으로 객체를 정의해놓음

  // 템플릿 엔진 준비
  var template = Handlebars.compile("<p>{{name}} 님 반갑습니다!</p>");
  
  // 템플릿 엔진에 값이 들어있는 객체를 줘서 텍스트를 생성한다.
  var obj = new Object();
  obj.name = "홍길동";
  
  var str = template(obj);
  
  console.log(str);

sql 코드를 xml 파일에 분리시키는 거랑 똑같음

https://handlebarsjs.com/installation/#usage

script 태그로 감싼다
나중에 사용할 html 코드 일부를 별도로 분리하는 용도로 쓴다

<script>
<p>{{name}} 님 반갑습니다!</p>
</script>

script 태그 안에 자바스크립트 코드 있는 줄 알았는데 아니어서 에러 냄

script 태그 안에는 js 코드
기본은 type="text/javascript"

<script type="text/ohora">
<p>{{name}} 님 반갑습니다!</p>
</script>

type="text/ohora"
ohora 라고 쓰면 다른 개발자가 혼동할 수 있음
의미있게 이름을 써야 함

<script type="text/x-handlebars-template">
<p>{{name}} 님 반갑습니다!</p>
</script>

type="text/x-handlebars-template"
텍스트는 텍스트인데 자바스크립트는 아니므로 무시해버린다
웹 브라우저는 화면에 출력하지 않고 무시해버린다

script 태그에 id를 부여한다
id="template1"

<script id="template1" type="text/x-handlebars-template">
<p>{{name}} 님 반갑습니다!</p>
</script>
  // 템플릿 엔진에서 사용할 HTML 조각을 가져오기
  var tamplate1 = document.querySelector("#template1");
  console.log(template1.innerHTML);

script 태그 안에 있는 html을 넘긴다
Handlebars.compile(template1.innerHTML)
이제 자바스크립트 안에 html은 없다

  // 템플릿 엔진에서 사용할 HTML 조각을 가져오기
  var tamplate1 = document.querySelector("#template1");

  // 템플릿 엔진 준비
  var template = Handlebars.compile(template1.innerHTML);

이름 변경
template → htmlGenerator

  // 템플릿 엔진에서 사용할 HTML 조각을 가져오기
  var tamplate1 = document.querySelector("#template1");
  
  // 템플릿 엔진 준비
  var htmlGenerator = Handlebars.compile(template1.innerHTML);
  
  // 템플릿 엔진에 값이 들어있는 객체를 줘서 텍스트를 생성한다.
  var obj = {
		  name: "임꺽정"
  };
  
  var str = htmlGenerator(obj);
  
  console.log(str);

실무에서는 변수를 따로 안 만들고 파라미터에 객체를 바로 넘긴다

  // 템플릿 엔진에 값이 들어있는 객체를 줘서 텍스트를 생성한다.
  var str = htmlGenerator({
      name: "임꺽정"
  });

템플릿 엔진의 파라미터 값으로 자바스크립트 객체를 넘기는데 그 객체 안에는 template 안에 들어갈 값을 담고 있어야 한다

  // 템플릿 엔진에서 사용할 HTML 조각을 가져오기
  var tamplate1 = document.querySelector("#template1");
  
  // 템플릿 엔진 준비
  var htmlGenerator = Handlebars.compile(template1.innerHTML);
  
  // 템플릿 엔진에 값이 들어있는 객체를 줘서 텍스트를 생성한다.
  var str = htmlGenerator({
      name: "임꺽정"
  });
  
  console.log(str);

id 이름 변경
template1 → tr-template

값이 들어갈 자리에 중괄호 2개 적기 {{ }}

<script id="tr-template" type="text/x-handlebars-template">
<tr>
  <td>{{no}}</td>
  <td><a href="view.html?no={{no}}">{{name}}</a></td>
  <td>{{email}}</td>
  <td>{{tels.[0].tel}}</td>
  <td>{{company}}</td>
</tr>
</script>

id="tr-template"

  fetch("/contact/list")
    .then(function(response) {
      return response.json();
    })
    .then(function(contacts) {
    	var tbodyContent = "";
      for (var contact of contacts) {
    	  // 값이 들어있는 객체를 가지고 템플릿 엔진을 실행하여 HTML을 생성한다.
    	  var str = htmlGenerator(contact);
        
    	  tbodyContent += str;
      }
      tbody.innerHTML = tbodyContent;
    });

굳이 반복문을 돌리면서 tr 태그를 만들지 말고

https://handlebarsjs.com/guide/builtin-helpers.html#each

this는 파라미터 객체를 가리킨다
배열에서 한 개를 꺼내서 실행

  fetch("/contact/list")
    .then(function(response) {
      return response.json();
    })
    .then(function(contacts) {
    	// 서버에서 받은 연락처 배열을 가지고 템플릿 엔진을 실행하여 tbody 콘텐트를 생성한다.
      tbody.innerHTML = htmlGenerator(contacts);
    });

자바스크립트 안에 html 코드가

카드는 div 태그
div 태그 안에 이미지

15.1 MyBatis 고급 기능 활용 : 테이블 조인과 동적 SQL 다루기

    select 
      c.contact_no,
      c.name,
      c.email,
      c.company,
      t.ct_no,
      t.tt_no,
      t.tel
    from
      ml_contact c
      left outer join ml_cont_tel t on c.contact_no=t.contact_no
    order by 
      c.name asc

15.1 MyBatis 고급 기능

90-MyList프로젝트2 / 43 페이지

① 테이블 조인과 자바 객체
(연락처) (전화번호)

연락처
new Contact()
같은 데이터의 경우 한 개의 객체만 생성

전화번호
new ContactTel()
데이터당 한 개의 객체 생성

new Contact() - new ContactTel() ← 포함 관계 (aggregation)
연락처가 전화번호를 포함한다

  <resultMap type="contact" id="contactMap">
  
    <id column="contact_no" property="no"/>
    <result column="name" property="name"/>
    <result column="email" property="email"/>
    <result column="company" property="company"/>
    
    <collection property="tels" ofType="contactTel">
      <id column="ct_no" property="no"/>
      <result column="tt_no" property="telTypeNo"/>
      <result column="tel" property="tel"/>      
    </collection>
    
  </resultMap>

MyBatis가 자동으로 만든다

Contact 객체는 하나만 만든다
ContactTel 객체는 3개를 만든다
리스트에 담아서 List<Contact> tel에 꽂는다

http://localhost:8080/contact/list

전화번호가 없는 사람은 어떻게 될까

반드시 outer join을 해야 유관순 데이터도 나온다

http://localhost:8080/contact/index.html

    select 
      c.contact_no,
      c.name,
      c.email,
      c.company,
      t.ct_no,
      t.tt_no,
      t.tel
    from 
      ml_contact  c
      left outer join ml_cont_tel t on c.contact_no=t.contact_no
    where 
      c.contact_no=#{no}

select를 여러 번 하는 것보다 join 하는 게 시간이 적게 걸린다

기존의 insert문은 데이터 1개만 추가할 수 있음

  <insert id="insertTel" parameterType="ContactTel">
    insert into ml_cont_tel(contact_no, tt_no, tel)
    values(#{contactNo}, #{telTypeNo}, #{tel});
  </insert>

한 번에 여러 개 추가할 수 있게 하자

ContactDao 인터페이스에 insertTels() 메서드 추가

 int insertTels(List<ContactTel> tels);

https://mybatis.org/mybatis-3/dynamic-sql.html

  <insert id="insertTels" parameterType="list">
    insert into ml_cont_tel(contact_no, tt_no, tel)
    values
    <foreach collection="list" item="tel" separator=",">
    (#{contactNo}, #{telTypeNo}, #{tel})
    </foreach>
  </insert>

ContactDao 인터페이스

int insertTels(@Param("contactNo") int contactNo, @Param("tels") List<ContactTel> tels);

@Param("contactNo") ← SQL Mapper에서 사용할 이름
@Param("tels") ← SQL Mapper에서 사용할 이름

  <insert id="insertTels">
    insert into ml_cont_tel(contact_no, tt_no, tel)
    values
    <foreach collection="tels" item="tel" separator=",">
    (#{contactNo}, #{telTypeNo}, #{tel})
    </foreach>
  </insert>

  <insert id="insertTels">
    insert into ml_cont_tel(contact_no, tt_no, tel)
    values
    <foreach collection="tels" item="contactTel" separator=",">
    (#{contactNo}, #{contactTel.telTypeNo}, #{contactTel.tel})
    </foreach>
  </insert>

<foreach collection="tels" item="contactTel" separator=",">
tels 에서 하나 꺼낸 걸 contactTel 이라고 하겠다

  @Override
  @Transactional // 다음 메서드는 트랜잭션 안에서 실행하도록 설정한다.
  public int add(Contact contact) {
    contactDao.insert(contact);
    contactDao.insertTels(contact.getNo(), contact.getTels());
    return 1;
  }

http://localhost:8080/contact/add?name=x4&[email protected]&company=bitcamp&tel=1_02-0000-0001&tel=2_02-0000-0002&tel=3_010-0000-0003

입력한 개수만큼 동적으로 SQL문 생성

  @Override
  @Transactional
  public int update(Contact contact) {
    int count = contactDao.update(contact);
    if (count > 0) {
      contactDao.deleteTelByContactNo(contact.getNo()); // 전화번호 변경 전에 기존 전화번호를 모두 삭제한다.
      contactDao.insertTels(contact.getNo(), contact.getTels());
    }
    return count;
  }

https://mybatis.org/mybatis-3/dynamic-sql.html

if문은 우리에게 맡기겠음..

세션을 사용해서 로그인
파일 업로드
facebook 로그인

좋은 웹페이지 즐겨찾기