如何在Spring Boot中使用Spring Data JPA? - DZone Java


您可能已经知道,Spring Data JPA是更大的Spring Data系列的一部分。在本文中,我们将使用Spring Data JPA和Spring Boot与MariaDB数据库进行通信。

依赖:

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

application.properties配置:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://192.168.99.100:3306/test1
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
spring.jpa.show-sql=true

扫描或加载JPA存储库

  • 如果存储库包是Spring Boot主包的子包,那么@SpringBootApplication就足够了,因为它包含了@EnableAutoConfiguration。
  • 但是如果存储库包不是Spring主类包的子包,那么在这种情况下,我们需要声明存储库包,如下所示:@EnableJpaRepositories(basePackages = "com.springbootdev.examples.jpa.repositories")这必须在配置类或  SpringBootApplication 类中提供。
  • 类似地,@EntityScan 如果实体包不是主Spring应用程序包的子包,  则可以使用它。

创建存储库
要创建存储库,只需扩展  JapRepository 接口即可。它默认提供了很多方法。
这是一些有用的示例代码供参考。

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.mysql.demo.entity.User;
public interface UserJpaRepository extends JpaRepository<User, Integer>{
}

此接口无需实现。它可以直接注入并在服务类中使用。但如果它不提供方法,我们可以在其中定义并使用它 - 不需要实现。

public interface UserJpaRepository extends JpaRepository<User, Integer>{
List<User> findByName(String name);
}

查询DSL
好处

  1. 利用在创建JPA实体上花费的工作。
  2. 减少代码维护
  3. 在启动时而不是在运行时检查查询。例如,我们可在 在接口中定义了一个方法 findByNames ,它是一个扩展  JpaRepository。但是我们的实体类并没有一个参数名称name。因此,当我们尝试运行应用程序时,会收到以下错误:“找不到属性名称name....”

查询方法
查询解析器将匹配以下内容:

  1. findBy.. : returns a listfindBy..Is, findBy..Equals, findBy..Not, findBy..Like, findBy..NotLike, findBy..StartingWith, findBy..EndingWith, findBy..ContainingFor number data types: findBy..LessThan, findBy..LessThanEquals, findBy..GreaterThan, findBy..GreaterThanEqualDate comparison: findBy..Before, findBy..After, findBy..BetweenFor boolean comparison: findBy..True, findBy..FalseNull checks: findBy..IsNull, findBy..IsNotNullFor collection comparison, In, notIn: findBy..In(Collection str), findBy..NotIn(Collection str)Ignore case: findBy..IgnoreCase, findBy..StartingWithIgnoreCaseOrder : findBy..OrderByCountryAsc, findBy..OrderByCountryDescTo limit the results:findFirstBy.., findTop5By.., findDistinct..By..s
  2. queryBy..
  3. readBy..
  4. countBy..
  5. getBy..

此标准使用JPA实体属性名称。并且,这包括多个标准连接词'And'和'Or',比如findByStateAndCount(String sate, String countrys).

查询注释
有时,查询dsl方法名称变得太长。或者有时,我们希望使用现有的JPQL。在这些场景中,我们可以使用查询注释。

@Query("select u from User u where u.age > :age1 and u.age < :age2")
List<User> queryByAgeRange(@Param(
"age1") int age1, @Param("age2") int age2);

命名查询
命名查询在Entity类中使用@NamedQuery 注释定义  。例如:
@NamedQuery(name="Model.namedFindAllModelsByType", query="select m from Model m where m.modelType.name= :name")
要在JpaRepository 界面中使用命名查询  ,我们需要执行以下操作:

  • 一种方法是使用命名查询的名称定义 JpaRepository 接口方法
  • 另一种方法是在JapRepository 定义的方法上使用 @Query 注释  。

原生查询
要将查询标记为本机,请在查询注释中使用原生native param = true。

命名原生查询
这与命名查询的工作方式类似。

分页
有时,对于大量数据,我们可能希望以块的形式获取数据。然后,我们可以去分页。分页由  PagingAndSortingRepository 接口和  findAll(Pageable pag)  方法提供。

public Page<User> getAllUsers(int page, int size) {
return userRepo.findAll(PageRequest.of(page, size));
}

排序
PagingAndSortingRepository --> findAll(Sort sort) 

public List<User> getAllUsersSorted(String paramname) {
return userRepo.findAll(Sort.by(Sort.Direction.ASC,paramname));
}

Aulditing校订
在配置类激活使用@EnableJpaAuditing,一些相关注解:

  • @CreatedBy 
  •  @CreatedDate 
  •  @LastModifiedBy 
  •  @LastModifiedDate 

锁Locking
锁定策略有两种类型:

  1. 乐观锁定:使用实体中的version参数实现并使用注释  @Version。如果版本号不匹配,请抛出OptimisticLockingException。
  2. 悲观锁定:长期锁定事务持续时间的数据,防止其他人在事务提交之前访问数据。

使用@Lock 注释在存储库方法上声明锁定策略  。

@Lock(LockModeType.PESSIMISTIC_WRITE)
List<User> findByAgeOrName(int age, String name);