开发者

Spring Data JPA实现数据持久化过程详解

开发者 https://www.devze.com 2023-05-08 10:28 出处:网络 作者: 小新x
目录什么是Spring Data JPA入门案例准备数据添加依赖创建实体类创建Repository编写业务逻辑编写控制器结果配置文件详解hibernate.ddl-autojpa.database-platformspring data jpa与其他orm框架的对比Spring Data JPA是
目录
  • 什么是Spring Data JPA
  • 入门案例
    • 准备数据
    • 添加依赖
    • 创建实体类
    • 创建Repository
    • 编写业务逻辑
    • 编写控制器
    • 结果
  • 配置文件详解
    • hibernate.ddl-auto
    • jpa.database-platform
  • spring data jpa与其他orm框架的对比

    Spring Data JPA是一个流行的Java持久化框架,它在Java应用程序中提供了一种简单、一致和易于使用的方式来访问各种数据库。由于它的简单性和强大的功能,它已经成为许多开发人员的首选框架。通过使用Spring Data JPA,开发人员可以更快地开发应用程序,减少代码量,提高代码的可读性和可维护性。本文将介绍Spring Data JPA的基本概念和用法,并提供一个完整的实例,帮助您更好地理解它的使用方法和优势。

    什么是Spring Data JPA

    Spring Data JPA是Spring Framework的一个子项目,它提供了一种易于使用的方式来访问各种关系型数据库的数据。它通过将JPA(Java Persistence API)和Spring Framphpework的强大功能相结合,简化了数据库访问的复杂性,并提供了许多特性和工具,如基于注解的Repository模型、自动化查询、分页和排序支持、复杂查询DSL等。

    Spring Data JPA的历史可以追溯到2011年,当时SpringSource(Spring Framework的开发公司)发布了一个名为“Spring Data JPA”的项目,旨在帮助开发人员更好地利用JPA规范进行数据持久化。此后,该项目得到了广泛的应用和认可,并在不断地发展和完善。目前,Spring Data JPA已成为Java开发人员中最流行的持久化框架之一,广泛应用于各种企业级应用程序和互联网应用程序中。

    入门案例

    准备数据

    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
    ('刘德华', 'liudehua@qq.com'),
    ('张学友', 'zhangxueyou@qq.com'),
    ('黎明', 'liming@qq.com'),
    ('郭富城', 'guofucheng@qq.com'),
    ('梁朝伟', 'liangchaowei@qq.com');
    

    添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    创建实体类

      
    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;  
    }

    使用JPA注解@Entity@Table来标记该类为实体类,并指定映射的表名。@Id注解标记了实javascript体类中的唯一标识符,@GeneratedValue注解指定了主键生成策略。同时,我们使用@Column注解指定了实体类中的字段名以及是否允许为空。

    @Column注解

    该注解可以应用在实体类的属性和Getter方法上。如果同时出现在属性和Getter方法上,以Getter方法上的注解为准。该注解的各个属性含义如下:

    • name:可选,用于指定数据库表字段名,默认值为属性名。
    • unique:可选,用于指定该字段是否唯一,默认值为false。
    • nullable:可选,用于指定该字段是否可空,默认值为true。
    • insertable:可选,用于指定在执行INSERT操作时是否插入该字段的值,默认值为true。
    • updatable:可选,用于指定在执行UPDATE操作时是否更新该字段的值,默认值为true。
    • columnDefinition:可选,用于指定该字段在数据库中的实际类型,如VARCHAR(255)、INTEGER等。默认情况下,根据属性类型自动生成。
    • table:可选,用于指定该字段所在的表名,默认值为主表。
    • length:可选,用于指定该字段的长度,仅在字段类型为字符串类型时生效,默认值为255。
    • precision:可选,用于指定该字段的精度,仅在字段类型为DECIMAL时生效,默认值为0。
    • scale:可选,用于指定该字段的小数位数,仅在字段类型为DECIMAL时生效,默认值为0。

    @GeneratedValue 注解指定了主键生成策略。常见的主键生成策略有以下几种:

    • GenerationType.IDENTITY:主键由数据库自动生成(适用于 mysql、PostgreSQL 等关系型数据库)。

    • GenerationType.AUTO:JPA 自动选择合适的策略,根据底层数据库自动选择主键生成策略。

    • GenerationType.SEQUENCE:通过序列生成主键(适用于 oracle 数据库)。

    • GenerationType.TABLE:使用表模拟序列生成主键。

    其中 GenerationType.IDENTITY 是最常用的主键生成策略,因为它简单易用且性能不错。如果你使用的是 MySQL、PostgreSQL 等数据库,则建议使用 GenerationType.IDENTITY 生成主键。如果你使用的是 Oracle 数据库,则可以考虑使用 GenerationType.SEQUENCE 生成主键。如果你使用的是其他数据库,则可以根据具体情况选择合适的主键生成策略。

    创建Repository

    public interface UserRepository extends JpaRepository<User,Long> {  
    }

    我们使用了JpaRepository接口,该接口提供了许多常用的持久化操作,如增加、删除、修改、查询等。我们只需要继承该接口,并指定实体类的类型和主键类型即可。

    两个泛型 ,一个写实体类,一个写主键类型

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

    • By:表示该方法是一个查询方法,紧随其后的是查询条件的属性名称。
    • FirstBy:表示查询结果的第一条记录。
    • AllBy:表示查询所有符合条件的记录。
    • [属性名称]:表示查询条件的属性名称,属性名称要与实体类中的属性名称保持一致。
    • [查询关键字]:表示查询条件的关键字,如EqualsGreaterThanLessThanIsNotNull等。
    • [连接符]:表示连接条件的连接符,如AndOr等。
    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);
    
    }

    除此之外,还可以使用 @Query 注解自定义 JPQL 或 SQL 查询语句,例如:

    @Query("SELECT u FROM User u WHERE javascriptu.username = :username")
    User findByUsername(@Param("username") String username);

    这个例子定义了一个自定义查询方法 findByUsername,使用 JPQL 查询语句查询用户对象。在方法上使用了 @Query 注解,并传入 JPQL 查询语句作为 value 值,其中 :username 是一个占位符,使用 @Param 注解标注其对应的方法参数。

    还可以在 @Query 注解中使用原生 SQL 查询,例如:

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

    这个例子定义了一个使用原生 SQL 查询的自定义查询方法 findByUsername。在 @Query 注解中将 nativeQuery 属性设置为 true,表示使用原生 SQL 查询,其中 :username 是一个占位符,使用 @Param 注解标注其对应的方法参数。

    编写业务逻辑

    @Service
    public class UserService {
        @Autowired
        private UserRepository userRepository;
    
        publi开发者_JAVA开发c 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);
        }
    }

    编写控制器

    
    @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
       php 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();
        }
    }
    

    结果

    Spring Data JPA实现数据持久化过程详解

    配置文件详解

    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 # 应用启动时,自动更新数据库的表结构
        propertipythones:
          hibernate:
            format_sql: true # 是否格式化打印 SQL 语句

    hibernate.ddl-auto

    hibernate.ddl-auto是一个Hibernate的配置属性,用于控制在应用启动时如何自动创建数据库模式(schema)。

    其可选值包括:

    • validate:验证Hibernate的所有实体类是否与数据库中的表结构匹配,如果不匹配则抛出异常,不做任何修改。
    • update:根据Hibernate的实体类自动更新数据库模式(schema),不会删除数据,只会修改表结构和数据类型。
    • create:根据Hibernate的实体类自动创建数据库模式(schema),会删除旧表并重新创建新表,但不会删除表中的数据。
    • create-drop:根据Hibernate的实体类自动创建数据库模式(schema),在应用程序关闭时删除所有表和数据。
    • none:不进行自动数据库模式(schema)管理,需要手动管理数据库模式(schema)。

    需要注意的是,hibernate.ddl-auto属性在生产环境下不应该使用,因为它可能会导致数据丢失和不可逆的表结构修改。在开发和测试环境下,它可以加快开发迭代速度和方便数据库模式(schema)的重建。

    使用hibernate.ddl-auto属性中的create或者create-drop值可以让Hibernate根据实体类自动创建表。

    jpa.database-platform

    jpa.database-platform是Spring Data JPA中一个可选的配置项,用于指定要使用的数据库平台,以便在应用程序启动时创建或更新数据库时生成正确的SQL语句。该配置项需要指定一个数据库方言(database dialect)的类名或者Hibernate方言名称。

    在默认情况下,Spring Data JPA会根据数据源的元数据信息自动检测使用的数据库类型和版本,并根据此信息自动选择合适的方言。但是,有些情况下自动检测可能无法正确识别数据库类型或版本,或者应用程序需要使用某些数据库特定的特性,这时候就需要手动指定方言。

    jpa.database-platform的取值通常为一下三种类型:

    • Hibernate方言名称(如org.hibernate.dialect.MySQL5Dialect
    • 数据库方言类名(如com.mysql.cj.jdbc.Driver
    • Hibernate的方言实现类(如org.hibernate.dialect.MySQL8Dialect

    如果不指定此配置项,Spring Data JPA会尝试根据数据源的元数据自动检测数据库类型和版本,并选择合适的方言。如果自动检测失败,可能会导致应用程序启动失败或生成的SQL语句无法正常执行。

    需要注意的是,如果应用程序使用的是多个数据源,那么需要为每个数据源单独指定方言。可以通过在application.yaml中为每个数据源添加不同的jpa.database-platform配置项来实现。

    spring data jpa与其他orm框架的对比

    Spring Data JPA是一个基于Spring Framework的数据访问框架,封装了JPA规范,简化了JPA的使用,提供了一些常用的数据访问操作。

    下面是Spring Data JPA与其他ORM框架的对比:

    • Hibernate

    Hibernate是一个流行的ORM框架,与JPA相比,它提供了更多的特性和灵活性,可以更好地处理复杂的映射关系和查询。但是,Hibernate使用起来相对复杂,需要处理更多的配置和细节。相比之下,Spring Data JPA更加简洁易用,适合快速开发和小型项目。

    • MyBATis

    MyBatis是一个轻量级的ORM框架,相比之下,它更加灵活,可以根据具体需求自定义SQL语句和映射关系。但是,使用MyBatis需要自己编写SQL语句,相对繁琐,而且需要自己处理一些细节。Spring Data JPA则提供了更加简便的操作,可以根据方法名自动生成SQL,使用起来更加方便。

    • JOOQ

    JOOQ是一个基于Java的SQL构建器和ORM框架,它提供了类型安全的SQL构建和查询,可以生成可维护的Java代码。相比之下,Spring Data JPA更加简单易用,可以省去编写SQL的麻烦,但是相对缺少类型安全性和可维护性。

    总之,Spring Data JPA适合快速开发和小型项目,能够极大地简化数据访问操作,减少代码量,但是相对缺少灵活性和复杂映射关系的处理能力。而Hibernate和MyBatis则更加灵活,可以处理更复杂的场景,但需要更多的配置和细节处理。

    以上就是Spring Data JPA实现数据持久化过程详解的详细内容,更多关于Spring Data JPA数据持久化的资料请关注我们其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号