반응형

Maven을 이용하여 Java 외부 라이브러리를 사용하는 예로, H2 데이터베이스 엔진을 사용하여 JPA에서 데이터베이스 액세스하는 프로그램을 만드는 방법을 설명한다.


H2 + JPA 프로젝트 생성

Maven은 개발할 때, 필요한 라이브러리를 중앙 저장소에서 자동으로 다운로드하고 빌드한다. 따라서 개발하는데 뭔가 라이브러리를 사용하는 경우에도, Maven을 사용하고 있다면 해당 사이트에 가서 라이브러리를 다운로드하여 프로젝트에 추가할 필요가 전혀 없다. pom.xml에 라이브러리를 작성하고, 빌드하면 자동으로 모든 라이브러리가 참조되어 사용되기 때문이다.

그러면 실제로 어떤 라이브러리를 이용한 개발을 해보록 하자. Java 응용 프로그램에서 많이 사용되는 라이브러리라고 하면 "데이터베이스" 관련일 것이다.

여기에서는 "H2" 데이터베이스 엔진을 사용해 보기로 한다. H2는 pure Java의 SQL 데이터베이스 라이브러리이다. pure Java이어서 Java 프로그램 내에서 그대로 사용할 수 있다. 또한 H2는 파일에 데이터를 저장하고 메모리에 데이터를 저장할 수 있다. 개발 중에는 메모리에 저장해 두고, 릴리스 시에는 파일에 저장하는 방법도 있다.

중앙 저장소에서 검색

H2를 이용하기 위해 <dependency> 태그 작성법에 대해 알아 본다. 먼저 중앙 저장소 검색을 하는 사이트에 액세스를 한다.

https://search.maven.org/

여기에 액세스해서, 입력 필드에 "h2"라고 입력하여 검색해 본다. 검색 결과가 목록으로 표시될 것이다. 거기에서 그룹 ID는 "org.h2database", 아티팩트 ID는 "h2"라는 항목을 찾아, 해당 "Latest Version" 버전 번호 링크를 클릭한다. 버전 정보가 표시된다.

여기에 주요 빌드 도구에서의 라이브러리 추가하는 코드가 도구별로 정리되어 있다. "Dependency Information" 의 "Apache Maven"에 Maven의 <dependency> 태그가 게재되어 있다. 이것을 복사하여 pom.xml의 <dependencies> 안에 붙여 넣으면, H2 라이브러리를 프로젝트에 넣을 수 있다.

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

Maven에서 라이브러리를 이용하려면 이렇게 Maven의 검색 사이트에서 라이브러리를 검색하고 그 Dependency Information을 복사하여 pom.xml에 붙이는 식으로 라이브러리를 추가 할 수 있다. 익숙해지면 간단하다.

프로젝트와 pom.xml을 완성시킨다

이제 프로젝트를 만들어 보자. 이번에도 이전에 사용한 SampleMavenApp 프로젝트를 재사용할 수 있다. 만약 새로운 프로젝트를 생성하려면, mvn archetype:generate 명령으로 프로젝트를 작성한다. 이때 -DarchetypeArtifactId=maven-archetype-quickstart를 지정하여 실행하면 된다.

프로젝트가 준비되면 pom.xml을 완성시킨다. H2 라이브러리의 <depenency> 태그는 쉽게 준비할 수 있었지만, 이 외에도 필요한 라이브러리가 있다. 이번에는 JPA를 사용하여 데이터베이스에 액세스를 한다. 이를 위해 javax.persistence과 Persistence JPA를 준비해야 한다.

아래에 완성된 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/xsd/maven-4.0.0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.devkuma</groupId>
    <artifactId>SampleMavenApp</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
 
    <name>SampleMavenApp</name>
    <url>http://maven.apache.org</url>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </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>
 
    </dependencies>
 
    <build>
        <!--resource folder-->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
 
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <configuration>
                    <mainClass>com.devkuma.App</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
</project>

이번에는 플러그인 관계는 exec:java 위한 exec-maven-plugin 만 넣어 두었다. 일단 동작하면 되기에 이것으로 충분하다.

3개의 <dependency> 태그 외에 <build> 태그에도 낯선 태그가 추가되어 있다. 이것들은 모든 JPA 이용을 위해 필요한 것이다.

pom.xml에 추가된 내용

pom.xml에 이번 추가한 내용을 간략하게 정리하고 설명한다.

Eclipse의 Java Persistence API

JPA를 이용하면, Java Persistence API (javax.persistene)와 JPA 구현 라이브러리가 필요하다. 이번은 Eclipse Foundation이 개발하는 오픈 소스 라이브러리를 사용하고 있다.

Java Persistence API

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>javax.persistence</artifactId>
    <version>2.2.0</version>
</dependency>

javax.persistence 패키지의 라이브러리이다. API가 없으면 아무것도 할 수 없기에 이는 필수이다.

JPA

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.jpa</artifactId>
    <version>2.7.0</version>
</dependency>

JPA의 Eclipse Foundation에 의한 구현이다. JPA를 이용하는데 이것도 필요하다. 이 두 라이브러리 세트로 준비해야 한다고 생각하면 된다.

이에 앞서의 H2의 라이브러리를 맞춰 총 3 개의 라이브러리를 추가하면 JPA에 따르면 H2 데이터베이스 액세스를 사용할 수있게됩니다.

리소스 폴더의 등록

이 밖에 <build> 태그에도 새롭게 추가한 부분이 있다. 이 태그 부분이다.

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>

이것은 리소스 폴더를 등록하기 위한 것이다. <resource>는 리소스 폴더의 정보를 작성하는 것으로, 여기에서는 src/main/resources 경로를 추가한다. 이것으로 main 폴더의 resoures 폴더에 있는 리소스 파일을 빌드할 때에 로드하는 패키지에 추가하게 된다.



JPA를 사용하는 프로그램

JPA를 사용하는 프로그램을 만드는 방법을 설명한다.

persistence.xm 준비

JPA를 사용하는 경우, persistence.xml이라는 파일을 준비해야 한다. 이것은 JPA에서 사용하는 퍼시스턴스 유닛을 정의하는 것이다.

main 폴더에 resources 폴더를 작성한다. 이것은 앞에서 언급한 바와 같이, 리소스 폴더로 등록한 것이다. 이 폴더에 "META-INF"라는 폴더를 만든다. 그리고 그 안에 "persistence.xml '라는 이름으로 파일을 준비한다.

아래에 persistence.xml 소스 코드를 올려 두었다.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
 
    <persistence-unit name="sample-persistance" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.devkuma.MyEntity</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:db" />
            <property name="javax.persistence.jdbc.user" value="sa" />
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
            <property name="eclipselink.ddl-generation.output-mode" value="database" />
        </properties>
    </persistence-unit>
</persistence>

persistence.xml은 <persistence> 태그 안에 <persistence-unit>라는 태그를 준비하고, 거기에 퍼시스턴스 유닛의 정보를 작성한다. 여기에서는 다음과 같은 정보가 정리되어 있다.

  • 유닛 이름 : sample-persistance
  • 공급자 : org.eclipse.persistence.jpa.PersistenceProvider
  • 엔티티 클래스 : com.devkuma.MyEntity
  • 속성 :
    • javax.persistence.jdbc.driver (드라이버 클래스) : org.h2.Driver
    • javax.persistence.jdbc.url (데이터베이스 URL) : jdbc : h2 : mem : db
    • javax.persistence.jdbc.user (사용자 이름) : sa
    • eclipselink.ddl-generation (Eclipse Link 설정) : drop-and-create-tables
    • eclipselink.ddl-generation.output-mode (Eclipse Link 설정) : database

이들은 마지막 2개(Eclipse Link 설정) 이외는 JPA를 사용할 때 대부분은 필요한 정보이다. 이 중에는 특히 처음에 있는 유닛 이름, 프로바이더 클래스, 엔터티 클래스의 세 가지 필수 항목으로 반드시 준비한다.

<properties> 태그 안에 있는 속성의 값은 사용하는 데이터베이스에 따라 달라진다. 이 드라이버와 URL, 사용자 이름은 우선 대부분의 데이터베이스에 필요한 것이다. H2 이외의 데이터베이스의 설정은 여기에서 다루지 않는다. 별도 학습하길 바란다.

엔티티 클래스 생성

persistence.xml이 준비되면 다음에 필요한 것은 "엔티티 클래스"이다. 엔티티 클래스는 JPA에서 데이터베이스에 액세스할 때 기본이 되는 것이다. JPA에는 데이터베이스 테이블의 내용을 엔티티 클래스로서 정의해야 레코드를 주고 받을 때는 이 엔티티 클래스의 인스턴스로 처리하게 된다.

앞에서 persistence.xml에서 클래스로 com.devkuma.MyEntity 값을 설정했다. 이것이 sample-persistance 지속성 단위로 사용하는 엔티티 클래스이다. 이 클래스를 만들어 보자.

src/main/java/com/devkuma/ 폴더 안에 "MyEntity.java"라는 이름으로 파일을 작성한다. 그리고 아래와 같이 소스 코드를 작성하자.

package com.devkuma;
 
import java.util.Date;
import java.util.Calendar;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
 
@Entity
public class MyEntity {
    @Id
    @GeneratedValue
    private Integer id;
 
    private String name;
    private String message;
    private Date date = Calendar.getInstance().getTime();
 
    public MyEntity(){
        super();
    }
 
    public MyEntity(String name, String msg){
        super();
        this.name = name;
        this.message = msg;
    }
 
    public Integer getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String msg) {
        this.message = msg;
    }
    public Date getDate() {
        return date;
    }
 
    @Override
    public String toString() {
        return "{\n\tid: " + id + ",\n\tname: " + name + ",\n\tmessage: "
             + message+ ",\n\tdate: " + date + "\n}";
    }
 
}

엔티티 클래스는 @Entity 어노테이션을 붙인 POJO 클래스이다. Primary key가 되는 필드에는 @Id를 분여, 더불어 @GeneratedValue으로 값을 자동 할당하는 것을 나타낸다.

이 후에는 private 필드와 그 Setter/Getter 메소드의 형태로 저장하는 값을 준비하고 있다. 이것들은 테이블에 포함하는 항목에 해당하는 것이다. 이번에는 id, name, message, date 등 항목을 준비해 두었다.

MyEntity를 이용하기

이제 H2 + JPA에서 데이터베이스를 사용하는 환경이 되었다. 실제로 이용해 보자.

아래에 간단한 샘플을 올려 두었다. App.java을 편집한다.

package com.devkuma;
 
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
 
public class App {
    private static EntityManagerFactory factory
        = Persistence.createEntityManagerFactory("sample-persistance");
 
    public static void main( String[] args ){
        EntityManager manager = factory.createEntityManager();
        try {
            manager.getTransaction().begin();
            manager.persist(new MyEntity("sungjin", "This is sample message!"));
            manager.persist(new MyEntity("wonsuk", "안녕하세요!"));
            manager.persist(new MyEntity("byeongho", "이것을 테스트입니다."));
            manager.getTransaction().commit();
 
            Query query = manager.createQuery("select i from MyEntity i");
            List<MyEntity> list = query.getResultList();
            int count = 0;
            for (MyEntity p : list) {
                System.out.print("No," + ++count + " ");
                System.out.println(p);
            }
            System.out.println(" -- total: " + list.size() + " data.");
        } finally {
            manager.close();
        }
    }
}

소스가 변경되면,

mvn packge
mvn exec:java

이와 같이 실행하여 패키지와 프로그램의 실행을 한다. 실행하면 콘솔에 다음과 같은 텍스트가 출력된다.

No, 1 {
        id : 1
        name : sungjin,
        message : This is sample message !,
        date : Fri Oct 13 21:28:11 JST 2017
}
No, 2 {
        id : 2
        name : wonsuk,
        message : 안녕하세요!,
        date : Fri Oct 13 21:28:11 JST 2017
}
No, 3 {
        id : 3
        name : byeongho,
        message : 이것을 테스트입니다. ,
        date : Fri Oct 13 21:28:11 JST 2017
}
 - total : 3 data.

여기에서는 더미로 3개의 엔티티를 생성하여 데이터베이스에 저장하고 다시 데이터베이스에서 MyEntity을 얻어 내용을 출력한다. 우선 데이터의 읽고 쓰기 가능하다는 것은 확인할 수 있다.

여기서는 JPA의 사용법을 설명하기 위한 것이 아니기 때문에 자세한 설명은 생략하지만, 이것으로 "JPA를 사용하는 프로그램"의 기본적인 만드는 방법은 알게 되었다. 우선은 데이터베이스부터 시작하여 조금씩 사용할 수 있는 라이브러리의 폭을 넓혀 가면 된다.

반응형

+ Recent posts