JPA 이용 준비

JPA는 데이터베이스 액세스의 기본이라고 할 수 있는 기술이다. 우선, JPA가 무엇인지 설명하고 JPA를 사용하는 프로젝트를 준비하고, JPA 활용을 위한 준비를 하도록 하겠다.

JPA 란?

JPA(Java Persistence API)는 관계형 데이터베이스에 액세스하기 위한 프레임워크이다. 데이터베이스 액세스라고 하면, Java SE에서는 오랫동안 JDBC가 일반적이었다. 지금도 사용하고 있는 사람은 꽤 있을 것이다.

JPA는 데이터베이스 액세스라고 하기 보다는 정확하게는 “데이터 지속성” 기능을 제공한다. 지속성이라는 것은 “프로그램을 종료한 후에도 계속 데이터가 남아있다"라는 것을 말한다. 데이터베이스에 데이터를 저장하고, 필요에 따라 저장된 데이터를 조회할 수 있게 되는 것이다.

그럼, 데이터베이스 액세스로 되는 거자나? 왜 지속성이라고 하는거야? 라고 생각하는 사람이 있을 수도 있다. 이는 실제로 JPA를 사용해 보면 알 수 있을 것이다. JPA는 데이터 객체를 저장하면 그대로 저장될 뿐이다.

JPA를 이용하게 되면 데이터베이스에 액세스하고 저장 쿼리를 실행은 전혀 하지 않아도 된다. 또한 액세스하는 SQL 쿼리를 텍스트로 작성하지도 않는다. 저장하는 객체에서 하나 하나 값을 꺼내 변경하고…… 등과 같은 일도 하지 않는다. 다만, 저장할 객체를 그대로 저장할 뿐이다.

JPA 안쪽에서는 데이터베이스에 대한 액세스가 이루어지고 있다. 하지만 앞쪽(우리가 실제로 작동하는 측)에서는 Java의 객체를 저장하고 검색하고 있을 뿐이다. 데이터베이스에 SQL으로 액세스하고 하는 것을 의식하지 않아도 된다.

어디선가 “ORM"라는 말을 들어 본 적이 있을 것이다. ORM은 “Object-relational Mapping"의 약자로 Java의 객체와 관계형 데이터베이스 사이를 매핑하는 방식이다. Java 객체와 데이터베이스 레코드 사이를 매핑하고 원활하게 교환할 수 있는 구조를 제공하는 것이 ORM이다.

JPA는 정확히 ORM과는 조금 다르지만, ORM처럼 Java의 객체에서 원활하게 데이터베이스 레코드로 변환하여 처리를 해준다. JPA를 이용하면 데이터베이스 이용의 개발도 데이터베이스 처리 등을 생각할 필요는 없다. 단, 데이터가 되는 클래스를 정의하고 해당 메소드를 호출하면 내부적으로 필요에 따라 데이터베이스에 액세스하게 되는 것이다.

또한 액세스를 위해서는 “JPQL"라는 전용 간이 언어가 준비되어 있다. 이것은 SQL과 유사한 언어이다. 하지만 SQL와 같이 데이터베이스마다 문법이 다른 경우가 있는데 하나의 작성 방법으로 다양한 데이터베이스에 동일하게 액세스할 수 있다. 데이터베이스를 변경하고자 하는 경우에도 이를 위한 설정을 다시 작성뿐이다. 구체적인 코드는 모두 다시 작성할 필요는 없다.

JPA 프로젝트 만들기

그러면 실제로 샘플 프로젝트를 생성하여 코드를 작성하여 동작시키면서 JPA의 사용법에 대해 설명하도록 하겠다.

우선 프로젝트를 생성해 보자. 여기에서는 빌드 도구 “Apache Maven"를 사용하여 Web 응용 프로그램 프로젝트를 만든다. Maven이 뭔지 모르는 사람은 먼저 다음 Maven에 대해 먼저 알아보길 바란다.

Maven

그럼, 먼저 명령 프롬프트 또는 터미널을 기동하여 cd로 적당한 위치로 이동한다. 그러고 다음과 같이 명령을 실행한다.

$ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp

그러면 Web 어플리케이션의 프로젝트가 만들어 진다. 실행되면 다음의 정보를 입력해 가도록 한다.

groupId: com.devkuma.jpa
artifactId: JavaApp
version: 1.0-SNAPSHOT (디폴트 설정으로 OK)
package: com.devkuma.jpa (디폴트 설정으로 OK)

기본적으로 첫 번째 groupId와 artifactId 만 입력하면,이후 2개는 디폴트인 상태로 하도록 한다. 만들 때 “JavaApp” 폴더가 만들어지고 그 안에 응용 프로그램의 파일들이 생성된다.

여기에서는 모든 설명은 JavaApp 프로젝트를 사용한다. 도중에 일일이 “이런 프로젝트를 준비하고 ……“라고 설명하지 않겠다. 이 프로젝트를 열고 파일을 편집하면서 보길 바란다.

폴더 구성

생성된 프로젝트 폴더에는 이미 여러 개의 파일이나 폴더가 생성되어 있다. 대략 정리하면 다음과 같다.

JavaApp 폴더

$ tree
.
├── pom.xml
└── src
    └── main
        ├── resources
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            └── index.jsp

5 directories, 3 files

폴더의 구성이 복잡해 보일 수도 있지만, “webapp” 폴더가 실제로 Web 어플리케이션으로서 공개되는 폴더하다고 생각해도 좋다. 이 안에 JSP 나 HTML 등의 파일을 준비해 나갈 것이다.

그리고, resources 폴더는 Web 응용 프로그램에 필요한 리소스 파일을 넣는 폴더이다. 이 폴더에는 JPA를 사용하게 되면 설정 파일들이 들어가게된다.

pom.xml 작성하기

Maven 프로젝트 빌드에 대한 상세한 설정 등을 pom.xml이라는 파일에 작성한다. 프로젝트를 만들려면 이 pom.xml에 필요한 라이브러리 등의 정보를 작성하면 된다.

이번에는 Web 응용 프로그램에 필요한 라이브러리와 JPA 이용에 필요한 것을 준비하려고 한다. 어떤 것이 필요한지 정리해 보도록 하겠다. 우선, Web 어플리케이션 관련부터 설명하겠다.

Web 응용 프로그램에 필요한 라이브러리

<!-- jetty -->
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>${jetty.version}</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-webapp</artifactId>
    <version>${jetty.version}</version>
</dependency>

Web 응용 프로그램은 서블릿 컨테이너(이른바 Java 서버) 기능이 필요하다. 여기에서는 Jetty를 Web 응용 프로그램 내에서 사용하기 하였다. 이에 해당되는 라이브러리가 jetty-server와 jetty-webapp의 두 가지이다.

이 라이브러리를 포함하여 Web 응용 프로그램을 그대로 Jetty 서버에서 실행될 수 있게 한다. 또한 Jetty 등의 서블릿 컨테이너에는 Web 응용 프로그램의 기본 API (서블릿과 JSP를 위한 라이브러리)가 내장 되어 있어, 일부러 Web 응용 프로그램 작성을 위해 서블릿과 JSP를 위한 라이브러리를 별도 준비할 필요는 없다.

Web 응용 프로그램에서 사용할 플러그인

<!-- jetty plugin -->
<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>${jetty.version}</version>
</plugin>

Jetty 서버 라이브러리를 제공하는 것만으로는 활용할 수 없다. 준비한 Jetty 서버를 사용하여 Web 응용 프로그램을 실행하는 기능도 제공하지 않으면 안된다. 이에 해당되는 플러그인이 jetty-maven-plugin이다.

마무리

이번 프로젝트의 pom.xml을 아래와 같다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.devkuma.jpa</groupId>
    <artifactId>JavaApp</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>JavaApp Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jetty.version>9.4.7.v20170914</jetty.version>
    </properties>

    <dependencies>
        <!-- jetty -->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${jetty.version}</version>
        </dependency>

        <!--h2-->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.196</version>
        </dependency>

        <!-- eclipse.persistence-->
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>javax.persistence</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.jpa</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>JavaApp</finalName>

        <plugins>
            <!-- jetty plugin -->
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>${jetty.version}</version>
            </plugin>
        </plugins>
    </build>
</project>