preface

Spring Data JPA is part of the Sping ecosystem bucket created by the Spring team. Its kernel uses Hibernate core source code, and it is a good choice as a sample to understand the basic structure of the Java persistence layer framework. Recently, I built a demo project to read the source code of Spring Data JPA, which will be helpful for macro understanding of the basic work of the persistence layer framework, micro analysis of the principle and advantages and disadvantages of Spring Data JPA, and avoiding pit mining in the process of use.Copy the code

Construction of capital works

The use of Spring Data JPA needs to rely on the Web framework, the simplest and fastest way is to use https://start.spring.io/ to build a Spring Boot project containing Spring Data JPA, Simply select the Spring Data Jpa and Driver for the response database in the menu of the corresponding SQL for boot, which is currently supported by both Idae and Eclipse. The essence of the above method is to add dependencies to the pom.xml of the resulting Spring Boot project, so you can also generate a Maven-managed Spring Boot project directly, and then in pom.xml: <? The XML version = "1.0" encoding = "utf-8"? > < project XMLNS = "http://maven.apache.org/POM/4.0.0" XMLNS: xsi = "http://www.w3.org/2001/XMLSchema-instance" Xsi: schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion > 4.0.0 < / modelVersion > < the parent > < groupId > org. Springframework. Boot < / groupId > The < artifactId > spring - the boot - starter - parent < / artifactId > < version > 2.1.8. RELEASE < / version > < relativePath / > <! -- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>jpademo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>jpademo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> < plugin > < groupId > com. Mysema. Maven < / groupId > < artifactId > apt - maven - plugin < / artifactId > < version > 1.1.3 < / version > <executions> <execution> <goals> <goal>process</goal> </goals> <configuration> <outputDirectory>target/generated-sources/apt</outputDirectory> <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor> </configuration> </execution> </executions> </plugin>  </plugins> </build> </project>Copy the code

Where, spring-boot-starter-web is the spring Boot framework dependency, spring-boot-starter-data-jPA is the Spring data JPA dependency, I use Mysql database, So mysql-connector-Java was introduced. Querydsl-jpa and QueryDsl-APT are dependencies that use QueryDSL on top of JPA and may not be introduced. Finally lombok’s widely used lazy cancer toolkit. The next step, of course, is to build a data source. You need to install mysql locally, which I won’t go into. Create a test database, create a song table, create a song table:

CREATE TABLE `song` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(10) DEFAULT NULL, `year` int(11) DEFAULT NULL, `length` int(11) DEFAULT NULL, `type` varchar(64) DEFAULT NULL, PRIMARY KEY (' id ')) then set the database configuration in the application.properties project: Datasource. Driver-class-name = com.mysql.cj.jdbc.driver spring.datasource.url=jdbc:mysql://localhost:3306/test? UseSSL = false&allowPublicKeyRetrieval = true spring. The datasource. The username = root spring. The datasource. The password = 123456 # jpa configuration spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=updateCopy the code

Spring.jpa.hibernate.dcl-auto is one of the most interesting configurations that can lead to disastrous repository deleters if you’re not careful.

  • Create: Each time you run this program, no tables are created and the data in the table is cleared.
  • Create-drop: Clears the table at the end of each program.
  • Update: Each time you run the program, no new table is created, and the data in the table is not cleared, but only updated
  • Validate: The running program verifies whether the data and database field types are the same

The presence or absence of a table is based on the Entity Entity configured in the application, which means that the application can influence the creation and structure of the table based on its Entity Entity. Do not configure create as a sentence. Finally, you need to configure Entity and Entity Repository in your application. The overall file structure of the project directory is as follows:Among them:

  • JpademoApplication. Java: spring boot entry application
  • Testcontroller.java: Controller interface for testing
  • Song-java: Entity class corresponding to the Song table
  • SongRepository: Repository interface corresponding to the entity class Song

Definition of Song entity:

@entity // define Entity class @table (name = "song") // map Table configuration @dynamicinsert // support DynamicInsert @dynamicupdate // support DynamicUpdate // @constructor @noargsconstructor public class Song {@id // constructor @generatedValue;  private String name; private Integer year; private Integer length; private String type; }Copy the code

The Jpa Entity corresponds to the persistence layer table data, and the definition of Song Entity corresponds to the Song table in the local mysql data test library. Adding, deleting, modifying, and querying table data can be implemented by using Repository.

public interface SongRepository extends JpaRepository<Song,Integer>{
    Song findById(Long id);

    Song getById(Long id);

    Song queryByIdAndYear(Long id, Long year);

    void deleteById(Long id);
}
Copy the code

SongRepository inherits the JpaRepository interface and implements methods such as save(S Entity), findAll(), Count (), and Delete (T Entity) by default. Subclasses can also use names to extend the ability to customize new queries or other ways to manipulate data, such as find, GET, Query By ID, or IdAndYear, which I defined above. While it may seem silly to use names to extend a new operational data interface, it’s worth exploring how it works.

The basic use

To understand the basic principle of a thing, we first need to fully understand the external function of the thing. For spirng Data JPA, the main data manipulation methods are using Repository and EntityManager. @Slf4j @RestController public class TestController { @Resource private EntityManager entityManager; @Resource private SongRepository songRepository; @GetMapping("/") public List<Song> test() { return repositoryList(); } public List<Song> Repository () {//Repository <Song> songs = songrepository.findall (); return songs; } @Transactional public void repositorySave() { Song song = new Song(); song.setName("MyHeart"); song.setLength(230); song.setYear(2020); songRepository.save(song); } @transactional public void entityManagerMerge() {// entityManagerMerge = new Song(); song = new Song(); song.setName("Journey"); song.setLength(230); song.setYear(2020); entityManager.merge(song); } public List < Song > hqlList () {/ / way HQL Query Query = entityManager. CreateQuery (" select s as ss from Song s "); List<Song> songs = query.getResultList(); return songs; {} public List < Song > sqlList ()/way/SQL Query nativeQuery = entityManager. CreateNativeQuery (" select * from Song s the where name LIKE 'MyHeart'"); List<Song> songs = nativeQuery.getResultList(); return songs; }}Copy the code

Repository provides standard Crud interfaces as well as support for custom interfaces that follow canonical naming standards, as described above. The EntityManager approach, which is the underlying implementation of Repository, provides the ability to create CriteriaQueries (not shown above), HQL Queries, SQL Queries, and ultimately to interact with the database. As shown in the preceding example, THE HQL format is similar to THAT of SQL, except that THE HQL uses object-oriented encapsulation in the “Select S as SS from Song S” statement. Song corresponds to the entity Song instead of the table name. Native NativeQuery corresponds to native Sql queries. In addition, Repository also provides informally named interface queries that are essentially HQL and SQL using EntityManager. You can use the @Query annotation on the Repository interface method and define the corresponding HQL or SQL statement. The Query conditions must be consistent with the input parameters of the interface method, and the Query results must correspond to the return parameters of the interface method. In fact, spring Data JPA provides a basic idea for SQL evolution from SQL to HQL to Repository for combined entities. However, entities are difficult to solve the join problem of relational database table data. In Java Database Persistence Layer Framework Basics: Why not JPA? In this article, I mentioned that you can use querydsl to solve the syndication problem, but spring data jpa actually has its own solution, which is to define a collection of maps in a single entity. To put it simply, suppose that a table corresponds to an entity class named Person, which contains a collection property called Head, which corresponds to data in another table. Used in the Person entity

 @JoinTable(name = "head", joinColumns = { @JoinColumn(nullable = false, name = "item_id", referencedColumnName = "id") })
Copy the code

Implement syntables. But this approach has complex cascades that are extremely difficult to handle in update, insert, and delete operations.

Author: Sun Xin [Didi Chuxing Software Development Engineer]

  • If you register with Didi Cloud now, you will get 10,000 yuan in red envelopes
  • Special offer in August, 1C2G1M cloud server 9.9 yuan/month limited time grab
  • Didi Cloud messenger exclusive special benefits, including annual cloud server as low as 68 yuan/year
  • Enter master code [7886] to get a 10% discount for all GPU products