newlife 프로젝트 2

2021. 11. 3. 17:47카테고리 없음

1. spring framework의 공식 문서를 찾았다..

아니 나는 홈페이지 들어가면 있는 guide가 문서인줄 알았는데 아니었고!!

어쩐지 정보가 너무 없고 섞여있더라... 진짜...guide였어... 여행 안내서처럼... 그냥 따라가는 거였다..

궁금한 거 찾으려고 검색하다가 doc은 따로 있는걸 알게 되었다..

나는 항상 공식문서를 파기 때문에! 신나게 공식문서를 보았다!!! 

공식이 항상 제일 친절하고 재밌다구~~~~~~~

나는 영어를 잘 못하지만 어차피 공식문서는 친절하기 때문에 보다보면 맨날 보는 단어만 나와서 이해하는데 큰 무리는 없다! 왜냐면 이해하기 힘든 건 어차피 한글로 봐도 어렵기 때문! 하하하

아무튼 지금 너무 기쁘다 ㅠㅠ 공식문서를 찾아서!!!

대애애박...그리고 pdf 파일로도 다운로드 가능하다...

https://docs.spring.io/spring-framework/docs/5.3.12/reference/pdf/index.pdf

무겁게 책 들고다닐 필요도 없고 정말 최고야..

https://docs.spring.io/spring-framework/docs/current/reference/html/

 

Spring Framework Documentation

Overview history, design philosophy, feedback, getting started. Core IoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP. Testing Mock Objects, TestContext Framework, Spring MVC Test, WebTestClient. Data Access Tran

docs.spring.io


2. 스프링 공식 문서에서 처음으로 살펴본 정보는 이것이다!

Annotation-based Container Configuration

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-annotation-config

 

Core Technologies

In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do

docs.spring.io

setter랑 constuctor DI중에 뭘 쓸까 하다가 일단 convention 따라서 setter를 썼는데 쓰고 나니깐


3. Dependencies

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependencies

 

Core Technologies

In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do

docs.spring.io

1.4. Dependencies

A typical enterprise application does not consist of a single object (or bean in the Spring parlance).

기업에서 만든 보통의 application은 하나의 객체로 이루어져있지 않다.(객체는 스프링 용어로는 빈이라고 함)

Even the simplest application has a few objects that work together to present what the end-user sees as a coherent application.

가장 간단한 애플리케이션 조차도, 최종사용자에게 일관성 있는 애플리케이션으로 보이도록, 함께 동작하는 몇 개의 객체를 갖고 있다. 

This next section explains how you go from defining a number of bean definitions that stand alone to a fully realized application where objects collaborate to achieve a goal.

다음 섹션은 독립적인 여러개의 빈을 정의하는 것에서부터, 목표를 실행하기 위해 객체들이 협력하는 완전한 애플리케이션을 구현하기까지에 대해 설명한다.

* stand alone = independent 

 

와.. 번역 몇 줄 하니까 지치네.. 안한다...

1.4.1. Dependency Injection

(Dependency는 수학적인 개념으로 이해하는게 확실히 쉬운것 같다. independent하지 않고 서로 의존적으로 작동하는 것...독립시행은 각각의 확률을 그저 곱하면 되었지만, 그게 아니고서는 의존관계를 따져서 조건부확률을 구하거나 했어야 했다.)

Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of (반대로) the bean itself controlling the instantiation or location of its dependencies on its own by using direct construction of classes or the Service Locator pattern.

Code is cleaner with the DI principle, and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies and does not know the location or class of the dependencies. As a result, your classes become easier to test, particularly 특히 when the dependencies are on interfaces or abstract base classes, which allow for stub or mock implementations to be used in unit tests.

DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.


3. Vo class에서 getter와 setter 쓰는 이유..

: 자바의 은닉성

https://ecsimsw.tistory.com/387

 

OOP / Getter랑 Setter를 왜 써야해??

자바의 접근 제한자 private : 같은 클래스 내에서만 접근 가능 default : 같은 패키지 내에서만 접근 가능 protected : 같은 패키지내 또는 자손 클래스일 경우 접근 가능 public : 제한 없음 캡슐화 접근

ecsimsw.tistory.com


4. 와.. 위 글을 읽고서 내가 이제까지 잘못 이해했구나 싶었다.

 

spring.io 에서 설명하는 spring framework는 한마디로 plumbing(배관 작업)이라고 했다.

배관 작업을 대신 해줘서, 개발자는 비즈니스 로직만 만들면 되도록 도와준다는 것..

아래는 공식 설명이다.

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.
A key element of Spring is infrastructural support at the application level: Spring focuses on the "plumbing" of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments.

 

java에서 VO, DAO, DTO, Controller, view 등을 만드는 것은 MVC 디자인 패턴 때문이고,

https://ko.wikipedia.org/wiki/%EB%AA%A8%EB%8D%B8-%EB%B7%B0-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC

 

모델-뷰-컨트롤러 - 위키백과, 우리 모두의 백과사전

모델, 뷰, 컨트롤러의 관계를 묘사하는 간단한 다이어그램. 웹 애플리케이션에서 일반적인 MVC 구성요소 다이어그램 모델-뷰-컨트롤러(model–view–controller, MVC)는 소프트웨어 공학에서 사용되는

ko.wikipedia.org

링크에서 말하는 바와 같이, Model, View, Controller를 분리하여, 비즈니스 로직(DB와의 데이터 주고받는 로직을 포함)과 사용자 인터페이스, 그리고 그 둘의 상호작용을 control하는 작업을 분리하기 위함이다.

즉.. Spring과는 전혀 상관이 없는데...

나는 annotatin DI랑 VO에 getter, setter 만드는 걸 관련짓고 있었다니...

분명 배웠던 건데 까먹은 것이다. 

그래도 이제 정확히 알게 되었으니 감사하자..

 

MVC 패턴을 자바에서 구현하기 위해, VO, DAO, DTO의 차이를 명확히 할 필요가 있다.

지금까지 그것조차 헷갈리는데 일단 시작한거라서.. 

일단 시작한 건 참 잘한 일이지만 중간 수정이 필요하다.

 

Difference between DTO, VO, POJO, JavaBeans?

https://newbedev.com/difference-between-dto-vo-pojo-javabeans

 

Programming tutorials | Newbedev

Checkout new tutorials and guides for programming languages Javascript, Python, Java, Golang, C++, PHP

newbedev.com

VO는 불변하는 클래스라서 Color.red 와 같이 변치않는 값을 getter 메서드로만 읽어오는 클래스였다.

내가 DB 테이블을 가져온 클래스를 VO라고 명명한 것은 잘못되었다는 거..

DTO로 싹다 고쳐야겠다.

하지만 이제 DataAccessObject는 필요없다.

왜냐면 data access를 MyBatis와 xml(스프링 프레임워크가 읽어서 bean 생성하고 configuration 처리, 그리고 dbcp처리)로 처리가능하기 때문... 와, 이제야 어느정도 이해한거네 ㅠㅠ

아무튼 나에겐 이제 거의 다 프레임워크를 이용하기 때문에 비즈니스 로직이 있는 Service와 ServiceImpl을 구현하면 된다!


5. JPA에 대한 글을 봤다.

JPA는 Java Persistance API로서 ORM(Object Relation Mapping) 구현체(예: Hibernate)와 java를 연결해준다. 상위 인터페이스의 집합인 것..

 

java에서는 java Object와 DB를 Mapping하는 JPA를 쓸 수 있는데, JPA와 Hibernate를 사용하면, sql, 즉 쿼리문을 작성하지 않아도 된다는 엄청난 장점이 있다. 그리고 중간에 ORM이나 DB를 바꿔도 쿼리문을 수정하느라 고생하지 않아도 된다는 것도 장점이란다.

단점은.. MyBatis보다 훨씬 어렵다는 것, (설정 공부 많이 필요..) 그리고 복잡한 select문을 쓸 경우에 사용이 어렵다는 것이라고 한다. (그래서 간단한 경우에는 JPA, 복잡한 쿼리 필요시에는 MyBatis, 이렇게 섞어쓰기도 한다고..)

 

이번 프로젝트는 구현할 시간이 얼마 없고, select를 많이 쓸것이기 때문에 일단은 JDBC로 MyBatis를 쓰기로 했다.

그리고 상용화할 것이기 때문에 나중에 유지보수를 하면서 JPA로 바꾸든지 해야겠다.

 

https://goodteacher.tistory.com/344?category=880880 

 

[Spring-Data-JPA]이제는 MyBatis를 보내주자.

이제는 MyBatis를 보내주자 Java를 이용해서 DB를 사용하기 위해서는 JDBC라이브러리를 이용하는게 필수다. 하지만 JDBC를 이용해서 직접 프로그래밍을 하는 경우는 대학 졸업 이후에는 아마 거의 없

goodteacher.tistory.com

https://gmlwjd9405.github.io/2018/12/25/difference-jdbc-jpa-mybatis.html

 

[JDBC] JDBC, JPA/Hibernate, Mybatis의 차이 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

https://gmlwjd9405.github.io/2019/08/04/what-is-jpa.html

 

[JPA] JPA란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io


6. 자바 naming conventions

Service 패키지에 메서드 이름을 짓는데 중구난방이어서 java의 naming convention을 찾아보았다.

그런데 매우 간단한 것밖에 없어서..

구글 클라우드 이름규칙naming convention을 봤는데 언어는 다르지만(python, Objective-C) 굉장히 참고하기 좋았다.

https://cloud.google.com/apis/design/naming_convention#method_names

 

이름 지정 규칙  |  Cloud API  |  Google Cloud

의견 보내기 이름 지정 규칙 다수의 API에서 오랜 시간이 지나더라도 일관적인 개발자 환경을 제공하려면 API에서 사용하는 이름이 모두 다음과 같아야 합니다. 단순해야 합니다. 직관적이어야

cloud.google.com

 

A service may, in its IDL specification, define one or more RPC methods that correspond to methods on collections and resources. The method names should follow the naming convention of VerbNoun in upper camel case, where the noun is typically the resource type.

나는 자바를 쓰니까, camel case지만 첫글자는 소문자로 작성해야 한다.

Verb Noun Method name Request message Response message
List Book ListBooks ListBooksRequest ListBooksResponse
Get Book GetBook GetBookRequest Book
Create Book CreateBook CreateBookRequest Book
Update Book UpdateBook UpdateBookRequest Book
Rename Book RenameBook RenameBookRequest RenameBookResponse
Delete Book DeleteBook DeleteBookRequest google.protobuf.Empty

The verb portion of the method name should use the imperative mood(명령형-앞에 주어 쓰지말라는 얘기), which is for orders or commands rather than the indicative mood which is for questions.

For standard methods, the noun portion of the method name must be singular for all methods except List, and must be plural for List. For custom methods, the noun may be singular or plural as appropriate. Batch methods must use the plural noun.

명사 부분에선 단수가 기본이지만, List를 요구하는 List method에서는 

 

This is easily confused when the verb is asking a question about a sub-resource in the API, which is often expressed in the indicative mood. For example, ordering the API to create a book is clearly CreateBook (in the imperative mood), but asking the API about the state of the book's publisher might use the indicative mood, such as IsBookPublisherApproved or NeedsPublisherApproval. To remain in the imperative mood in situations like this, rely on commands such as "check" (CheckBookPublisherApproved) and "validate" (ValidateBookPublisher).

요약: 무언가의 상태를 물을 때에도 명령형을 지키기 위해 is 말고 check나 validate를 써라.

Method names should not include prepositions (e.g. "For", "With", "At", "To"). Generally, method names with prepositions indicate that a new method is being used where a field should instead be added to an existing method, or the method should use a distinct verb. 

전치사 쓰지 말기, 다른 단어를 찾아서 최대한 전치사 배제

For example, if a CreateBook message already exists and you are considering adding CreateBookFromDictation, consider a TranscribeBook method instead.


7. Controller를 무슨 기준으로 나눌지 고민하다가 아래 글을 찾았다.

https://umbum.dev/1066

 

[Spring] MVC : Controller와 Service의 책임 나누기

martinfowler.com/bliki/PresentationDomainDataLayering.html 우선, 가장 크고 중요한 개념은 layer다. 일반적으로 많이 사용하는 layer 구분 Presentation layer Service layer Business layer Persistence laye..

umbum.dev

내가 내린 결론은, Conroller는 UI를 고려해서, view를 호출해야 하기 때문에, 내가 만들 웹사이트의 대메뉴에 맞게 분할한다는 것이다.

그래서 메인페이지의 HomeCotroller를 만들고, 대메뉴 하나당 Controller 하나를 만들기로 했다. 


8. eclipse에서 java 소스 보기(F3 누르면 보이던 자바 소스 안나올 때)

https://zzdd1558.tistory.com/150

 

Java Attach Source 설정하기.

이클립스를 하면서 System.out.println()이라던지 .. 다양한 메서드들이 어떻게 코딩되어있는지 궁금한 경우가 있다. 해당 메서드 위에서 F3을 누르거나 Ctrl + 왼쪽버튼으로 클릭했을때 코드가 나오지

zzdd1558.tistory.com

external location -> Path에 있는 Extenal file -> jdk/src.zip


9. MySQL Workbench에서 표(result grid-에디터 형식)로 데이터 입력insert할 때!!!

함수를 써도 무조건 string이 된다.

이 때의 해결책

Note
MySQL Workbench handles quoting and escaping for strings entered into the result grid, so adding quotes and proper escaping here is optional. 
탈출 문자(\; 한글자판에서 \; backslash) 입력 가능~~

 

Note
It is possible to enter a function, or other expression, into a field. Use the prefix \func to prevent MySQL Workbench from escaping quotation marks. For example, for the expression md5('fred'), MySQL Workbench normally would generate the code md5(\'fred\'). To prevent this, enter the expression as \func md5('fred') to ensure that the quoting is not escaped.
표에서 뭘 입력하면 string되니깐.. \func 를 압에 접두사로 붙여라~

 

https://dev.mysql.com/doc/workbench/en/wb-develop-sql-editor-results.html

 

MySQL :: MySQL Workbench Manual :: 8.1.4 Result Grid

The results area of the screen shows the results from executed statements. If the script contains multiple statements, a result subtab will be generated for each statemented that returned results. The following figure shows a single subtab and highlights t

dev.mysql.com


10. 바보같다...

자꾸 No qualifying bean of type 'xxx.BoardMapper' available 에러가 떠서, 있는데 뭐가 문제야 싶고...

(해결책은 12번에서!)

MyBatis 3 공식 docs에는 설명도 없고.. 분명 spring이 아니라 MyBatis 측에서 연동을 담당한다고 했는데 왜 문서에 없지 ...

했었다...

그러다 찾은 것이다..

http://mybatis.org/spring/factorybean.html

 

mybatis-spring –

SqlSessionFactoryBean In base MyBatis, the SqlSessionFactory is built using SqlSessionFactoryBuilder. In MyBatis-Spring, SqlSessionFactoryBean is used instead. Setup To create the factory bean, put the following in the Spring XML configuration file: Note t

mybatis.org

MyBatis-Spring 공식 문서를.....

정말 답답하고 바보같다... 

 

이제 이 문서와 함께라면 ㅠㅠ 두려울 것이 없다구

그리고 드디어 찾던 부분이 나왔다.

Injecting Mappers
Rather than code data access objects (DAOs) manually using SqlSessionDaoSupport or SqlSessionTemplate, Mybatis-Spring can create a thread safe mapper that you can inject directly into other beans:

SqlSessionDaoSupport이나 SqlSessionTemplate를 사용해서 DAO class랑 DAOImpl class 만들고 직접 연결을 하는 것보다, Mapper 클래스로 injecting 하는 것이 훨씬 좋아~~

 

Notice that there are no SqlSession or MyBatis references in this code. Nor is there any need to create, open or close the session, MyBatis-Spring will take care of that.

session 관리( 만들고, 열고 닫고..)는 이제 MyBatis-Spring이 알아서 한다구~~

 

http://mybatis.org/spring/mappers.html

 

mybatis-spring –

Injecting Mappers Rather than code data access objects (DAOs) manually using SqlSessionDaoSupport or SqlSessionTemplate, Mybatis-Spring can create a thread safe mapper that you can inject directly into other beans: Once injected, the mapper is ready to be

mybatis.org

 

ServiceImpl에 Mapper를 injecting 하는 것은 xml bean 설정 말고 @Autowired 어노테이션으로 하는 것이 좋다고 생각한다.

훨씬 간편하니까.. 예시는 아래와 같다.

package com.myproject.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.nlchurch.dto.BoardDTO;
import com.nlchurch.mapper.BoardMapper;
import com.nlchurch.service.BoardService;

@Service("BoardService")
public class BoardServiceImpl implements BoardService {

	@Autowired
	BoardMapper boardMapper;
    
    @Override
    methods....
    .
    .
    .    
}

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-classpath-scanning

 

Core Technologies

In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do

docs.spring.io


11. MyBatic-Spring docs에 따르면..   http://mybatis.org/spring/mappers.html

 

Registering a mapper 에는 두 가지 방법이 있다. 

1. xml file에 등록해서 org.mybatis.spring.mapper.MapperFactoryBean 이 생성하도록 하는 것

2. java Configuration Class 작성하기

결국 둘 다 직접 Mapper Interface를 하나하나 등록해야한다.

 

Scanning for mappers

하나하나 말고 Mapper Interface들을 한꺼번에 scan해서 자동으로 읽어들이게 하는 방법!

괜히 Mapper 등록했던 기억이 없는게 아니다..

안했었거든.. 

MyBatis는 우리에게 다음과 같이 말해준다.

There is no need to register all your mappers one by one. Instead, you can let MyBatis-Spring scan your classpath for them. 하나하나 등록할 필요!가 없다고!!

scanning에는 3가지 방법이 있다. (택 1)

1. Using the <mybatis-spring:scan> element.
가장 일반적.. 그리고 뭔가 제공해주는거랑 설명이 제일 많은걸로 봐선 MyBatis는 이걸 제일 추천하는게 아닐까..?
그런데 놀랍게도 공식 문서에 mybatis:scan으로 잘못 나와있다..
mybatis-spring:scan으로 쓰지않으면 bound안된다고 오류난다.

2. Using the annotation @MapperScan
spring에서 xml <bean></bean> 설정 대신에 @Configuration이나 @Bean 으로 Config class 즐겨쓰는 사람을 위한 annotion. 해당 Config 클래스에 사용.

(https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-java)

3. Using a classic Spring xml file and registering the MapperScannerConfigurer
clssic한 xml  <bean> 설정
can be included in a classic xml application context as a normal bean

 

결론: datasource-context.xml 맨 아래쪽에 아래 한 줄을 집어넣으면 된다.

<mybatis-spring:scan base-package="com.myproject.mapper" />

그럼 not available 어쩌구 에러도 사라진다~~~ 왜냐면 이제 mapper인터페이스 찾아서~~ binding해서~~~ Mapper 객체 만들어서~~~ 연결해주니깐~~~~~~


12. 이렇게 console에 떠서 찾아봤다.

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. 

The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

 

https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-usagenotes-spring-config.html

 

MySQL :: MySQL Connector/J 8.0 Developer Guide :: 14 Using Connector/J with Spring

Chapter 14 Using Connector/J with Spring The Spring Framework is a Java-based application framework designed for assisting in application design by providing a way to configure components. The technique used by Spring is a well known design pattern calle

dev.mysql.com

com.mysql.cj.jdbc.Driver 로 바꿔주기..


13.  indext.jsp의 navigation bar, 즉 대메뉴 작업에 들어간다..

font-family 를 잘 모르고 썼었는데 멋진 글을 찾았다!

https://www.codingfactory.net/10551

 

CSS / font-family / 글꼴 정하는 속성

개요 font-family는 글꼴을 설정하는 속성입니다. 기본값 : 웹브라우저의 기본 글꼴 상속 : Yes 애니메이션 : No 버전 : CSS Level 1 문법 font-family: font | initial | inherit font : family-name 또는 generic-family initial

www.codingfactory.net

 

이 글이 더 멋지다. 그리고 더 자세함

https://webclub.tistory.com/261

 

그리고 font-face 자동 생성기: 겁나 유용..

https://transfonter.org/


14. video 게시판을 꾸밀 템플릿을 찾았다. 
글 insert할 때 youtube url을 반드시 입력할것이기에..

아예 list view에서 비디오 썸네일이 보이는게 좋다..

 

youtube url에서 thumbnail image얻어오기

https://hello-bryan.tistory.com/183

글 insert시에 링크 넣을때 썸네일 이미지도 받아서 db에 저장하도록(썸네일 용량이 작아서 하나에 50kb정도임 다행) 하고 사이즈 정보도 넣어야겠다.. 그래서 list 불러올때 썸네일 이미지도 받아서 띄우게 해야지....