


This article mainly introduces the relevant knowledge of SpringBoot integrating Spring Data JPA and reading and writing separation. Friends in need can refer to the
related code: github OSCchina
What is JPA
JPA (Java Persistence API) is the Java persistence specification officially proposed by Sun, which provides a for Java developers Object/association mapping tool to manage relational data in Java applications. It includes the following aspects:
1. ORM mapping supports xml and annotation methods to create entities and tables Mapping between.
2. Java persistence API defines some commonly used CRUD interfaces, we only need to call them directly without considering the details of the underlying JDBC and SQL.
3.JPQLQuery Language This is a very important aspect in persistence operations. Query data through Object-oriented rather than database-oriented query language to avoid program SQL Statements are tightly coupled.
In our work, we all use ORM technologies, such as Hibernate, JOOQ, etc. Depending on the needs, we will use different ORMframeworks. When we need to change When the ORM framework meets our needs, we often need to reconstruct the code due to the implementation, usage, and differences of different ORM frameworks. The emergence of JPA is to solve this problem. JPA fully absorbs some of the existing The advantages of the ORM framework are that it is easy to use and has strong scalability. It provides a set of standard interfaces for ORM technology to integrate different ORM frameworks.
Hibernate's implementation of JPA
JPA itself does not implement specific implementations, but only defines some interface specifications, allowing otherORMs to implement these interfaces specifically. For now, The best implementation of the JPA specification is Hibernate. Let me mention Mybatis here. Mybatis does not implement the JPA specification, and it itself cannot be regarded as a real ORM framework.
Spring Data JPA What is
Spring Data JPA is just a module of the Spring Data framework, which can greatly simplify the use of JPA. The power of Spring Data JPA is that it can simplify our persistence layer business logic. By standardizing the names of persistence layer methods and using the names to determine what business logic needs to be implemented, we have the opportunity to complete most of our development without writing a sentence of SQL or doing any DAO layer logic. Of course, for For some complex queries with high performance requirements, Spring Data JPA also supports us to use native sql.
Here we will not introduce too much about JPA and Spring Data JPA, mainly some details of integration with SpringBoot and Example.
Introducing dependencies
<!-- 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>
After we introduced this dependency, we found that the Hibernate package was also introduced, which is now the default Practice, Hibernate has been regarded as the best implementation of the JPA specification. I will not introduce the configuration of the Druid data source here. You can read another article 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 data source injection
@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 instance injection
EntityManagerFactory is similar to Hibernate's SessionFactory and mybatis's SqlSessionFactory. In short, before performing an operation, we always need to obtain an EntityManager, which is similar to Hibernate's Session and mybatis's sqlSession. There are two ways to inject EntityManagerFactory, one is to directly inject EntityManagerFactory, The other is to inject indirectly through LocalContainerEntityManagerFactoryBean. Although both methods are based on LocalContainerEntityManagerFactoryBean, there are still some differences in configuration.
1. Directly inject EntityManagerFactory
Configuration: Configure Hibernate's properties through 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; } }
2. First inject LocalContainerEntityManagerFactoryBean, and then obtain EntityManagerFactory
Configuration:
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)); } }
For this configuration
@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 }
getObject() method can get an instance of EntityManagerFactory, which seems to be no different from the first one, but we cannot use getObject() directly , otherwise it will not be obtained and a null pointer exception will be reported.
Read-write separation configuration
Custom injection AbstractRoutingDataSource
@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; } }
Custom annotations
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TargetDataSource { String dataSource() default "";//数据源 }
Use ThreadLocal to bind the data source to the thread
public class DynamicDataSourceHolder { //使用ThreadLocal把数据源与当前线程绑定 private static final ThreadLocal<String> dataSources = new ThreadLocal<String>(); public static void setDataSource(String dataSourceName) { dataSources.set(dataSourceName); } public static String getDataSource() { return (String) dataSources.get(); } public static void clearDataSource() { dataSources.remove(); } } public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { //可以做一个简单的负载均衡策略 String lookupKey = DynamicDataSourceHolder.getDataSource(); System.out.println("------------lookupKey---------"+lookupKey); return lookupKey; } }
Define aspects
@Aspect @Component public class DynamicDataSourceAspect { @Around("execution(public * com.lc.springBoot.jpa.service..*.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable { MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); Method targetMethod = methodSignature.getMethod(); if (targetMethod.isAnnotationPresent(TargetDataSource.class)) { String targetDataSource = targetMethod.getAnnotation(TargetDataSource.class).dataSource(); System.out.println("----------数据源是:" + targetDataSource + "------"); DynamicDataSourceHolder.setDataSource(targetDataSource); } Object result = pjp.proceed();//执行方法 DynamicDataSourceHolder.clearDataSource(); return result; } }
The above is the detailed content of Detailed explanation of examples of Spring Data JPA integration implemented by SpringBoot. For more information, please follow other related articles on the PHP Chinese website!

选择JPA还是MyBatis取决于具体需求和偏好。JPA和MyBatis都是Java持久层框架,都提供了将Java对象与数据库表进行映射的功能。如果需要一个成熟的、支持跨数据库操作的框架,或者项目已经采用了JPA作为持久层解决方案,继续使用JPA可能是一个更好的选择。如果要更高的性能和更灵活的SQL编写能力,或者正在寻找一个对数据库依赖性较小的解决方案,MyBatis更适合。

JPA和MyBatis:功能与性能对比分析引言:在Java开发中,持久化框架扮演着非常重要的角色。常见的持久化框架包括JPA(JavaPersistenceAPI)和MyBatis。本文将对这两个框架的功能和性能进行对比分析,并提供具体的代码示例。一、功能对比:JPA:JPA是JavaEE的一部分,提供了一种面向对象的数据持久化解决方案。它通过注解或X

一、@RequestParam注解对应的axios传参方法以下面的这段Springjava代码为例,接口使用POST协议,需要接受的参数分别是tsCode、indexCols、table。针对这个Spring的HTTP接口,axios该如何传参?有几种方法?我们来一一介绍。@PostMapping("/line")publicList

什么是JPA?它与JDBC有什么区别?JPA(JavaPersistenceapi)是一个用于对象关系映射(ORM)的标准接口,它允许Java开发者使用熟悉的Java对象来操作数据库,而无需编写直接针对数据库的sql查询。而JDBC(JavaDatabaseConnectivity)是Java用于连接数据库的标准API,它需要开发者使用SQL语句来操作数据库。JPA将JDBC封装起来,为对象-关系映射提供了更方便、更高级别的API,简化了数据访问操作。在JPA中,什么是实体(Entity)?实体

在Java编程领域,JPA(JavaPersistenceapi)作为一种流行的持久化框架,为开发者提供了对关系型数据库进行操作的便捷方式。通过使用JPA,开发者可以轻松地将Java对象持久化到数据库中,并从数据库中检索数据,从而极大地提高了应用程序的开发效率和维护性。本文精心挑选了10个高质量的JavaJPA开源项目,涵盖了各种不同的功能和应用场景,旨在为开发者提供更多的灵感和解决方案,助力打造更高效和可靠的应用程序。这些项目包括:SpringDataJPA:springDataJPA是Spr

1.Spring项目的创建1.1创建Maven项目第一步,创建Maven项目,Spring也是基于Maven的。1.2添加spring依赖第二步,在Maven项目中添加Spring的支持(spring-context,spring-beans)在pom.xml文件添加依赖项。org.springframeworkspring-context5.2.3.RELEASEorg.springframeworkspring-beans5.2.3.RELEASE刷新等待加载完成。1.3创建启动类第三步,创

springbootjpa延迟加载问题在springboot中,在application.properties的配置文件中新增spring.jpa.open-in-view=true方法失效经过测试,有两种解决办法:1、在application.properties的配置文件中新增spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true;2、在测试的方法上添加@Transactional注解。关于springboot延迟加载懒加

SpringBean的生命周期管理一、SpringBean的生命周期通过以下方式来指定Bean的初始化和销毁方法,当Bean为单例时,Bean归Spring容器管理,Spring容器关闭,就会调用Bean的销毁方法当Bean为多例时,Bean不归Spring容器管理,Spring容器关闭,不会调用Bean的销毁方法二、通过@Bean的参数(initMethod,destroyMethod)指定Bean的初始化和销毁方法1、项目结构2、PersonpublicclassPerson{publicP


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SublimeText3 Linux new version
SublimeText3 Linux latest version

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 English version
Recommended: Win version, supports code prompts!
