How does Spring Data JPA easily achieve data persistence?

Spring Data JPA is a popular Java persistence framework that provides a simple, consistent and easy-to-use way to access various databases in Java applications. Due to its simplicity and powerful features, it has become the framework of choice for many developers. By using Spring Data JPA, developers can develop applications faster, reduce the amount of code, and improve code readability and maintainability. This article will introduce the basic concepts and usage of Spring Data JPA, and provide a complete example to help you better understand its usage and advantages.

What is Spring Data JPA

Spring Data JPA is a sub-project of the Spring Framework that provides an easy-to-use way to access data from various relational databases. It simplifies the complexity of database access by combining the powerful functions of JPA (Java Persistence API) and Spring Framework, and provides many features and tools, such as annotation-based Repository model, automated query, paging and sorting support, complex Check DSL etc.

The history of Spring Data JPA can be traced back to 2011, when SpringSource (the development company of Spring Framework) released a project called "Spring Data JPA" to help developers better utilize the JPA specification for data persistence. Since then, the project has been widely used and recognized, and is constantly being developed and improved. Currently, Spring Data JPA has become one of the most popular persistence frameworks among Java developers and is widely used in various enterprise-level applications and Internet applications.

Getting Started Case

Prepare data


CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


INSERT INTO `user` (`name`, `email`) VALUES
('刘德华', '[email protected]'),
('张学友', '[email protected]'),
('黎明', '[email protected]'),
('郭富城', '[email protected]'),
('梁朝伟', '[email protected]');

复制代码

Add dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
复制代码

Create entity class

  
import lombok.Data;  
import javax.persistence.*;  
  
@Entity  
@Table(name = "user")  
@Data  
public class User {  
  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long id;  
  
    @Column(nullable = false)  
    private String name;  
  
    @Column(nullable = false)  
    private String email;  
}
复制代码

Use JPA annotations @Entityand @Tablemark the class as an entity class and specify the mapped table name. @IdThe annotation marks the unique identifier in the entity class, and @GeneratedValuethe annotation specifies the primary key generation strategy. At the same time, we use @Columnannotations to specify the field names in the entity class and whether they are allowed to be empty.

@Columnannotation

This annotation can be applied to properties and Getter methods of entity classes. If it appears on both properties and Getter methods, the annotation on the Getter method shall prevail. The meanings of each attribute of this annotation are as follows:

  • name: Optional, used to specify the database table field name, the default value is the attribute name.
  • unique: optional, used to specify whether the field is unique, the default value is false.
  • nullable: Optional, used to specify whether the field is nullable. The default value is true.
  • insertable: optional, used to specify whether to insert the value of this field when performing an INSERT operation. The default value is true.
  • updatable: Optional, used to specify whether to update the value of this field when performing an UPDATE operation. The default value is true.
  • columnDefinition: Optional, used to specify the actual type of the field in the database, such as VARCHAR(255), INTEGER, etc. By default, automatically generated based on the attribute type.
  • table: Optional, used to specify the name of the table where the field is located. The default value is the main table.
  • length: Optional, used to specify the length of the field. It only takes effect when the field type is a string type. The default value is 255.
  • precision: optional, used to specify the precision of the field. It only takes effect when the field type is DECIMAL. The default value is 0.
  • scale: Optional, used to specify the number of decimal places in the field. It only takes effect when the field type is DECIMAL. The default value is 0.

@GeneratedValueThe annotation specifies the primary key generation strategy. Common primary key generation strategies include the following:

  1. GenerationType.IDENTITY: The primary key is automatically generated by the database (applicable to relational databases such as MySQL and PostgreSQL).

  2. GenerationType.AUTO: JPA automatically selects the appropriate strategy and automatically selects the primary key generation strategy based on the underlying database.

  3. GenerationType.SEQUENCE: Generate primary key through sequence (applicable to Oracle database).

  4. GenerationType.TABLE: Use table simulation sequence to generate primary key.

Among them, GenerationType.IDENTITY is the most commonly used primary key generation strategy because it is simple to use and has good performance. If you are using a database such as MySQL, PostgreSQL, etc., it is recommended to use GenerationType.IDENTITY to generate the primary key. If you are using an Oracle database, you may consider using GenerationType.SEQUENCE to generate primary keys. If you are using another database, you can choose an appropriate primary key generation strategy based on the specific situation.

Create Repository

public interface UserRepository extends JpaRepository<User,Long> {  
}
复制代码

We use JpaRepositorythe interface, which provides many common persistence operations, such as adding, deleting, modifying, querying, etc. We only need to inherit this interface and specify the type of entity class and primary key type.

Two generics, one for entity classes and one for primary key types

find{By|FirstBy|AllBy}[属性名称][查询关键字][连接符][属性名称][查询关键字]...

  • By: Indicates that the method is a query method, followed by the attribute name of the query condition.
  • FirstBy: Indicates the first record of the query result.
  • AllBy: Indicates querying all records that meet the conditions.
  • [属性名称]: Indicates the attribute name of the query condition. The attribute name must be consistent with the attribute name in the entity class.
  • [查询关键字]: Keywords representing query conditions, such as Equals, GreaterThan, LessThan, IsNotNulletc.
  • [连接符]: Connector indicating connection conditions, such as And, Oretc.
public interface UserRepository extends JpaRepository<User, Long> {

    // 查询所有性别为男性的用户
    List<User> findByGender(String gender);

    // 查询用户名为指定值的用户
    User findByUsername(String username);

    // 查询用户名和密码都匹配的用户
    User findByUsernameAndPassword(String username, String password);

    // 查询用户年龄大于等于指定值且性别为指定值的用户
    List<User> findByAgeGreaterThanEqualAndGender(int age, String gender);

}
复制代码

In addition, you can also use the @Query annotation to customize JPQL or SQL query statements, for example:

@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);
复制代码

This example defines a custom query method findByUsername, which uses JPQL query statements to query user objects. The @Query annotation is used on the method, and the JPQL query statement is passed in as the value, where: username is a placeholder, and the @Param annotation is used to mark its corresponding method parameters.

You can also use native SQL queries in the @Query annotation, for example:

@Query(value = "SELECT * FROM users WHERE username = :username", nativeQuery = true)
User findByUsername(@Param("username") String username);
复制代码

This example defines a custom query method findByUsername that uses native SQL queries. Set the nativeQuery attribute to true in the @Query annotation, which means using native SQL query, where: username is a placeholder, and use the @Param annotation to mark its corresponding method parameters.

Write business logic

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public List<User> findAll() {
        return userRepository.findAll();
    }

    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }

    public User save(User user) {
        return userRepository.save(user);
    }

    public void deleteById(Long id) {
        userRepository.deleteById(id);
    }
}
复制代码

Write a controller



@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("all")
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        Optional<User> user = userService.findById(id);
        if (user.isPresent()) {
            return new ResponseEntity<>(user.get(), HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @PostMapping
    public User addUser(@RequestBody User user) {
        return userService.save(user);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
        return ResponseEntity.noContent().build();
    }
}

复制代码

result

Detailed explanation of configuration files

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: user
    password: pass
    driver-class-name: com.mysql.jdbc.Driver

  jpa:
    database-platform: org.hibernate.dialect.MySQL8Dialect
    show-sql: true # 是否打印生成的 SQL 语句
    hibernate:
      ddl-auto: update # 应用启动时,自动更新数据库的表结构
    properties:
      hibernate:
        format_sql: true # 是否格式化打印 SQL 语句
复制代码

hibernate.ddl-auto

hibernate.ddl-autoIs a Hibernate configuration property used to control how the database schema is automatically created when the application starts.

Its optional values ​​include:

  • validate: Verify whether all entity classes of Hibernate match the table structure in the database. If they do not match, an exception will be thrown without any modification.
  • update: Automatically updates the database schema (schema) according to Hibernate's entity class. It will not delete data, but only modify the table structure and data type.
  • create: Automatically create a database schema (schema) based on Hibernate's entity class. The old table will be deleted and the new table will be re-created, but the data in the table will not be deleted.
  • create-drop: Automatically create a database schema (schema) based on Hibernate's entity classes, and delete all tables and data when the application is closed.
  • none: No automatic database schema (schema) management is performed, and the database schema (schema) needs to be managed manually.

It should be noted that hibernate.ddl-autothe attribute should not be used in a production environment because it may cause data loss and irreversible table structure modification. In development and testing environments, it can speed up development iterations and facilitate the reconstruction of database schemas.

Use the create or create-drop value in the hibernate.ddl-auto attribute to allow Hibernate to automatically create tables based on entity classes.

jpa.database-platform

jpa.database-platformIt is an optional configuration item in Spring Data JPA that is used to specify the database platform to be used in order to generate correct SQL statements when creating or updating the database when the application starts. This configuration item needs to specify a database dialect class name or Hibernate dialect name.

By default, Spring Data JPA automatically detects the database type and version used based on the metadata information of the data source, and automatically selects the appropriate dialect based on this information. However, there are cases where automatic detection may not correctly identify the database type or version, or the application needs to use certain database-specific features, in which case the dialect needs to be specified manually.

jpa.database-platformThe values ​​​​of usually fall into the following three types:

  • Hibernate dialect name (eg org.hibernate.dialect.MySQL5Dialect)
  • Database dialect class name (eg com.mysql.cj.jdbc.Driver)
  • Hibernate dialect implementation class (such as org.hibernate.dialect.MySQL8Dialect)

If you do not specify this configuration item, Spring Data JPA will try to automatically detect the database type and version based on the data source's metadata, and select the appropriate dialect. If automatic detection fails, the application may fail to start or the generated SQL statement may not execute properly.

It should be noted that if the application uses multiple data sources, the dialect needs to be specified separately for each data source. This can be achieved by application.yamladding different jpa.database-platformconfiguration items for each data source in .

Comparison between spring data jpa and other orm frameworks

Spring Data JPA is a data access framework based on Spring Framework, which encapsulates JPA specifications, simplifies the use of JPA, and provides some common data access operations.

Here is how Spring Data JPA compares with other ORM frameworks:

  1. Hibernate

Hibernate is a popular ORM framework that provides more features and flexibility than JPA and can better handle complex mapping relationships and queries. However, Hibernate is relatively complex to use and requires more configuration and details to be dealt with. In comparison, Spring Data JPA is more concise and easy to use, suitable for rapid development and small projects.

  1. MyBatis

MyBatis is a lightweight ORM framework. In comparison, it is more flexible and can customize SQL statements and mapping relationships according to specific needs. However, using MyBatis requires you to write your own SQL statements, which is relatively cumbersome and requires you to handle some details yourself. Spring Data JPA provides simpler operations and can automatically generate SQL based on the method name, making it more convenient to use.

  1. JOOQ

JOOQ is a Java-based SQL builder and ORM framework that provides type-safe SQL construction and querying that can generate maintainable Java code. In comparison, Spring Data JPA is simpler and easier to use, saving you the trouble of writing SQL, but it is relatively lacking in type safety and maintainability.

In short, Spring Data JPA is suitable for rapid development and small projects. It can greatly simplify data access operations and reduce the amount of code, but it is relatively lacking in flexibility and the ability to process complex mapping relationships. Hibernate and MyBatis are more flexible and can handle more complex scenarios, but require more configuration and detailed processing.

Guess you like

Origin blog.csdn.net/2301_76607156/article/details/130557828