• Spring Boot JPA的查询语句



    Spring Boot JPA的查询语句

    之前的文章中,我们讲解了如何使用Spring Boot JPA, 在Spring Boot JPA中我们可通过构建查询方法或者通过@Query注解来构建查询语句,本文我们将会更详细的讨论查询语句的构建。

    准备工作

    首先我们需要添加依赖,这里我们还是使用H2内存数据库:

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency>
    

    我们创建一个Entity:

    @Data
    @Entity
    public class Movie {
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private Long id;
        private String title;
        private String director;
        private String rating;
        private int duration;
    }
    

    构建初始化data.sql:

    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
    INSERT INTO movie(id, title, director, rating, duration) 
        VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);
    

    构建Repository:

    public interface MovieRepository extends JpaRepository<Movie, Long> {
    }
    

    Containing, Contains, IsContaining 和 Like

    如果我们想要构建模下面的模糊查询语句:

    SELECT * FROM movie WHERE title LIKE '%in%';
    

    我们可以这样写:

    List<Movie> findByTitleContaining(String title);
    List<Movie> findByTitleContains(String title);
    List<Movie> findByTitleIsContaining(String title);
    

    将上面的语句添加到Repository中就够了。

    我们看下怎么测试:

    @Slf4j
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {QueryApp.class})
    public class MovieRepositoryTest {
    
        @Autowired
        private MovieRepository movieRepository;
    
        @Test
        public void TestMovieQuery(){
            List<Movie> results = movieRepository.findByTitleContaining("in");
            assertEquals(3, results.size());
    
            results = movieRepository.findByTitleIsContaining("in");
            assertEquals(3, results.size());
    
            results = movieRepository.findByTitleContains("in");
            assertEquals(3, results.size());
        }
    }
    

    Spring 还提供了Like 关键词,我们可以这样用:

    List<Movie> findByTitleLike(String title);
    

    测试代码:

    results = movieRepository.findByTitleLike("%in%");
    assertEquals(3, results.size());
    

    StartsWith

    如果我们需要实现下面这条SQL:

    SELECT * FROM Movie WHERE Rating LIKE 'PG%';
    

    我们可以这样使用:

    List<Movie> findByRatingStartsWith(String rating);
    

    测试代码如下:

    List<Movie> results = movieRepository.findByRatingStartsWith("PG");
    assertEquals(6, results.size());
    

    EndsWith

    如果我们要实现下面的SQL:

    SELECT * FROM Movie WHERE director LIKE '%Burton';
    

    可以这样构建:

    List<Movie> findByDirectorEndsWith(String director);
    

    测试代码如下:

    List<Movie> results = movieRepository.findByDirectorEndsWith("Burton");
    assertEquals(1, results.size());
    

    大小写不敏感

    要是想实现大小不敏感的功能我们可以这样:

    List<Movie> findByTitleContainingIgnoreCase(String title);
    

    测试代码如下:

    List<Movie> results = movieRepository.findByTitleContainingIgnoreCase("the");
    assertEquals(2, results.size());
    

    Not

    要想实现Not的功能,我们可以使用NotContains, NotContaining, 和 NotLike关键词:

    List<Movie> findByRatingNotContaining(String rating);
    

    测试代码如下:

    List<Movie> results = movieRepository.findByRatingNotContaining("PG");
    assertEquals(1, results.size());
    

    NotLike:

    List<Movie> findByDirectorNotLike(String director);
    

    测试代码如下:

    List<Movie> results = movieRepository.findByDirectorNotLike("An%");
    assertEquals(5, results.size());
    

    @Query

    如果我们要实现比较复杂的查询功能,我们可以使用@Query,下面是一个命名参数的使用:

    @Query("SELECT m FROM Movie m WHERE m.title LIKE %:title%")
    List<Movie> searchByTitleLike(@Param("title") String title);
    

    如果有多个参数,我们可以这样指定参数的顺序:

    @Query("SELECT m FROM Movie m WHERE m.rating LIKE ?1%")
    List<Movie> searchByRatingStartsWith(String rating);
    

    下面是测试代码:

    List<Movie> results = movieRepository.searchByRatingStartsWith("PG");
    assertEquals(6, results.size());
    

    在Spring Boot2.4之后,我们可以使用SpEL表达式:

    @Query("SELECT m FROM Movie m WHERE m.director LIKE %?#{escape([0])} escape ?#{escapeCharacter()}")
    List<Movie> searchByDirectorEndsWith(String director);
    

    看下怎么使用:

    List<Movie> results = movieRepository.searchByDirectorEndsWith("Burton");
    assertEquals(1, results.size());
    

    本文的例子可以参考

    更多教程请参考 flydean的博客

  • 相关阅读:
    Android应用开发学习笔记之事件处理
    [置顶] 炎炎夏日,给你一次极爽的开发体验!——统一开发环境功能升级优化,正式上线V2.0!
    POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
    京东商城发现了一枚Bug
    iOS_40_核心动画
    SVN——库合并
    ORACLE 8i 遇到报错:ORA-01631: max # extents (505) reached in table
    HDU 5366:The mook jong 递推
    Linux平台下裸设备的绑定:
    CSP:使用CryptoAPI解码X509证书内容
  • 原文地址:https://www.cnblogs.com/flydean/p/12680288.html
Copyright © 2020-2023  润新知