Spring Data JPA basic learning

Last time I wrote about JPA, let's talk about Spring Data JPA

Spring Data JPA is a set of JPA application framework encapsulated by spring based on ORM framework and JPA specification. Developers can use very simple code to access and operate the database.

In daily use, Spring Data JPA development frees us from the operation of Dao layer, and basically all cruds can be implemented using it; Its simple way is that when we write code, we only need to implement two interfaces in the Dao layer. The JPA framework has encapsulated the methods for me to use directly.

Features of Spring Data JPA:

  • Provides a unified interface, and we will not duplicate sql
  • We can automatically generate sql statements by method names
  • The implementation class is automatically injected through the interface, and the implementation is very simple
  • Follow the database specification and access the database flexibly

I learned about Spring Data JPA, JPA and Hibernate, but what is the relationship between them:

As we said earlier, JPA is a set of specifications, which is completed by interfaces and abstract classes. Hibernate is a mature ORM framework and implements JPA specifications. Programming with JPA API means that we deal with problems at the change level and directly deal with interface oriented programming through interfaces; Spring Data JPA encapsulates JPA in a higher step and is a solution for data persistence under the JPA specification.

To use Spring Data JPA, you need to build its environment, integrate Spring and Spring Data JPA, implement Hibernate dependency, and be database driven.

Environment configuration

The things we need to configure are as follows

  1. Operation database: configuration database information is a necessary DataSource
  2. During JPA, there is an EntityManagerFactory that operates JPA, so the entity management factory object EntityManagerFactory is required
    1. Scanned package, database, JPA implementation, JPA implementation adapter
  3. The transaction is configured using JPA's transaction manager, JPA transaction manager
  4. Spring needs to scan entity object scanning package context component scan
  5. Spring transactions: declarative or programmatic tx
  6. Finally, you need to integrate the configured into jpa: repositories in Spring Data JPA
<!--Database configuration-->
<bean id="ds" class="xxxDataSource">
  <property name="url" value=""></property>
  <property name="Driver" value=""></property>
  <property name="username" value=""></property>
  <property name="password" value=""></property>

<!--EntityManagerFactory to configure-->
<bean id="MyEntitiManagerFactory" class="xxx.LocalContainerEntityManagerFactoryBean">
  <proerty name="dataSource" ref="ds"></proerty>
  <!--Scanned packages-->
  <proerty name="PageToScan" value="xxx.xxx.model"></proerty>
  <!--JPA Implementation of-->
  <proerty name="persistenceProvicer">
  	<bean class="xxx.HibernatePersistenceProvider"></bean>
  <!--Adapter for implementation-->
  <proerty name="jpaVendorAdapter">
    <bean class="xxx.HibernateJpaVendorAdapter">
      	<!--Create table-->
    		<property name="GenerateDdl" value=""></property>
        <!--Database configuration used-->
        <property name="database" value=""></property>
        <!--Database dialect-->
        <property name="databasePlatform" value="MySQLDialect"></property>
        <!--Show sql sentence-->
      	<property name="showSql" value=""></property>
  <!--JPA Advanced feature support for Hibernate of-->
  <property name="jpaDialect">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

<!--JPa Transaction manager for-->
<bean id="JpaTranscationManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="MyEntitiManagerFactory"></property>

<!--Spring Annotation scanned package-->
<context:component-scan base-package="xxxx"></context:component-scan>

<!--Spring affair-->

<!--integration Spring Data JPa-->
<jpa:repositories base-package="xxx" tansaction-manager-ref="JpaTranscationManager" entity-manager-factory-ref="MyEntitiManagerFactory"></jpa:repositories>

Implement value capitalization of party database

I don't think it's necessary to memorize all the configurations if you can understand them,

Let's take a look at how Spring Data JPA frees up our Dao layer

To use Spring Data JPA, you only need to write an interface that conforms to the specification. There are two requirements

  1. Create a Dao interface and implement the jpaspecification executor interface and the jpaspecification executor interface
  2. Provide corresponding generics
 * Spring Data JPA Specification for writing Dao layer
 *      Inherit two interfaces
 *             JpaRepository: Encapsulates the basic CRUD operations
 *                  Entity class
 *                  Type of corresponding primary key
 *             JpaSpecificationExecutor: Encapsulates complex operations (paging queries, etc.)
 *                  Entity class
public interface StudentDao extends JpaRepository<Student,Long>, JpaSpecificationExecutor<Student>{

Then you can get the bean object directly from the container

You can see that we have encapsulated basic methods without writing any methods

Next, let's see why it is so convenient. In fact, the methods in the two interfaces we implement can be traced back to the top-level interface CrudRepository

And jpaspecification executor
The method has been encapsulated

Analysis of the running process of Spring Data JPA

It is found that the bean object injected at this time is a proxy object, which is essentially a proxy object generated through jdkddynamicaaopproxy

Let's enter this object to see:

It is mainly the invoke method. Currently, the targetSource is a SimpleJpaRepository object,

Entering the method is actually calling the em.find method

em is the EntityManager entity manager

Therefore, we come to the conclusion that Spring Data JPA only further encapsulates the standard JPA operation and simplifies the development of Dao layer code

CRUD of Spring Data JPA is basically the same as that of JPA

  • The save method is a save or update method, and the judgment basis is whether there is an id
    With id: update operation, query first and then update
    No id: save operation

  • getOne uses the getReference method of JPA
    findOne uses the findOne method of JAP

  • delete queries and deletes them

Take a look at the JPQL query language of Spring Data JPA

Use @ Query annotation

  • value is: JPQL statement

  • nativeQuery: whether to use local sql query. Default false is to use JPQL; true is to query using sql statements

for instance:

//Or use objects instead of database tables
@Query(value = "from Student where stutName = ? ")
public Student findByName(String name);
//Multiple placeholder settings? 1 represents the placeholder for the parameter, where 1 corresponds to the parameter index in the method
//   Either write sequentially or match according to the placeholder array
@Query(value="from Student where stuName = ?2 and stuAge = ?1")
public Student findByNameAndAge(Integer age,String name);

If the update operation is required, it must be accompanied by the annotation @ Modifying

@Query(value = "update Student set stuId = ?2 where stuName = ?1")
public void updateById(String name,Long id);

The annotation @ Transaction and @ Rollback (false) of the Transaction need to be added to the test class

Spring data JPA executes jqpl statements. After updating or deleting, the default transaction is rolled back, and @ Rollback (value=false) needs to be added

If you want to use sql query, you need @ query annotation (value = "sql", nativeQuery=true)

In addition, Spring Data JPA has another query method that can be customized: Method naming rule query. As the name suggests, you can execute the query statement by performing the corresponding query according to the method name and writing the method name according to the rules.

When the query method starts with findBy and involves conditional query, the condition attributes are connected with condition keywords. Note that the initial letter of the condition attribute should be capitalized. When the framework resolves the method name, it first intercepts the redundant prefix of the method name, and then resolves the rest.

For example:

public Student findByStuName(String stuName);//Query by stuName
public Student findByStuNameLike(String stuName);//Fuzzy query
public Student findByStuNameLikeAndStuClassAndStuAge(String stuName,String stuClass,String stuAge);//Multi condition query

The specific keywords, usage and production into SQL are shown in the following table

IgnoreCasefindByFirstnameIgnoreCase... where UPPER(x.firstame) = UPPER(?1)
AndfindByLastnameAndFirstname... where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname... where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstnameIs,findByFirstnameEquals... where x.firstname = ?1
BetweenfindByStartDateBetween... where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan... where x.age < ?1
LessThanEqualfindByAgeLessThanEqual... where x.age ⇐ ?1
GreaterThanfindByAgeGreaterThan... where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual... where x.age >= ?1
AfterfindByStartDateAfter... where x.startDate > ?1
BeforefindByStartDateBefore... where x.startDate < ?1
IsNullfindByAgeIsNull... where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull... where x.age not null
LikefindByFirstnameLike... where x.firstname like ?1
NotLikefindByFirstnameNotLike... where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith... where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith... where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining... where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc... where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot... where x.lastname <> ?1
InfindByAgeIn(Collection ages)... where x.age in ?1
NotInfindByAgeNotIn(Collection age)... where x.age not in ?1
TRUEfindByActiveTrue()... where x.active = true
FALSEfindByActiveFalse()... where x.active = false

Tags: Database Hibernate Spring jpa

Posted on Fri, 03 Dec 2021 00:30:55 -0500 by beesgirl713