티스토리 뷰

Developer

[ORM#2] Getting started with JPA

rocksea 2015. 8. 4. 15:19

Hibernate, JPA Tutorial

JPA(Java Persistence API)를 이용하면 RDBMS의 접근성을 높일 수 있으며,

DBMS에 독립적인 (DBMS가 바뀌어도 소스코드를 바꿀일이 없다) 코드를

작성 할 수 있다.

JPA를 이용하여 RDBMS에 접근하는 방법을 Tutorial을 통해 설명한다.



개발환경

Spring Framework 3.2

Maven 3.0.4

Hibernate 4.3.10

Spring Security 3.2.7


Maven Dependencies

<dependency>

  <groupId>org.hibernate</groupId>

  <artifactId>hibernate-entitymanager</artifactId>

  <version>${hibernate.version}</version>

</dependency>

<dependency>

  <groupId>org.springframework.data</groupId>

  <artifactId>spring-data-jpa</artifactId>

  <version>1.3.2.RELEASE</version>

</dependency>


step 1. DB Table 생성

예제로 사용 할 DB 테이블 하나를 생성한다.

CREATE TABLE `code` (

  `code_no` int(11) NOT NULL AUTO_INCREMENT,

  `code` varchar(20) DEFAULT NULL,

  `name` varchar(20) DEFAULT NULL,

  `del_yn` char(1) DEFAULT NULL,

  `reg_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP

)


step 2. JPA Configuration Class 작성

Persistence Configuration을 위한 Class파일을 작성한다.

PersistenceConfig.java

package kr.co.rocksea.config; import java.util.Properties; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.orm.hibernate4.HibernateExceptionTranslator; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableJpaRepositories(basePackages="kr.co.rocksea.persistence.repository") @EnableTransactionManagement public class PersistenceConfig { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setDataSource(dataSource()); factory.setPackagesToScan("kr.co.rocksea.persistence"); factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); factory.setPersistenceUnitName("rocksea"); Properties jpaProperties = new Properties(); jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect"); jpaProperties.put("hibernate.hbm2ddl.auto", "update"); jpaProperties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy"); factory.setJpaProperties(jpaProperties); return factory; } @Bean public DataSource dataSource(){ BasicDataSource dataSource = new BasicDataSource() ; dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://192.168.0.10:3306/rocksea?autoReconnect=true&useUnicode=true&characterEncoding=UTF8"); dataSource.setUsername("rocksea"); dataSource.setPassword("1234"); dataSource.setMaxActive(5); dataSource.setMaxIdle(3); dataSource.setMaxWait(60000); dataSource.setValidationQuery("select 1"); dataSource.setTestWhileIdle(true); dataSource.setTimeBetweenEvictionRunsMillis(7200000); return dataSource; } @Bean public PlatformTransactionManager transactionManager(){ EntityManagerFactory factory = entityManagerFactory().getObject(); return new JpaTransactionManager(factory); } @Bean public HibernateExceptionTranslator hibernateExceptionTranslator(){ return new HibernateExceptionTranslator(); } }


step 3. Entity Class 작성

실제 DB테이블과 Mapping되는 Entity 객체를 지정한다.

Code.java

package kr.co.rocksea.persistence.entity;

import static javax.persistence.GenerationType.IDENTITY;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
 
@Entity
@Table(name = "code", catalog = "rocksea", uniqueConstraints = {
        @UniqueConstraint(columnNames = "NAME"),
        @UniqueConstraint(columnNames = "CODE") })
public class Code implements java.io.Serializable {
 
    private Integer codeId;
    private String code;
    private String name;
 
    public Code() {
    }
 
    public Code(String code, String codeName) {
        this.code = code;
        this.name = name;
    }
 
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "CODE_NO", unique = true, nullable = false)
    public Integer getCodeId() {
        return this.codeId;
    }
 
    public void setCodeId(Integer codeId) {
        this.codeId = codeId;
    }
 
    @Column(name = "CODE", unique = true, nullable = false, length = 10)
    public String getCode() {
        return this.code;
    }
 
    public void setCode(String code) {
        this.code = code;
    }
 
    @Column(name = "NAME", unique = true, nullable = false, length = 20)
    public String getName() {
        return this.name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
 
}



step 4. CodeRepository Class 작성

JPA Repository를 이용하여 DBMS에 접근하여 Data를 save(), find()등의 

메소드를 통해 입/출력을 제어 할 수 있다.

CodeRepository.java

package kr.co.igrove.persistence.repository;

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

import kr.co.igrove.persistence.entity.Code;

public interface CodeRepository extends JpaRepository<Code, Integer>  {

}


step 5. Service Class 작성

Service 객체를 이용하여 데이터를 가공하여 처리한다.

package kr.co.rocksea.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import kr.co.igrove.persistence.entity.Code;
import kr.co.igrove.persistence.repository.CodeRepository;

@Component
public class CodeService {
    @Autowired
    private CodeRepository codeRepository;
    
    public Code findCode(int id){
        Code code = codeRepository.findOne(id);
        return code;
    }
    
    public Code saveCode(Code code){
        Code result = codeRepository.save(code);
        return result;
    }
}


step 6. Test

findCode()를 통해 기존 데이터를 조회하고, saveCode()를 통해 저장하는 기능을통해

확인해보도록 한다.

@Controller
public class RockseaController {
    
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    @Autowired
    private CodeService codeService;

        @RequestMapping(value = "/rocksea", method = RequestMethod.GET)
    public String jpa(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
        
        System.out.println("Maven + Hibernate + MySQL");
        Code code1 = codeService.findCode(1);
        logger.info("CODE : " + code1.getCode());
        logger.info("NAME : " + code1.getName());
        
        
        Code setCode = new Code();
        setCode.setCode("MIRAI");
        setCode.setName("미래");
        Code code2 = codeService.saveCode(setCode);

        logger.info("CODE2 : " + code2.getCode());
        logger.info("NAME2 : " + code2.getName());

        return "home";
    }
}


DB Table 확인

mysql> select * from code;

+---------+---------------+---------+--------+--------+---------------------+

| code_no | code    | name   | del_yn | reg_dt              |

+---------+---------------+---------+--------+--------+---------------------+

|       1 | ROCKSEA | 락시   | N      | 2015-08-03 15:08:33 |

|      16 | MIRAI   | 미래   | N      | 2015-08-03 17:56:07 |

+---------+---------------+---------+--------+--------+---------------------+


댓글