Maison >Java >javaDidacticiel >Explication détaillée d'exemples d'intégration Spring Data JPA implémentés par SpringBoot

Explication détaillée d'exemples d'intégration Spring Data JPA implémentés par SpringBoot

Y2J
Y2Joriginal
2017-05-04 10:39:593023parcourir

Cet article présente principalement les connaissances pertinentes de SpringBoot intégrant Spring Data JPA et la séparation en lecture et en écriture. Les amis dans le besoin peuvent se référer au

code associé : github OSCchina

<.>Qu'est-ce que JPA

JPA (Java Persistence

API) est la spécification de persistance Java officiellement proposée par Sun, qui fournit aux développeurs Java un Objet/outil de mappage d'association pour gérer les données relationnelles dans les applications Java. Il comprend les aspects suivants :

1. Le mappage ORM prend en charge

xml et les méthodes d'annotation pour établir le mappage d'entités et de tables entre.

2. L'API de persistance Java définit certaines CRUD

interfaces couramment utilisées, qu'il suffit d'appeler directement sans tenir compte des détails du JDBC et du SQL sous-jacents.

3.JPQL

RequêteLangage Il s'agit d'un aspect très important dans les opérations de persistance. Interrogez les données via Orienté objet au lieu d'un langage de requête orienté base de données pour éviter que les instructions SQL du programme ne soient étroitement couplées.

Dans notre travail, nous utilisons tous des technologies ORM, telles que Hibernate, JOOQ, etc. En fonction des besoins, nous utiliserons différents ORM

frameworks lorsque nous aurons besoin de changer Quand le framework ORM répond à nos besoins, nous avons souvent besoin de reconstruire le code en raison des différences dans la mise en œuvre, l'utilisation et les différences des différents frameworks ORM. L'émergence de JPA est de résoudre ce problème en absorbant pleinement certains des avantages existants de l'ORM. framework sont faciles à utiliser et très évolutifs. Il fournit un ensemble d'interfaces standard pour la technologie ORM afin d'intégrer différents frameworks ORM.

Implémentation de JPA par Hibernate

JPA lui-même n'implémente pas d'implémentations spécifiques, mais définit uniquement certaines spécifications d'interface, permettant à

d'autres ORM d'implémenter ces interfaces spécifiquement. Pour l'instant, la meilleure implémentation de la spécification JPA est Hibernate. ici, Mybatis n'implémente pas la spécification JPA, et elle ne peut pas être considérée comme un véritable framework ORM

Spring Data JPA Qu'est-ce que Spring Data JPA n'est qu'un module du framework Spring Data, qui peut grandement simplifier l'utilisation de JPA. La puissance de Spring Data JPA est qu'il peut simplifier notre logique métier de couche de persistance en standardisant les noms des méthodes de couche de persistance et en utilisant le. noms pour déterminer quelle logique métier doit être implémentée, nous avons la possibilité de terminer la plupart de notre développement sans écrire une phrase SQL ni faire de logique de couche DAO. Bien sûr, pour certaines requêtes complexes avec des exigences de performances élevées, Spring Data JPA. nous aide également à utiliser SQL natif.

Ici, nous n'introduireons pas grand-chose sur JPA et Spring Data JPA, principalement quelques détails d'intégration avec SpringBoot et Sample.

Présentation de la dépendance

Après avoir introduit cette dépendance, nous avons constaté que le package Hibernate a également été introduit, qui est maintenant un L'approche par défaut est qu'Hibernate a été considéré comme la meilleure implémentation de la spécification JPA. La configuration de la source de données Druid ne sera pas présentée ici. Vous pouvez lire un autre article XXXX.
<!-- 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>

Configuration de notre source de données et 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
Injection de source de données 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();
  }
}
Injection d'instance EntityManagerFactory

EntityManagerFactory est similaire à SessionFactory d'Hibernate et SqlSessionFactory de mybatis. En bref, avant d'effectuer une opération, nous devons toujours obtenir un EntityManager, qui est similaire à la Session d'Hibernate et à la sqlSession de mybatis. Il existe deux façons d'injecter EntityManagerFactory, l'une consiste à injecter directement EntityManagerFactory et l'autre. L'autre consiste à injecter indirectement via LocalContainerEntityManagerFactoryBean Bien que ces deux méthodes soient basées sur LocalContainerEntityManagerFactoryBean, il existe encore quelques différences dans la configuration

1. Injectez directement EntityManagerFactory

Configuration. Configurez les propriétés

d'Hibernate via spring.jpa.properties.* Configuration d'EntityManagerFactory

 :

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;
  }
}

Pour cette configuration, le

getObject () peut obtenir une instance de EntityManagerFactory, qui semble être la même que la première. Il n'y a pas de différence, mais nous ne pouvons pas utiliser getObject() directement, sinon nous ne pourrons pas l'obtenir, et une exception de pointeur nul le fera être signalé.

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));
  }
}

Configuration de séparation en lecture-écriture

@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
  }

Injection personnalisée de AbstractRoutingDataSource

Annotation personnalisée.

@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;
  }
}
Utilisez ThreadLocal pour lier la source de données au fil

Définir les aspects
  @Target({ElementType.METHOD, ElementType.TYPE})
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  public @interface TargetDataSource {
    String dataSource() default "";//数据源
  }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn