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 PersistenceAPI) 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 chargexml 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 CRUD3.JPQLRequê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 ORMImplé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 à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
@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 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 EntityManagerFactoryConfiguration. Configurez les propriétés
d'Hibernate via spring.jpa.properties.* Configuration d'EntityManagerFactoryspring.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 }
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; } }
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!