>  기사  >  Java  >  SpringBoot로 구현된 Spring Data JPA 통합 예제에 대한 자세한 설명

SpringBoot로 구현된 Spring Data JPA 통합 예제에 대한 자세한 설명

Y2J
Y2J원래의
2017-05-04 10:39:592917검색

이 글에서는 Spring Data JPA와 읽기/쓰기 분리를 통합한 SpringBoot 관련 지식을 주로 소개합니다. 필요한 친구들은

관련 코드를 참고하세요: github OSCchina

JPA란

JPA(Java Persistence API)는 Sun에서 공식적으로 제안한 Java 지속성 사양으로, Java 개발자에게 객체/association 매핑 도구는 다음과 같은 측면을 포함합니다:

1. ORM 매핑은 xml과 주석 메서드를 지원하여 엔터티와 테이블 간의 매핑을 설정합니다.

2. Java 지속성 API는 일반적으로 사용되는 일부 CRUD인터페이스를 정의하며, 기본 JDBC 및 SQL의 세부 사항을 고려하지 않고 직접 호출하기만 하면 됩니다.

3.JPQL 쿼리언어 이는 지속성 작업에서 매우 중요한 측면입니다. 프로그램의 SQL 문이 긴밀하게 결합되지 않도록 데이터베이스 지향 쿼리 언어 대신 객체 지향을 통해 데이터를 쿼리합니다.

작업에서 우리는 모두 Hibernate, JOOQ 등과 같은 ORM 기술을 사용합니다. 필요에 따라 변경해야 할 때 다른 ORM프레임워크를 사용합니다. ORM 프레임워크가 필요할 때 우리의 요구 사항을 충족하려면 구현, 사용법, 다양한 ORM 프레임워크의 차이로 인해 코드를 재구성해야 하는 경우가 많습니다. JPA의 등장은 이러한 문제를 ORM의 기존 장점 중 일부를 완전히 흡수하는 것입니다. 프레임워크의 장점은 사용하기 쉽고 다양한 ORM 프레임워크를 통합하기 위한 ORM 기술용 표준 인터페이스 세트를 제공한다는 것입니다.

Hibernate의 JPA 구현

JPA 자체는 특정 구현을 구현하지 않고 일부 인터페이스 사양만 정의하므로 다른 ORM이 이러한 인터페이스를 구체적으로 구현할 수 있습니다. 현재 JPA 사양의 가장 좋은 구현은 Hibernate입니다. 여기서 Mybatis에 대해 언급하겠습니다. Mybatis는 JPA 사양을 구현하지 않으며 자체적으로 실제 ORM 프레임워크로 간주할 수 없습니다.

Spring Data JPA란

Spring Data JPA는 JPA 사용을 크게 단순화할 수 있는 Spring Data 프레임워크의 모듈일 뿐입니다. Spring Data JPA의 장점은 지속성 계층의 이름을 표준화하여 지속성 계층 비즈니스 로직을 단순화할 수 있다는 것입니다. 구현해야 할 비즈니스 로직을 결정하기 위해 메서드와 이름을 사용하면 SQL 문장을 작성하거나 DAO 레이어 로직을 수행하지 않고도 대부분의 개발을 완료할 수 있습니다. 물론 고성능 요구 사항이 있는 일부 복잡한 쿼리의 경우입니다. , Spring Data JPA는 기본 SQL 사용도 지원합니다.

여기에서는 JPA와 Spring Data JPA에 대해 너무 많이 소개하지 않고 주로 SpringBoot 및 예제와의 통합에 대한 몇 가지 세부 사항을 소개합니다.

종속성 소개

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

이 종속성을 도입한 후 우리는 Hibernate 패키지도 도입되었음을 발견했습니다. 이는 이제 기본 Practice입니다. Hibernate는 최고의 구현으로 간주되었습니다. 여기서는 Druid 데이터 소스 구성에 대해 소개하지 않겠습니다. XXXX의 다른 기사를 읽어보세요.

Configuring our data source And JPA(Hibernate)

#配置模板
#https://docs.spring.io/spring-boot/docs/1.4.0.RELEASE/reference/html/common-application-properties.html
#数据源
spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa
spring.datasource.druid.write.username=root
spring.datasource.druid.write.password=1
spring.datasource.druid.write.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.read.url=jdbc:mysql://localhost:3306/jpa
spring.datasource.druid.read.username=root
spring.datasource.druid.read.password=1
spring.datasource.druid.read.driver-class-name=com.mysql.jdbc.Driver
#JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration)
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.database=mysql
spring.jpa.generate-ddl=true
#就是hibernate.hbm2ddl.auto,具体说明可以看README
spring.jpa.hibernate.ddl-auto=update
#通过方法名解析sql的策略,具体说明可以看README,这里就不配置了
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy
spring.jpa.show-sql=true
#spring.jpa.properties.*
#spring.jpa.properties.hibernate.hbm2ddl.auto=update
#spring.jpa.properties.hibernate.show_sql=true
#spring.jpa.properties.hibernate.use-new-id-generator-mappings=true

druid 데이터 소스 삽입

@Configuration
public class DruidDataSourceConfig {
  /**
   * DataSource 配置
   * @return
   */
  @ConfigurationProperties(prefix = "spring.datasource.druid.read")
  @Bean(name = "readDruidDataSource")
  public DataSource readDruidDataSource() {
    return new DruidDataSource();
  }
  /**
   * DataSource 配置
   * @return
   */
  @ConfigurationProperties(prefix = "spring.datasource.druid.write")
  @Bean(name = "writeDruidDataSource")
  @Primary
  public DataSource writeDruidDataSource() {
    return new DruidDataSource();
  }
}

EntityManagerFactory 인스턴스 삽입

EntityManagerFactory는 Hibernate의 SessionFactory 및 mybatis의 SqlSessionFactory와 유사합니다. 즉, 작업을 수행하기 전에 항상 Hibernate의 Session 및 mybatis의 sqlSession과 유사한 EntityManager를 얻어야 합니다. EntityManagerFactory를 주입하는 방법에는 두 가지가 있습니다. 하나는 EntityManagerFactory를 직접 주입하는 것이고, 다른 하나는 LocalContainerEntityManagerFactoryBean을 통해 간접적으로 주입하는 것입니다. . 이 두 메소드는 LocalContainerEntityManagerFactoryBean을 기반으로 하지만 여전히 구성에는 약간의 차이가 있습니다.

1. EntityManagerFactory

구성: 다음을 통해 Hibernate의 속성을 ​​구성합니다. spring.jpa.properties.* 🎜>구성:

spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use-new-id-generator-mappings=true
@Configuration
@EnableJpaRepositories(value = "com.lc.springBoot.jpa.repository",
            entityManagerFactoryRef = "writeEntityManagerFactory",
            transactionManagerRef="writeTransactionManager")
public class WriteDataSourceConfig {
  @Autowired
  JpaProperties jpaProperties;
  @Autowired
  @Qualifier("writeDruidDataSource")
  private DataSource writeDruidDataSource;
  /**
   * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory
   * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session,
   * mybatis的sqlSession.
   * @return
   */
  @Bean(name = "writeEntityManagerFactory")
  @Primary
  public EntityManagerFactory writeEntityManagerFactory() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.lc.springBoot.jpa.entity");
    factory.setDataSource(writeDruidDataSource);//数据源
    factory.setJpaPropertyMap(jpaProperties.getProperties());
    factory.afterPropertiesSet();//在完成了其它所有相关的配置加载以及属性设置后,才初始化
    return factory.getObject();
  }
  /**
   * 配置事物管理器
   * @return
   */
  @Bean(name = "writeTransactionManager")
  @Primary
  public PlatformTransactionManager writeTransactionManager() {
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    jpaTransactionManager.setEntityManagerFactory(this.writeEntityManagerFactory());
    return jpaTransactionManager;
  }
}

이 구성의 경우

spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.database=mysql
spring.jpa.generate-ddl=true
#就是hibernate.hbm2ddl.auto,具体说明可以看README
spring.jpa.hibernate.ddl-auto=update
#通过方法名解析sql的策略,具体说明可以看README,这里就不配置了
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy
spring.jpa.show-sql=true
@Configuration
@EnableJpaRepositories(value = "com.lc.springBoot.jpa.repository",
    entityManagerFactoryRef = "writeEntityManagerFactory",
    transactionManagerRef = "writeTransactionManager")
public class WriteDataSourceConfig1 {
  @Autowired
  JpaProperties jpaProperties;
  @Autowired
  @Qualifier("writeDruidDataSource")
  private DataSource writeDruidDataSource;
  /**
   * 我们通过LocalContainerEntityManagerFactoryBean来获取EntityManagerFactory实例
   * @return
   */
  @Bean(name = "writeEntityManagerFactoryBean")
  @Primary
  public LocalContainerEntityManagerFactoryBean writeEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
    return builder
        .dataSource(writeDruidDataSource)
        .properties(jpaProperties.getProperties())
        .packages("com.lc.springBoot.jpa.entity") //设置实体类所在位置
        .persistenceUnit("writePersistenceUnit")
        .build();
    //.getObject();//不要在这里直接获取EntityManagerFactory
  }
  /**
   * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory
   * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session,
   * mybatis的sqlSession.
   * @param builder
   * @return
   */
  @Bean(name = "writeEntityManagerFactory")
  @Primary
  public EntityManagerFactory writeEntityManagerFactory(EntityManagerFactoryBuilder builder) {
    return this.writeEntityManagerFactoryBean(builder).getObject();
  }
  /**
   * 配置事物管理器
   * @return
   */
  @Bean(name = "writeTransactionManager")
  @Primary
  public PlatformTransactionManager writeTransactionManager(EntityManagerFactoryBuilder builder) {
    return new JpaTransactionManager(writeEntityManagerFactory(builder));
  }
}
getObject() 메서드는 EntityManagerFactory의 인스턴스를 가져올 수 있습니다. 처음과 다르지 않은 것 같습니다. 그러나 getObject()를 직접 사용할 수는 없습니다. 그렇지 않으면 null 포인터 예외가 보고됩니다.

읽기 및 쓰기 분리 구성

AbstractRoutingDataSource의 사용자 정의 삽입

@Bean(name = "writeEntityManagerFactoryBean")
  @Primary
  public LocalContainerEntityManagerFactoryBean writeEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
    return builder
        .dataSource(writeDruidDataSource)
        .properties(jpaProperties.getProperties())
        .packages("com.lc.springBoot.jpa.entity") //设置实体类所在位置
        .persistenceUnit("writePersistenceUnit")
        .build();
    //.getObject();//不要在这里直接获取EntityManagerFactory
  }
사용자 정의 주석
@Configuration
public class DataSourceConfig {
  private final static String WRITE_DATASOURCE_KEY = "writeDruidDataSource";
  private final static String READ_DATASOURCE_KEY = "readDruidDataSource";
  /**
   * 注入AbstractRoutingDataSource
   * @param readDruidDataSource
   * @param writeDruidDataSource
   * @return
   * @throws Exception
   */
  @Bean
  public AbstractRoutingDataSource routingDataSource(
      @Qualifier(READ_DATASOURCE_KEY) DataSource readDruidDataSource,
      @Qualifier(WRITE_DATASOURCE_KEY) DataSource writeDruidDataSource
  ) throws Exception {
    DynamicDataSource dataSource = new DynamicDataSource();
    Map<Object, Object> targetDataSources = new HashMap();
    targetDataSources.put(WRITE_DATASOURCE_KEY, writeDruidDataSource);
    targetDataSources.put(READ_DATASOURCE_KEY, readDruidDataSource);
    dataSource.setTargetDataSources(targetDataSources);
    dataSource.setDefaultTargetDataSource(writeDruidDataSource);
    return dataSource;
  }
}

ThreadLocal을 사용하여 데이터 소스를 스레드에 바인딩

  @Target({ElementType.METHOD, ElementType.TYPE})
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  public @interface TargetDataSource {
    String dataSource() default "";//数据源
  }
측면 정의아아아

위 내용은 SpringBoot로 구현된 Spring Data JPA 통합 예제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.