본문 바로가기

개발(합니다)/Java&Spring

Spring maven project JPA 설정 정리

반응형

Spring maven project Bean, DI, AOP(Aspect) 학습에 이어 JPA를 정리합니다.


1. xml 설정

pom.xml
<!-- Spring -->
        <spring-framework.version>3.2.9.RELEASE</spring-framework.version>

<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

        <!-- Property 'databaseType' threw exception; nested exception is
java.lang.IllegalStateException:
            Driver for test database type [H2] is not available => scope=test
-> scope=runtime -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.197</version>
            <scope>runtime</scope>
        </dependency>
        <!-- Constructor threw exception; nested exception is
java.lang.NoClassDefFoundError:
            javax/persistence/Converter -->
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <!-- Could not instantiate bean class [org.springframework.orm.jpa.vendor.
HibernateJpaVendorAdapter]:
            Constructor threw exception; nested exception is
java.lang.NoClassDefFoundError: -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

주석 부분은 에러가 나서 에러를 표시하고 pom에 필요 repository를 추가했습니다.


application.properties

#Database Configuration
db.driver=org.h2.Driver
db.url=jdbc:h2:mem:datajpa
db.username=sa
db.password=

#Hibernate Configuration
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create-drop

DB 정보를 입력합니다.

create-drop은 프로그램이 시작하면 생성하고 끝나면 삭제하라는 의미입니다.


dbBean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <jdbc:embedded-database id="dataSource"
        type="H2"></jdbc:embedded-database>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="true"></property>
            </bean>
        </property>
    </bean>


</beans>

datasource 설정입니다.


persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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.xsd">


    <persistence-unit name="persistence-unit"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.diarect"
                value="${hibernate.dialect}"></property>
            <property name="hibernate.hbm2ddl.auto"
                value="${hibernate.hbm2ddl.auto"></property>
            <property name="javax.persistence.jdbc.driver"
                value="${db.driver}"></property>
            <property name="javax.persistence.jdbc.url"
                value="${db.url}"></property>
            <property name="javax.persistence.jdbc.user"
                value="${db.user}"></property>
            <property name="javax.persistence.jdbc.password"
                value="${db.password}"></property>
        </properties>
    </persistence-unit>

</persistence>

datasource 설정과 같은 persistence.xml


SampleEntity.java

package com.otrodevym.test.db;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class SampleEntity {
    
    @Id
    @Column
    @GeneratedValue(strategy=GenerationType.AUTO)
    private String id;
    
    @Column(length=50, nullable=false)
    private String name;
    
    @Column(length=100, nullable=true)
    private String mail;
    
    public SampleEntity() {
        // TODO Auto-generated constructor stub
    }
    

    public SampleEntity(String name, String mail) {
        super();
        this.name = name;
        this.mail = mail;
    }


    public SampleEntity(String id, String name, String mail) {
        super();
        this.id = id;
        this.name = name;
        this.mail = mail;
    }


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    @Override
    public String toString() {
        return "SampleEntity [id=" + id + ", name=" + name + ", mail=" + mail + "]";
    }
}

DB와 같은 형태로 만들어야 합니다.


dbApp.xml

package com.otrodevym.test.db;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DbApp {
    private static EntityManager manager;
    
    public static void main(String args[]) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("dbbean.xml");

        EntityManagerFactory factory = ac.getBean(EntityManagerFactory.class);
        manager = factory.createEntityManager();
                
        makeDummyData();
        
Query query = manager.createQuery("from SampleEntity");
        List list = query.getResultList();

        printList(list);
        
        
    }
    
    public static void makeDummyData() {
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.persist(new SampleEntity("kim", "kim@naver.com"));
        manager.persist(new SampleEntity("park", "pack@daum.net"));
        manager.persist(new SampleEntity("han", "han@gaml.com"));
        manager.flush();
        transaction.commit();
    }
    
    
    public static void printList(List list) {
        for(Object item : list) {
            System.out.println(item);
        }
    }
}

추가, 조회를 합니다.


2. 어노테이션 설정

SampleBeanCnfig.java

package com.otrodevym.test.db;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.hibernate3.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories("com.otrodevym.test.db")
@EnableTransactionManagement
public class SampleEntityConfig {
    
    @Bean
    public DataSource dataSource() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).build();
    }
    
    @Bean
    public EntityManagerFactory entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        
        LocalContainerEntityManagerFactoryBean factory =
                new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.otrodevym.test.db");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}


dbApp.xml

package com.otrodevym.test.db;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DbApp {
private static EntityManager manager;
public static void main(String args[]) {
ApplicationContext ac =
new AnnotationConfigApplicationContext(SampleEntityConfig.class);

EntityManagerFactory factory = ac.getBean(EntityManagerFactory.class);
manager = factory.createEntityManager();
makeDummyData();
Query query = manager.createQuery("from SampleEntity");
List list = query.getResultList();

printList(list);
}
public static void makeDummyData() {
EntityTransaction transaction = manager.getTransaction();
transaction.begin();
manager.persist(new SampleEntity("kim", "kim@naver.com"));
manager.persist(new SampleEntity("park", "pack@daum.net"));
manager.persist(new SampleEntity("han", "han@gaml.com"));
manager.flush();
transaction.commit();
}
public static void printList(List list) {
for(Object item : list) {
System.out.println(item);
}
}
}


3. JPA CRUD 방법

CRUD 
package com.otrodevym.test.db;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DbApp {
    private static EntityManager manager;
    
    public static void main(String args[]) {
ApplicationContext ac = new ClassPathXmlApplicationContext("dbbean.xml");
        
        EntityManagerFactory factory = ac.getBean(EntityManagerFactory.class);
        manager = factory.createEntityManager();
        
        SampleEntityRepository repository = ac.getBean(SampleEntityRepository.class);
        
        makeDummyData();
        
        updateEntity("1");

        deleteEntity("2");
        
        Query query = manager.createQuery("from SampleEntity");
        List list = query.getResultList();
        printList(list);
        
        
    }
    
    public static void makeDummyData() {
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.persist(new SampleEntity("kim", "kim@naver.com"));
        manager.persist(new SampleEntity("park", "pack@daum.net"));
        manager.persist(new SampleEntity("han", "han@gaml.com"));
        manager.flush();
        transaction.commit();
    }
    
    
    public static void printList(List list) {
        for(Object item : list) {
            System.out.println(item);
        }
    }
    public static void updateEntity(String id) {
        SampleEntity entity = manager.find(SampleEntity.class, id);
        entity.setName("name");
        entity.setMail("name@mail.com");
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.merge(entity);
        manager.flush();
        transaction.commit();
    }
    
    public static void deleteEntity(String id) {
        SampleEntity entity = manager.find(SampleEntity.class, id);
        EntityTransaction transaction = manager.getTransaction();
        
        transaction.begin();
        manager.remove(entity);
        manager.flush();
        transaction.commit();
    }
    
}



4. JPQL 문법

from <entity > where <조건식>

from Entity where id = 1

from Entity where like '%k%''


5. JPA Repository

이 기능을 현업에서 많이 쓰지 않을까 생각합니다.

5-1. xml 설정

SampleEntityRepository.java 
package com.otrodevym.test.db;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SampleEntityRepository extends JpaRepository<SampleEntity, String> {
    
    public List<SampleEntity> findByNameLike(String name);
    public List<SampleEntity> findByMailEndingWith(String mail);
}


dbBean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <jdbc:embedded-database id="dataSource"
        type="H2"></jdbc:embedded-database>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="true"></property>
            </bean>
        </property>
    </bean>

    <jpa:repositories base-package="com.otrodevym.test.db"></jpa:repositories>

    <bean id="transactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory"
            ref="entityManagerFactory"></property>
    </bean>
</beans>


DbApp.java

package com.otrodevym.test.db;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DbApp {
    private static EntityManager manager;
    
    public static void main(String args[]) {

        ApplicationContext ac = new ClassPathXmlApplicationContext("dbbean.xml");

        SampleEntityRepository repository = ac.getBean(SampleEntityRepository.class);
        
        makeDummyData();
        
        List list = repository.findAll();
        printList(list);
        
        List list1 = repository.findByNameLike("%ki%");
        System.out.println("find by name");
        printList(list1);
        List list2 = repository.findByMailEndingWith(".com");
        System.out.println("find by mail");
        printList(list2);
    }
    
    public static void makeDummyData() {
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.persist(new SampleEntity("kim", "kim@naver.com"));
        manager.persist(new SampleEntity("park", "pack@daum.net"));
        manager.persist(new SampleEntity("han", "han@gaml.com"));
        manager.flush();
        transaction.commit();
    }
    
    
    public static void printList(List list) {
        for(Object item : list) {
            System.out.println(item);
        }
    }

}

manager가 아닌 repository로 호출합니다.

5-2. 어노테이션 설정

SampleEntityConfig.java
package com.otrodevym.test.db;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.hibernate3.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories("com.otrodevym.test.db")
@EnableTransactionManagement
public class SampleEntityConfig {
    
    @Bean
    public DataSource dataSource() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).build();
    }
    
    @Bean
    public EntityManagerFactory entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        
        LocalContainerEntityManagerFactoryBean factory =
                new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.otrodevym.test.db");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
    
     @Bean
     public HibernateExceptionTranslator hibernateExceptionTranslator(){
     return new HibernateExceptionTranslator();
     }
    
    @Bean
    protected JpaTransactionManager transactionManager(EntityManagerFactory
entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}


DbApp.java

package com.otrodevym.test.db;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class DbApp {
    private static EntityManager manager;
    
    public static void main(String args[]) {

        ApplicationContext ac =
new AnnotationConfigApplicationContext(SampleEntityConfig.class);
        
        SampleEntityRepository repository = ac.getBean(SampleEntityRepository.class);
        
        makeDummyData();
        
        List list = repository.findAll();
        printList(list);
        
        List list1 = repository.findByNameLike("%ki%");
        System.out.println("find by name");
        printList(list1);
        List list2 = repository.findByMailEndingWith(".com");
        System.out.println("find by mail");
        printList(list2);
    }
    
    public static void makeDummyData() {
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.persist(new SampleEntity("kim", "kim@naver.com"));
        manager.persist(new SampleEntity("park", "pack@daum.net"));
        manager.persist(new SampleEntity("han", "han@gaml.com"));
        manager.flush();
        transaction.commit();
    }
    
    
    public static void printList(List list) {
        for(Object item : list) {
            System.out.println(item);
        }
    }

}


6. JPA Repository 명명 규칙

findBy~
findName("kim"

Like / NotLike

findByNamLike("k")


StartingWith / EndingWith

findByNameStrartingWith("kim")


IsNull / IsNotNull

findByNameIsNull()


True / False

findByCheckTrue()


Before / After

findByDateBefore(2018)


LessThan / GreaterThan

findByNumLessThen(50)


Between

findByNameBetween

반응형