반응형

 

var val = 10; // 전역 변수 num을 선언

function changeValue() {
    console.log(val); // 10
    val = 20; // 전역 변수 함수 내부에서 변경
}

changeValue();  
console.log(val); // 20
var val = 10; // 전역 변수 num을 선언

function changeValue() {
    console.log(val); // undefined
    var val = 20; // 지역 변수 값 초기화
}

changeValue();  
console.log(val); // 10
var의 호이스팅

let, const는 아니지만 var는 변수 선언 시 undefined로 정의함

 

*changeValue 함수 내에서 일어나는 일* == 호이스팅

var val; // undefined

console.log(log); // undefined

val = 20;

 

  1. 전역 스코프에서 var val = 10;가 선언되고 초기화됩니다. val 변수는 10의 값을 가집니다.
  2. changeValue(); 함수가 호출됩니다.
  3. changeValue 함수 내에서 console.log(val)이 실행될 때 val 변수가 호이스팅되고 함수 스코프 내에서 선언되었습니다. 그러나 아직 초기화되지 않았으므로 undefined가 출력됩니다.
  4. 마지막으로 함수 내에서 var val = 20;이 실행되고, val 변수는 20으로 초기화됩니다.

 

var val = 10; // 전역 변수 num을 선언

function changeValue() {
	var val = 20; // 지역변수 초기화
    console.log(val); // 20
    
}

changeValue();  
console.log(val); // 10
반응형
반응형

C언어

1. 열혈강의 C

2. 독하게 시작하는 C 프로그래밍

 

알고리즘

1. 뇌를 자극하는 알고리즘

2. 열혈강의 자료구조

 

프로그래머적으로 사고하는 것 / 개발적으로 사고하는 것

1. 대체 뭐가 문제야 (제럴드 와인버그 / 도널 고즈)

2. 조엘 온 소프트웨어

3. 읽기 좋은 코드가 좋은 코드다

4. 코드 컴플리트

5. 실용주의 프로그래머

6. 생각하는 프로그래밍

7. 해커와 화가

 

 

 

하나하나 씹어먹짜

반응형
반응형

데이터 바인딩

 

실시간 자동 렌더링 > 웹앱 구현 가능

{{데이터바인딩}}

 

😲HTML 속성도 데이터바인딩 가능

:속성 = "데이터이름"

    <p :style="스타일">{{price1}} 만원</p>

 

 

App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <div>
    <h4>house 원룸</h4>
    <p :style="스타일">{{price1}} 만원</p>
  </div>
  <div>
    <h4>houseName2 원룸</h4>
    <p>{{price2}} 만원</p>
  </div>
</template>
<script>
    //document.getElementById().innerHTML = ?? //바닐라자바스크립트
    export default {
      name: 'App',
      data(){
        return {
          price1 : 60,
          price2 : 70,
          스타일 : 'color : red',
        }
      },
      components: {
      }
    }
</script>

v-for 반복문 사용

 

<태그 v-for="작명 in 몇 회" :key="작명">

* :key="" - 반복문 돌린 요소를 컴퓨터가 구분하기 위해서 필수적으로 써야함

 

* 변수 작명 2개까지 가능

- menu는 array내의 데이터

- i는 1씩 증가하는 정수(key 값으로 씀)

  <div v-for="(product, i) in products" :key="i">
    <h4> {{products[i]}} 원룸 </h4>
    <p>48 만원</p>
  </div>
  
<script>
    export default {
      name: 'App',
      data(){
        return {
          products : ['강서구', '마곡동', '송정역'],
        }
      },
      components: {
      }
    }
</script>

이벤트 핸들러 사용하기

 

버튼 클릭 시 신고 수 증가

<button v-on:click="cnt++">허위매물신고</button> <span>신고 수 : {{cnt}}</span>
<button @click="cnt++">허위매물신고</button> <span>신고 수 : {{cnt}}</span>

 

😲😲😲놀랍도록 간단...

- cnt++ 대신 cnt += 1도 가능
- 다양한 이벤트 존재 : @mouseover, @drag, @input 등
 
 
script 단에서 function 활용 : methods : { }
- 괄호없이 함수명만 사용
<button v-on:click="increase">허위매물신고</button> <span>신고 수 : {{cnt}}</span>
- data() 뒤에 생성
- 함수 안에서 데이터 쓸 때 this.데이터명 
<script>
export default {
  name: 'App',
  data(){
    return {
      메뉴들 : ['Home', 'Shop', 'About'],
      products : ['강서구', '마곡동', '송정역'],
      cnt : 0,
    }
  },
  methods : {
    increase() {
      this.cnt++;
    },
  },
  components: {
  }
}
</script>

이미지 가져오기

 

- src에 있는거 가져올 때 경로는 ./ 부터 (웹팩 문법)

    <img src="./assets/room0.jpg">

 

모달창 만들기

 

*vue-router 설치하면 다른 페이지도 만드는 것 가능

<button v-on:click="modal=true">열려라</button>
<button v-on:click="modal=false">닫혀라</button>

<div v-if="modal === true" class="black-bg">
  <div class="white-bg">
    <h4>상세 페이지</h4>
    <p>상세 페이지 내용</p>
    <button v-on:click="modal = false">닫혀라</button>
  </div>
</div>

state

  data(){
    return {
      modal : false,
    }
  },

😲간단..!

 


Vue.js에 Font 바꾸기

 

기본폰트 못참는다..!

@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap');

body {
  font-family: 'Noto Sans KR', sans-serif;
}

 


export/import로  js 파일에서 만든 변수나 자료를 다른 js 파일에서 사용하기

 

post.js

var apple = 10;
export default apple

- export default는 파일 맨마지막 한번만 사용 가능

 

 

App.vue

import apple from './post.js'

- apple 대신 다른 단어 사용 가능

- .js 생략 가능

 


post.js

var apple = 10;
var apple2 = 100;

export {apple, apple2}

- 변수 2개나 함수도 사용 가능 

 

App.vue

import {apple, apple2} from './assets/post.js';
apple
apple2

 

배열의 Object 값 반복문으로 불러오기

  <div v-for="(room, i) in rooms" :key="i">
    <img :src="room.image" class="room-img" v-on:click="modal=true">
    <h4>{{room.title}}</h4>
    <p>{{room.price}}원</p>
  </div>

기이이이이초 강의기라 그렇긴 하지만, 너무 쉬워서 충격 그 잡채.......

Vue.js 진짜 좋은 프레임워크구나..,,

강사님이 배열을 바인딩해보라고 했는데 Vue.js 자체를 쓴지 10분도 안된 상태였는데 구글링없이 바로 쉽게 구현했다..!

 

다음엔 스프링에 vue.js 연결하고 DB붙여봐야지. 컴포넌트 사용 관련해서도 공부해볼 것. 

 

 

 

[코딩애플]  Vue 로 만드는 직방 / 인스타그램 웹앱 영상을 기반으로 정리한 내용입니다.

 

반응형

'Front-End' 카테고리의 다른 글

[Vue.js] npm 환경 세팅 정리  (0) 2022.09.10
반응형

며칠 간 자바, 스프링, 네트워크 관련해서 이론 위주로 공부하다 보니 코드가 치고 싶어져서 새로운거 배우기!💃

 

 

1. Vue 개발 환경을 도와주는 개발 환경 설치

npm install -g @vue/cli

 

2. VSCode 익스텐션 설치

 

- Vetur

- html css support

- Vue 3 Snippets

 

 

3. Vue 프로젝트 생성

 

vue create vue-form

vue3 선택

 

*Windows 환경에서 에러가 난다면?

get-executionpolicy // restricted 

set-executionpolicy remotesigned // Y 선택

get-executionpolicy // remotesigned

 

4. npm run serve

 

초기화면..! 새로운 구조라 신기하다.

 

/* 설명 */

1. Nodejs 설치하면 npm 쓸 수 있음

2. npm은 각종 웹개발 라이브러리 설치 도우미

3. npm으로 @vue/cli 설치함 (vue 프로젝트 빠르게 생성해주는 라이브러리) > vue create 프로젝트명

4. App.vue가 메인페이지임

5. App.vue > index.html (main.js에서 html로 컴파일해주고 있음)

6. 구조

- node_modules : 프로젝트에 쓰는 라이브러리들

-  src : 소스코드 다 담는 곳

- public : html 파일, 기타 파일 보관

- package.json : 라이브러리 버전, 프로젝트 설정 기록

 

 


 그래도 저번에 줌 클론코딩으로 Nodejs 써봐서 vue 말고는 환경이 익숙하다. 다음엔 Spring Framework에 vue.js를 써봐야지

 

 

 

ref. [코딩애플] vue 1강 : Vue 3버전 설치랑 셋팅

반응형
반응형

 사실은 스프링 입문은 8월에 완강을 하였다. 유료 강의를 구매한게 아마 수박씨 닷컴이 마지막이었는데 커리큘럼을 다 따라가면 스프링은 60만원대, JPA까지하면 일백만원이 훌쩍 넘어가는 금액이 나에게는 큰 지출이어서 꽤나 오랜 시간동안 고민을 해왔다. 그리고 나와 같은 고민을 하는 분들도 더러 많을 것 같다.

 

 사람마다 다르겠지만 일단 무료 강의를 들으면 유료 강의를 살지 말지 바로 결정이 지어질거라고 생각된다. 개인 프로젝트를 하며 얻는 것도 귀중하지만 김영한님 강의를 통하여 쉽게 얻을 수 없는 것들을 많이 얻게 되고 또 그 지식의 단단한 힘과 신뢰성을 보고 믿고 따라 가게 된다. 이제 생각해보면 조금 더 빨리 수강할걸 이라는 짧은 후회가 있지만, 지금이라도 시작해서 다행이다. 내 개발 커리어에 유의미한 배움이 되길 원하며 하루를 더 나은 내일, 일주일로 만들어 나갈 것이다!

 

 추석 할인 기간까지 꼬박 기다려 (사실 기본 원리 이후 지금까지 너무 정신이 없어서 강의를 구매해도 수강하지 못했을 것 같다.)   무려 25%나 할인받아 강의를 구매했다. 스프링 커리큘럼은 모두 구매하고 JPA 강의는 기본편만 일단 구매했다. (다 들으면 설날할인으로 구매 예정)

 

객체지향을 더 객체지향답게 개발하는 개발자가 되도록.

수강하며 열심히 기록해나가야지

 

반응형
반응형

JDBC, JDBCTemplate 강의에서의 큰 수확은 스프링의 장점인 개방 폐쇄의 원칙, 다형성을 이해할 수 있다는 점이었다. 스프링 DB접근 기술 쪽은 이 부분을 중점적으로 포스팅

 

강의 비지니스 시나리오는 DB가 정해져 있지 않아 Memory로 repository를 구성했었다.

이를 H2 데이터베이스를 연결하고 JDBC로 구현체를 변경이 필요했다.

 

🎈🎈 개방-폐쇄 원칙(OCP, Open-Closed Principle) :확장에는 열려있고, 수정/변경에는 닫혀있다. 

DataSource dataSource;

@Autowired
public SpringConfig(DataSource dataSource) {
    this.dataSource = dataSource;
}
        
@Bean
    public MemberRepository memberRepository(){
        //new 키워드 뒤에 인터페이스 구현 클래스
        //return new MemoryMemberRepository();
        return new JdbcMemberRepostiory(dataSource);
    }

스프링의 DI (Dependencies Injection)을 사용하면 기존 코드를 전혀 손대지 않고, 설정(어셈블리 라인)만으로 구현 클래스(구현체)를 변경할 수 있다.

 

>> 객체지향의 다형성을 활용

Service 단에서 어떤 Repository를 의존할지 기존 코드를 다 수정해야하지만 DI를 사용하면 SpringConfig만 손봐주면 된다는 말

 


이후에 JDBCTemplate , JPA, 스프링 데이터 JPA도 동일하게 구현체를 쉽게 변경할 수 있었다.

🎈🎈JDBCTemplate 

DataSource dataSource;

@Autowired
public SpringConfig(DataSource dataSource) {
    this.dataSource = dataSource;
}
        
@Bean
    public MemberRepository memberRepository(){
        //new 키워드 뒤에 인터페이스 구현 클래스
        //return new MemoryMemberRepository();
        //return new JdbcMemberRepostiory(dataSource);
        return new JdbcTemplateMemberRepository(dataSource);
    }

 

🎈🎈JPA

//@PersistenceContext
private EntityManager em;

@Autowired
public SpringConfig(EntityManager em) {
    this.em = em;
}

@Bean
public MemberRepository memberRepository(){
    //new 키워드 뒤에 인터페이스 구현 클래스
    //return new MemoryMemberRepository();
    //return new JdbcMemberRepostiory(dataSource);
    //return new JdbcTemplateMemberRepository(dataSource);
    return new JpaMemberRepository(em);
}

 

+) 엔티티 매핑 필요

@Entity
public class Member {
	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	...
 }

*참고) build.gradle 수정, resources/application.properties 수정도 필요 

 

🎈🎈스프링 데이터 JPA

: JpaRepository를 상속하는 인터페이스를 만들면 자동으로 구현체를 등록해준다. (Repository bean등록 안해도 됨)

@Configuration
public class SpringConfig {
 	private final MemberRepository memberRepository;

	public SpringConfig(MemberRepository memberRepository) {
	 	this.memberRepository = memberRepository;
	 }
	 @Bean
	 public MemberService memberService() {
	 	return new MemberService(memberRepository);
 }
}

 

출처 : 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

반응형
반응형
javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save()

오류 : JPA를 사용할 때 PK인 컬럼을 도메인에 설정해주어야 함

 

해결 : @GeneratedValue 자동생성

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

*식별자를 직접 할당하는 방법도 있음

반응형
반응형

🎈 회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용 : 의존관계

 

👩회원 컨트롤러

: 스프링 실행 시 스프링 컨테이너라는 통이 생기는데 @Controller 있으면 회원 컨트롤러 객체 생성하여 컨테이너에 넣어두고 스프링이 관리함. (스프링 Bean 생성)

@Controller
public class MemberController {

    private MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

💥다음과 같이 객체 여러번 생성할 이유가 없다.

 

private final MemberService memberService = new MemberService();

 

🎈🎈DI (Dependency Injection), 의존성 주입 : 객체 의존관계를 외부에서 넣어주는 것

 생성자에 @Autowired 가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다.

(이전 테스트에서는 개발자가 직접 주입했고, 여기서는 @Autowired에 의해 스프링이 주입해준다.)

 

>> 회원 컨트롤러가 스프링 컨테이너에 생성 > 생성자를 호출 > 생성자에 @Autowired라고 되어있으면 스프링이 멤버 서비스를 스프링 컨테이너에 있는 멤버서비스에 연결시켜줌

 

 


🎈스프링 빈을 등록하는 2가지 방법

1. 컴포넌트 스캔(아래의 어노테이션은 컴포넌트가 근본)과 자동 의존관계 설정

실행 시, @Component어노테이션이 있으면 스프링 빈으로 자동 등록된다

  • @Controller : 외부 요청을 받음
  • @Service : 비지니스 로직을 만듦
  • @Repository : 데이터를 저장
  • @Autowired : 연관관계 설정

참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.

ex) OrderService가 memberRepository를 @Autowired 했을 경우, memberService와 같은 인스턴스를 넣어줌. 메모리 절약!

 

 

2. 자바 코드로 직접 스프링 빈 등록하기

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        //new 키워드 뒤에 인터페이스 구현 클래스
        return new MemoryMemberRepository();
    }
}

@Bean로 컨테이너에 스프링 빈 등록을 하고 @Autowired 대신 리턴 값의 매개변수를 연결

참고: XML로 설정하는 방식도 있지만 최근에는 잘 사용하지 않으므로 생략한다.

참고: DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다. 의존관계가 실행중에동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.

//필드 주입 - 주의! 스프링 실행할 때만 넣어주고 중간에 바꿀 수가 없다..! 권장X
@Autowired
private MemberService memberService;

//생성자 주입 - 조립 시점에 생성자로 조립해두고 변경될 수 없도록 막아버리기
private final MemberService memberService;

@Autowired
public MemberController(MemberService memberService) {
    this.memberService = memberService;
}

//setter 주입 - public하게 노출되어 있어야 함. 한번 세팅이 되면 바꿀 일이 없으니 위험.
// memeberService.setMemberService(); 코드 적어야함 
private MemberService memberService;
    
@Autowired
public void setMemberService(MemberService memberService) {
    this.memberService = memberService;
}

참고: 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. 그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.

주의: @Autowired 를 통한 DI는 helloController, memberService등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.

*스프링 컨테이너, DI 관련된 자세한 내용은 스프링 핵심 원리 강의에서 설명한다.

 

 


면접에서 어노테이션에 대한 질문을 받은 적이 있다. 한번도 타인에게 설명해본 적이 없어서 당황하며 Controller, Service에 어노테이션을 붙여 경로를 찾게 도와준다고 답변했었다. Spring Bean를 덧붙여서 말하긴 했는데 얼추 맞긴 했다..

 

내가 아는건 딱 여기까지고(@Autowired를 활용해서 주입시켜주는 것까지?) 강의를 들으며 컴포넌트 스캔 원리를 알게 되어 띵~했다. 스프링을 배울 때 스프링 빈이라는 개념이 추상적이고 와닿지가 않았다. 왜냐하면 구글링할 때는 어노테이션 쓰는 방법과 직접 Config를 작성하는 방법 둘 다 있으니 제대로 이해를 못하고 기능 구현에 급급했던 것 같다. (분명,,스프링 부트의 장점이 직접 하나하나 설정안해도 된다는거였는데,,뭐지? 혼란에 빠졌었다.) 후후 스프링을 실행시킬 때 컨테이너가 있는데 객체 생성할 때 컴포넌트 스캔으로 컨트롤러를 찾는구나! 

강의 들으면서 생성자 주입으로 실습을 하다보니 내가 이때까지 한건 뭐지..?라는 생각이 들었는데 DI에 대한 종류를 설명해주셔서 그저 감사했다. 나는 계속 필드 주입을 사용했구나(제일 안좋은듯;;) 이제부터 필드에 접근할 수 없고 조립 시 유용한 생성자 주입을 써야겠다. 

 

 

아래는 작년에 DB 관련 히카리CP 설정을 할 때 쓴 Config 파일,,이땐 @Bean이 무슨 용도인지 잘몰랐다,,,

 

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
@PropertySource("classpath:/application.properties") //application.properties를 사용할 수 있도록 설정 파일의 위치를 정해 준다.
public class DatabaseConfiguration {
	
	@Autowired
	private ApplicationContext applicationContext;		//bean 객체를 생성하고 관리하는 기능(beanfactory를 상속받음.)

    //application.properties에 설정했던 데이터베이스 관련 정보를 사용하도록 지정한다.
	//@ConfigurationProperties 어노테이션에 prefix가 spring.datasource.hikari로 설정되었기 때문에 
	//spring.datasource.hikari로 시작하는 설정을 이용해서 히카리CP의 설정파일을 만든다.
    @Bean
    @ConfigurationProperties(prefix="spring.datasource.hikari")		//@ConfigurationProperties : *.properties, *.yml 파일에 있는 property를 자바 클래스에 값을 가져와서 사용 할 수 있게 해주는 어노테이션
    public HikariConfig hikariConfig() {
        return new HikariConfig();
    }

    //앞에서 만든 히카리CP의 설정파일을 이용해서 데이터베이스와 연결하는 데이터 소스를 생성한다. 
    //여기서는 데이터 소스가 정상적으로 생성되었는지 확인하기 위해서 데이터 소스를 출력했다.
    @Bean
    public DataSource dataSource() throws Exception {
        DataSource dataSource = new HikariDataSource(hikariConfig());
        System.out.println(dataSource.toString());
        return dataSource;
    }
    
    @Bean
    @ConfigurationProperties(prefix = "mybatis.configuration")  //@ConfigurationProperties을 통해서 application.properties에서 prefix가 mybatis.configuration인 설정을 가져온다.
    public org.apache.ibatis.session.Configuration mybatisConfig(){
        return new org.apache.ibatis.session.Configuration();   //가져온 마이바티스 설정을 자바 클래스로 만들어 반환한다.
    }
    
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {	//SqlSessionFactory : mybatis와 mysql 서버를 연동시켜줌, sqlsession 생성
    	//sqlsession : 세션을 한번 생성하면 매핑구문을 실행하거나 커밋 또는 롤백을 하기 위해 세션을 사용할수 있다. 더 이상 필요하지 않은 상태가 되면 세션을 닫는다.
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:/mapper/**/*.xml"));	//** : 하위폴더전체
        sqlSessionFactoryBean.setConfiguration(mybatisConfig());	//해당 설정을 sqlSessionFactory에 설정해준다.
        return sqlSessionFactoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {		//SqlSessionTemplate은 SqlSession을 구현하고 코드에서 SqlSession를 대체하는 역할을 한다.
        return new SqlSessionTemplate(sqlSessionFactory);
    }
    
}

한 강의마다 시간은 짧은데 반복해서 듣다보니 시간이 꽤 걸린다. 다 들었을 땐 레벨업되어 있기를!!

 

출처 : 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

반응형