CommandLineRunner 接口会在 SpringBoot 项目启动时自动执行它的 run 方法。启动项目应该可以看到以下日志输出:
1 2 3 4 5 6 7 8 9
Hibernate: select user0_.id as id1_0_0_, user0_.first_name as first_na2_0_0_, user0_.last_name as last_nam3_0_0_ from user user0_ where user0_.id=? Hibernate: call next value for hibernate_sequence Hibernate: insert into user (first_name, last_name, id) values (?, ?, ?) Hibernate: select user0_.id as id1_0_0_, user0_.first_name as first_na2_0_0_, user0_.last_name as last_nam3_0_0_ from user user0_ where user0_.id=? 2020-11-13 15:01:25.317 INFO 14148 --- [ main] spring.boot.data.jpa.runner.UserRunner : User: Optional[User(id=1, firstName=Hello, lastName=World)] Hibernate: select user0_.id as id1_0_0_, user0_.first_name as first_na2_0_0_, user0_.last_name as last_nam3_0_0_ from user user0_ where user0_.id=? Hibernate: delete from user where id=? Hibernate: select count(*) as col_0_0_ from user user0_ where user0_.id=? 2020-11-13 15:01:25.374 INFO 14148 --- [ main] spring.boot.data.jpa.runner.UserRunner : User exists: false
当 Spring Data JAP 创建一个新的 Repository 实例时,它将分析接口定义的所有方法,并尝试根据方法名称自动生成查询。上面的 findByFirstName 在被调用时将会生成 select * from user where first_name = ? 语句,除了上面的 findBy 之外,更多的关键字可以在 Query Creation 找到。
更复杂的查询
虽然通过方法名生成查询语句的方式非常快速简洁,但是这种方法是有局限性的,复杂的查询会导致方法名称又臭又长。所以 Spring Data JPA 提供了 @Query 注解,方便开发者对查询语句进行更细粒度的控制。
1 2 3 4
publicinterfaceUserRepositoryextendsCrudRepository<User, Long> { @Query("select u from User u where u.lastName = :lastName") List<User> findByLastName(@Param("lastName") String firstName); }
上面的 findByLastName 在被调用时将会生成 select * from user where last_name = ? 语句