使用阿帕奇骆驼的春季数据


Spring Data通过创建无需编写任何代码就可以免费获得的智能Dao,为您节省了大量时间。它基本上遵循Repository PatternEric Evans’ DDD book并将实体视为集合。它有一个很好的约定,允许您为复杂的查询指定条件,甚至利用JPA Criteria API或者QueryDSL fluent APIs对于更复杂的查询/规范。最棒的部分是抽象不仅适用于JPA,而且many other providers。有some great examples在春季生态系统中使用春季数据,如Spring Boot但是有时候你想在魔法世界之外使用它。

如果您正在进行任何认真的系统集成,您可能也在使用Apache Camel,所以在下面的快速博客(承诺)中,我将向您展示与Camel一起使用时需要的突出部分…但是,这里没有什么特别的。我们基本上解构了Spring Boot为您带来的一些魔力,并允许您理解必要的组成部分(如果运行Tomcat、Dropwizard、Wildfly或任何容器,这是真的)。

这方面的示例代码是located here at my github for some code we were working on

第一步,您需要JPA和spring数据依赖关系!

<!-- spring data + JPA -->
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-jpa</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
  <groupId>org.hibernate.javax.persistence</groupId>
  <artifactId>hibernate-jpa-2.1-api</artifactId>
  <version>1.0.0.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>${hibernate.version}</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>${hibernate.version}</version>
</dependency>

这将为我们准备类路径,它应该包括一个JPA API和我们将使用的提供者的实体管理器。

接下来,我们应该向spring上下文/bean工厂添加以下内容:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
  <property name="url" value="jdbc:derby:memory:orders;create=true"/>
  <property name="username" value=""/>
  <property name="password" value=""/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="persistenceXmlLocation" value="classpath:/META-INF/persistence.xml"/>
  <property name="persistenceUnitName" value="sample"/>
  <!-- spring based scanning for entity classes>-->
  <property name="packagesToScan" value="org.jboss.fuse.examples.rest"/>
</bean>

<bean id="transactionManager"
      class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory"/>
  <property name="dataSource" ref="dataSource"/>
</bean>

这就是全部run of the mill Spring ORM stuff;这里没有什么特别的,但是这是spring-data需要的样板材料。

要使用JPA,我们还需要一个persistence.xml文件。如果您想使用Mongo或其他东西,请参考特定的spring-data mdoule了解如何使用它。

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
  <persistence-unit name="sample">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect"/>
    </properties>
  </persistence-unit>
</persistence>

这应该给我们使用春季数据的基础!现在,让我们做一些有趣的事情。我们将添加一个存储库,允许我们进行CRUD操作(等等!)对照数据库:

package org.jboss.fuse.examples.repositories;

import org.jboss.fuse.examples.rest.Organization;
import org.springframework.data.repository.PagingAndSortingRepository;

/**
 * Created by ceposta 
 * <a href="http://christianposta.com/blog>http://christianposta.com/blog</a>.
 */
public interface OrganizationRepository extends PagingAndSortingRepository<Organization, Integer> {

}

我们有自己的存储库,但是我们需要告诉spring如何找到它并应用一些魔法。因此,让我们像这样将其添加到spring上下文中(并让spring扫描一个包来发现存储库)

<jpa:repositories base-package="org.jboss.fuse.examples.repositories"/>

注意,这将需要适当的名称空间(假设我们使用的是spring XML配置;也支持java配置,但这里没有显示):

<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"
       xsi:schemaLocation="
          http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

现在,让我们将我们的存储库注入到我们自己的POJO类中,从中我们可以使用它!哇,哇…“我们实际上还没有写任何代码来实现这个存储库”你说…是的,这是真的!Spring-data为我们这么做!

让我们注入:

<bean id="orgCollection" class="org.jboss.fuse.examples.rest.OrganizationCollection">
  <property name="repository" ref="organizationRepository"/>
</bean>

请注意存储库的名称organizationRepository是spring在扫描包中的存储库时按照约定创建的,但是我们仍然可以像bean工厂中的任何其他spring bean一样获得并使用它。现在,让我们使用这个包装类(OrganizationCollection在这种情况下)在我们的骆驼路线中:

<route id="findAll">
  <from uri="direct:findAll"/>
  <bean ref="orgCollection" method="findAll"/>
</route>


<route id="orgById">
  <from uri="direct:orgById"/>
  <bean ref="orgCollection" method="findById"/>
</route>

<route id="paginate">
  <from uri="direct:paginate"/>
  <bean ref="orgCollection" method="findOrganizationWithPagination"/>
</route>

酷!我们有3条单独的路线使用我们的orgCollection pojo(它又使用利用spring-data的organizationRepository)。让我们看看那个POJO:

package org.jboss.fuse.examples.rest;

import org.apache.camel.Header;
import org.apache.camel.language.Simple;
import org.jboss.fuse.examples.repositories.OrganizationRepository;
import org.springframework.data.domain.PageRequest;


public class OrganizationCollection {

    private OrganizationRepository repository;


    public Organization insertNewOrganization(@Simple("body.org_id") Integer id, @Simple("body.org_name") String name) {
        Organization org = new Organization(id, name);
        return repository.save(org);
    }

    public Iterable<Organization> findAll(){
        return repository.findAll();
    }

    public Iterable<Organization> findOrganizationWithPagination(@Header("pageNumber")int pageNum, @Header("pageSize")int size){
        return repository.findAll(new PageRequest(pageNum, size));
    }

    public Organization findById(@Header("id")int id) {
        return repository.findOne(id);
    }

    public OrganizationRepository getRepository() {
        return repository;
    }


    public void setRepository(OrganizationRepository repository) {
        this.repository = repository;
    }
}

我们注射了OrganizationRepository并在这里使用它来查询数据存储。请注意,参数有Apache Camel从标题和正文中提取值用作参数的注释。