programing tip

Spring DAO 대 Spring ORM 대 Spring JDBC

itbloger 2020. 8. 27. 07:25
반응형

Spring DAO 대 Spring ORM 대 Spring JDBC


Spring에서 지원하는 데이터 액세스 기술을 살펴 보았는데 여러 옵션이 언급되어 있고 그 차이에 대해 잘 모르겠습니다.

내가 이해하는 바와 같이 Spring JDBC는 평범한 예전 방식을 통해 데이터베이스에 액세스하기위한 상용구 코드를 줄이기위한 템플릿을 제공합니다. 사용자는 SQL 쿼리를 직접 작성합니다.

Spring-ORM은 Hibernate, My (i) Batis 등과 같은 ORM 기술을 통해 데이터베이스에 액세스하기위한 단순화 된 템플릿을 제공합니다.

Spring 웹 사이트에 따른 Spring-DAO :

Spring의 DAO (Data Access Object) 지원은 JDBC, Hibernate 또는 JDO와 같은 데이터 액세스 기술을 일관된 방식으로 쉽게 사용할 수 있도록하는 데 목적이 있습니다.

DB에 액세스하는 다른 방법을 겨냥한 ORM 대 JDBC에 대해 조금 분명합니다. 그러나 Spring-DAO는 혼란 스럽습니다!

누구든지이 세 가지의 차이점을 정확히 설명해 주시겠습니까? 어떤 시나리오에서 어떤 것이 선호되어야합니까?

또한 Spring-DATA사용 가능한 다른 프로젝트가 있습니다 ( http://projects.spring.io/spring-data/ ) 이제 Spring에서 지원하는 모든 데이터 액세스 기술을위한 일종의 부모 프로젝트입니까 아니면 Spring의 새로운 이름입니까? -DAO?


다음은 언급 된 각 기술에 대한 소개입니다.

봄 -DAO

Spring-DAO는 엄격한 스프링 모듈이 아니라 DAO를 작성하고 잘 작성하도록 지시하는 규칙입니다. 따라서 데이터에 액세스하기위한 인터페이스, 구현 또는 템플릿을 제공하지 않습니다. DAO를 작성할 때 @Repository기본 기술 (JDBC, Hibernate, JPA 등)에 연결된 예외가 적절한 DataAccessException하위 클래스 로 일관되게 변환되도록 DAO에 주석을 달아야합니다 .

예를 들어, 이제 Hibernate를 사용하고 있고 서비스 계층 HibernateException이 이에 대응하기 위해 포착한다고 가정 합니다. JPA로 변경하면 DAO 인터페이스가 변경되어서는 안되며 서비스 계층은 여전히를 catch하는 블록으로 컴파일 HibernateException되지만 DAO가 이제 JPA를 던지고 있으므로 이러한 블록에 들어 가지 않습니다 PersistenceException. @RepositoryDAO에서 사용 하면 기본 기술에 연결된 예외가 Spring으로 변환됩니다 DataAccessException. 서비스 계층은 이러한 예외를 포착하고 지속성 기술을 변경하기로 결정한 경우 Spring DataAccessExceptions이 네이티브 예외를 번역했기 때문에 동일한 Spring 이 여전히 throw됩니다.

그러나 다음과 같은 이유로 사용이 제한됩니다.

  1. 공급자가 트랜잭션을 롤백했을 수 있으므로 (정확한 예외 하위 유형에 따라) 일반적으로 지속성 예외를 포착하지 않아야하며, 따라서 대체 경로로 실행을 계속해서는 안됩니다.
  2. 예외의 계층 구조는 일반적으로 Spring이 제공하는 것보다 공급자에서 더 풍부하며 한 공급자에서 다른 공급자로의 명확한 매핑이 없습니다. 이것에 의존하는 것은 위험합니다. 그러나 @Repository스캔 절차에 의해 빈이 자동으로 추가 되므로 DAO에를 주석으로 추가하는 것이 좋습니다 . 또한 Spring은 주석에 다른 유용한 기능을 추가 할 수 있습니다.

Spring-JDBC

Spring-JDBC는 배관 코드를 제거하고 SQL 쿼리 및 매개 변수에 집중하는 데 도움이되는 JdbcTemplate 클래스를 제공합니다. 으로 구성하기 만하면 DataSource다음과 같은 코드를 작성할 수 있습니다.

int nbRows = jdbcTemplate.queryForObject("select count(1) from person", Integer.class);

Person p = jdbcTemplate.queryForObject("select first, last from person where id=?", 
             rs -> new Person(rs.getString(1), rs.getString(2)), 
             134561351656L);

Spring-JDBC는 DAO를 개발하기 위해 확장 할 수있는 JdbcDaoSupport도 제공합니다. 기본적으로 두 가지 속성, 즉 DAO 메서드를 구현하는 데 사용할 수있는 DataSource 및 JdbcTemplate을 정의합니다. 또한 SQL 예외에서 Spring DataAccessExceptions로 예외 변환기를 제공합니다.

일반 jdbc를 사용하려는 경우이 모듈을 사용해야합니다.

봄 ORM

Spring-ORM은 JPA, JDO, Hibernate 및 iBatis와 같은 많은 지속성 기술을 다루는 우산 모듈입니다. 이러한 각 기술에 대해 Spring은 각 기술이 Spring의 구성 원칙에 따라 사용될 수 있도록 통합 클래스를 제공하고 Spring 트랜잭션 관리와 원활하게 통합됩니다.

각 기술에 대해 구성은 기본적으로 DataSource일종의 SessionFactory또는 EntityManagerFactory기타 빈에 빈을 주입하는 것으로 구성됩니다 . 순수한 JDBC의 경우 JDBC는 DataSource에만 의존하므로 JdbcTemplate과는 별도로 이러한 통합 클래스가 필요하지 않습니다.

JPA 또는 Hibernate와 같은 ORM을 사용하려는 경우 spring-jdbc가 필요하지 않고이 모듈 만 필요합니다.

스프링 데이터

Spring-Data is an umbrella project that provides a common API to define how to access data (DAO + annotations) in a more generic way, covering both SQL and NOSQL data sources.

The initial idea is to provide a technology so that the developer writes the interface for a DAO (finder methods) and the entity classes in a technology-agnostic way and, based on configuration only (annotations on DAOs & entities + spring configuration, be it xml- or java-based), decides the implementation technology, be it JPA (SQL) or redis, hadoop, etc. (NOSQL).

If you follow the naming conventions defined by spring for the finder method names, you don't even need to provide the query strings corresponding to finder methods for the most simple cases. For other situations, you have to provide the query string inside annotations on the finder methods.

When the application context is loaded, spring provides proxies for the DAO interfaces, that contain all the boilerplate code related to the data access technology, and invokes the configured queries.

Spring-Data concentrates on non-SQL technologies, but still provides a module for JPA (the only SQL technology).

What's next

Knowing all this, you have now to decide what to pick. The good news here is that you don't need to make a definitive final choice for the technology. This is actually where Spring power resides : as a developer, you concentrate on the business when you write code, and if you do it well, changing the underlying technology is an implementation or configuration detail.

  1. Define a data model with POJO classes for the entities, and get/set methods to represent the entity attributes and the relationships to other entities. You will certainly need to annotate the entity classes and fields based on the technology, but for now, POJOs are enough to start with. Just concentrate on the business requirements for now.
  2. Define interfaces for your DAOs. 1 DAO covers exactly 1 entity, but you will certainly not need a DAO for each of them, as you should be able to load additional entities by navigating the relationships. Define the finder methods following strict naming conventions.
  3. Based on this, someone else can start working on the services layer, with mocks for your DAOs.
  4. You learn the different persistence technologies (sql, no-sql) to find the best fit for your needs, and choose one of them. Based on this, you annotate the entities and implement the DAOs (or let spring implement them for you if you choose to use spring-data).
  5. If the business requirements evolve and your data access technology is not sufficient to support it (say, you started with JDBC and a few entities, but now need a richer data model and JPA is a better choice), you will have to change the implementation of your DAOs, add a few annotations on your entities and change the spring configuration (add an EntityManagerFactory definition). The rest of your business code should not see other impacts from your change.

Note : Transaction Management

Spring provides an API for transaction management. If you plan to use spring for the data access, you should also use spring for transaction management, as they integrate together really well. For each data access technology supported by spring, there is a matching transaction manager for local transactions, or you can choose JTA if you need distributed transactions. All of them implement the same API, so that (once again) the technology choice is just a matter a configuration that can be changed without further impact on the business code.

Note : Spring documentation

The links to Spring documentation that you mentioned are rather old. Here is the documentation of the latest release (4.1.6, covering all topics) :

Spring-data is not part of the Spring framework. There is a common module that you should first read to get used to the principles. Documentation can be found here:


Spring DAO(Data Access Object): is an object that provides an abstract interface to JDBC implementation frameworks i.e. Spring DAO is generalized concept to access JDBC and Hibernate, MyBatis, JPA, JDO using it's individual Support classes. And it provides generalized exception hierarchy by defining @Repository annotation. This annotation defines to Spring container for SQL exception translation from SQLException to Spring's data access strategy-agnostic DataAccessException hierarchy.

i.e. platform specific exceptions are catches and then re-throws as one of Spring’s unchecked data access exceptions.


Spring JDBC: For plain JDBC we use this module, which is only depends on DataSource and Template classes like JdbcTemplate, NamedParameterJdbcTemplate(wraps JdbcTemplate) and SimpleJdbcTemplate for reducing cross cutting concerns.

public class EmployeeDao {  
private JdbcTemplate jdbcTemplate;  

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
    this.jdbcTemplate = jdbcTemplate;  
}  

public int saveEmployee(Employee e){  
    return jdbcTemplate.update(query);  
}  
public int updateEmployee(Employee e){  
    return jdbcTemplate.update(query);  
}  
public int deleteEmployee(Employee e){  
       return jdbcTemplate.update(query);  
}  

}  

and in Spring XML:

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

Spring JDBC also provides JdbcDaoSupport, NamedParameterJdbcDaoSupport, SimpleJdbcDaoSupport, which are support(i.e. convenient) way to extend and develop our own DAO abstract interface as follows:

public interface EmployeeDao {

    public void saveEmployee(Employee emp);
}

public class EmployeeDaoImpl extends JdbcDaoSupport implements EmployeeDao{

    @Override
    public void saveEmployee(Employee emp) {

        Object[] inputs = new Object[] {emp.getName(), emp.getSalary(), emp.getDept()};
        getJdbcTemplate().update(query, inputs);
    }
}

and in spring XML:

<bean id="employeeDAO" class="EmployeeDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

Spring ORM: For ORM tools support such as Hibernate, JPA, MyBatis...easily integrates Spring by injecting DataSource along with following classes and respective DaoSupport classes.

  • SessionFactory for Hibernate
  • EntityManagerFactory for JPA,
  • SqlSessionFactory for MyBatis

The spring-dao lib stopped in version 2.0.8 (January 2008). The classes in spring-dao were copied to spring-tx. So, if you need a class that you find in spring-dao, add the dependency to spring-tx instead. (Source.)


You create interface like SomeObjectDao and then create different implementations of this interface like JdbcSomeObjectDao, HibernateSomeObjectDao. Then in your SomeObjectService class you will operate on the SomeObjectDao interface, and inject there one of the concrete implementations. So each implementation of SomeObjectDao will hide the details, whether you use JDBC, or ORM etc.

Usually JDBC, and different implementations of ORM throws different kind of exceptions. Spring's DAO support can map those different, technology specific exceptions to common Spring DAO exceptions. So you are decoupled more from the actual implementation. Also Spring's DAO support offers set of abstract *DataSupport classes which even more help in DAO development. So beside implementing your SomeObjectDao interface, you can extend one of Spring's *DataSupport class.


As an additional info. I suggest you use Spring Data JPA. Using anotations such as: @Repository, @Service. I show you an example:

@Repository("customerEntitlementsRepository")
public interface CustomerEntitlementsRepository extends CrudRepository<BbsExerul, BbsExerulPK> {

  @Query(value = "SELECT " + "CONTRACT_NUMBER, EXECUTIVE_NUMBER, " + "GROUP_VALUE, " + "CODE, "
      + "SUBCODE, " + "CURRENCY " + "FROM BBS_EXERUL " + "WHERE CONTRACT_NUMBER =:clientId AND "
      + "EXECUTIVE_NUMBER =:representativeId", nativeQuery = true)
  Collection<CustomerEntitlementsProjection> getFieldsExerul(@Param("clientId") String clientId,
      @Param("representativeId") String representativeId);

}

Where CustomerEntitlementsProjection is Spring projection, linked with you entity or DTO pojo;

@Projection(name = "customerEntitlementsProjection", types = { BbsExerul.class })
public interface CustomerEntitlementsProjection {

  String getContractNumber();

  String getExecutiveNumber();

참고URL : https://stackoverflow.com/questions/24990400/spring-dao-vs-spring-orm-vs-spring-jdbc

반응형