일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 동시성
- 가비지 컬렉터
- MySQL
- CAS
- 동시성 문제
- iterator
- jpa
- iterable
- foreach
- db
- 자바
- Lock
- java
- MVCC
- text
- Atomic Type
- Locking Read
- Varchar
- 스프링
- Di
- 백엔드
- reflection
- 데이터 타입
- Synchronized
- gc
- 가비지 컬렉션
- Today
- Total
목록전체 글 (98)
과정을 즐기자
객체와 테이블 매핑 @Entity @Entity가 붙은 클래스는 JPA가 관리하는 것으로 엔티티라고 부른다. @Entity의 속성에는 name이 있다. name은 JPA에서 사용할 엔티티 이름을 지정한다. 설정하지 않으면 클래스 이름을 그대로 사용한다. JPA가 내부에서 동적으로 객체를 생성하기 때문에 기본 생성자가 필요하다. @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity public class Member{...} @Table @Table은 엔티티와 매핑할 테이블을 지정한다. @Table의 속성에는 name, catalog, schema, uniqueConstraints 등이 있다. name은 매핑할 테이블 이름을 지정하고 설정하지 않으면 엔티..
영속성 관리 JPA가 제공하는 기능은 크게 엔티티와 테이블을 매핑하는 설계하는 정적인 부분(객체와 관계형 데이터베이스를 매핑)과 매핑한 엔티티를 실제 사용하는 동적인 부분으로 나눌 수 있다.(영속성 컨텍스트) 이제부터 매핑한 엔티티를 실제 사용하는 동적인 부분에 대해 알아보자. 엔티티 매니저 팩토리와 엔티티 매니저 데이터베이스를 하나만 사용하는 애플리케이션은 일반적으로 EntityManagerFatory를 하나만 생성한다. EntityMangerFactory emf = Persistence.createEntityManagerFactory("jpabook");여기서 필요할 때마다 엔티티 매니저를 생성한다. EntityManager em = emf.createEntityManager();엔티티 매니저 팩토리..
SQL 중심적인 개발의 문제점 자바와 같은 객체지향언어를 사용한다면 추상화, 캡슐화, 정보은닉, 상속, 다형성을 활용하여 역할과 책임을 구분하여 개발을 한다. 관계형 데이터베이스를 사용한다면 SQL을 이용해서 DB에 저장, 수정, 삭제를 하게된다. 그렇다면 객체를 관계형 데이터베이스에 저장하려면 객체정보를 SQL로 변환하여 저장하면 된다. 하지만 객체와 관계형 데이터베이스에는 다음과 같이 크게 4가지 차이가 있다. 상속 : 관계형 데이터베이스에서 상속을 사용하려면 각각의 테이블에 JOIN SQL을 작성해야 한다. 연관관계 : 객체는 참조를 사용하여 연관관계를 가져왔는데 테이블은 외래키를 사용하여 가져와야한다. 데이터 타입 데이터 식별방법 객체 모델과 관계형 데이터베이스 모델은 지향하는 패러다임이 서로 다..

좋은 객체 지향 설계 먼저 좋은 객체 지향 설계의 5가지 원칙 SOLID에 대해 알아보자 SRP(single responsibility priciple) 단일 책임 원칙으로 한 클래스는 하나의 책임만 가져야 한다. OCP(open/closed principle) 개방-폐쇄 원칙으로 확장에는 열려 있으나 변경에는 닫혀있어야 한다. LSP(Liskov subsititution principle) 리스코프 치환 원칙으로 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야한다. ISP(interface segregation principle) 인터페이스 분리 원칙으로 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다. DIP(Dependence inversion principle) 의..
추상 클래스 추상 클래스는 변수를 가질 수 있다. 일반 메소드, 추상 메소드 둘 다 있을 수 있다. 자식 클래스에서 일반 메소드는 재정의 할 수도 있고 그냥 사용할 수도 있다. 하지만 추상 메소드는 반드시 재정의 해야한다. 단일 상속을 지원한다. 코드로 이러한 특징들을 확인해보자 public abstract class AbstractParent { public int number = 10; // 변수 선언 가능 public void hello() { System.out.println("hello"); // 일반 메소드 구현가능 } public abstract void hi(); // 추상 메소드 사용가능 }public class AbstractChild extends AbstractParent { @Ov..

Front Controller V3 1. 컨트롤러에 있는 HttpServletRequest, HttpServletResponse를 사용하지 않고 자바의 Map을 사용하여 요청 파라미터를 넘길 수 있는 구조를 만들어보자. request 객체를 model로 사용하던 구조를 별도의 다른 Model 객체를 만들어서 반환하는 구조로 바꾸자 2. /WEB-INF, /.jsp와 같이 뷰 이름이 중복되는 부분을 제거하자 1번은 MyView를 반환하던 구조에서 ModelView로 반환하는 구조로 바꿔 해결한다. 2번은 ViewResolver를 사용해 논리 뷰 이름을 이용하여 해결한다. 먼저 viewName과 model을 갖는 ModelView클래스를 만든다 private String viewName; private Ma..

프론트 컨트롤러는 입구를 하나로 만들어 공통적인 처리를 먼저해준다. 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받고 요청에 맞는 컨트롤러를 프론트 컨트롤러가 찾아서 호출한다. 스프링 웹 MVC의 핵심은 프론트 컨트롤러이고 DispatcherServlet으로 구현되어 있다. Front Controller V1 먼저 가장 간단한 구조로 확인해보자 프론트 컨트롤러는 서블릿을 사용하였고 ControllerV1 interface를 만들어 나머지 컨트롤러들은 이 인터페이스를 구현한다. 프론트 컨트롤러에서는 먼저 URL 매핑 정보에서 컨트롤러를 조회한다. @WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-controller/v1/*") ..

Call by Value Call by value는 값에 의한 호출이다. 다르게 표현하면 값만 전달한다고 할 수 있다. 따라서 call by value 방식으로 값을 전달받고 수정을 해도 원본 값은 바뀌지 않는다. 값을 전달받으면 스택에 메모리가 할당된다. 서로 같은 메모리가 아님! class CallByValue { @Test void test() { int a = 0; -- (1) int b = 0; -- (1) assertEquals(a, 0); assertEquals(b, 0); addTest(a, b); assertEquals(a, 0); assertEquals(b, 0); } void addTest(int a, int b) { a += 10; b += 10; System.out.println(..
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [hello.webpractice7.repository.MemberRepository arg0] in constructor [public hello.webpractice7.repository.MemberRepositoryTest(hello.webpractice7.repository.MemberRepository)]. 다음과 같은 에러가 나왔다. @RequiredArgsConstructor @SpringBootTest class MemberRepositoryTest { private final MemberReposi..
static 변수 static 변수를 사용하는 목적에는 2가지가 있다. 메모리의 효율 공유의 목적 class Counter { static int count = 0; Counter() { count++; System.out.println(this.count); } } public class Sample { public static void main(String[] args) { Counter c1 = new Counter(); Counter c2 = new Counter(); } }위와 같은 코드를 생각해보자. static 변수를 사용하면 count를 공유할 수 있다. static 변수가 없었으면 new Counter()로 객체를 생성할 때 count가 1 늘어나지만 공유되지는 않아 계속 만들어도 cou..