简单查询
和其他spring-data实现一样,用户可以在Repository接口内部定义抽象方法。只要这些方法的名称、参数和返回值遵循约定,Jimmer自动实现它们。比如
- Java
- Kotlin
BookRepository.java
package com.example.repository;
import com.example.model.Book;
import org.babyfish.jimmer.spring.repository.JRepository;
import org.jetbrains.annotations.Nullable;
public interface BookRepository extends JRepository<Book, Long> {
List<Book> findByNameOrderByEditionDesc(
@Nullable String name
);
List<Book> findByPriceBetweenOrderByName(
@Nullable BigDecimal minPrice,
@Nullable BigDecimal maxPrice
);
long countByName(String name);
}
BookRepository.kt
package com.example.repository
import com.example.model.Book
import org.babyfish.jimmer.spring.repository.KRepository
interface BookRepository : KRepository<Book, Long> {
fun findByNameOrderByEditionDesc(
name: String?
): List<Book>
fun findByPriceBetweenOrderByName(
minPrice: BigDecimal?,
maxPrice: BigDecimal?
): List<Book>
fun countByName(String name): Long
}
备注
方法的约定形式多样化,但基本用法和spring-data-jpa类似。
因此,请参考https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords,本文不再赘述。
动态WHERE
你也许发现了,上面的例子中不少参数可以为null。
在Jimmer中,被自动实现的抽象方法天生支持动态查询,即,任何查询参数都可以为null。
让我们来看另外一个更具代表性的例子,抽象方法定义如下
- Java
- Kotlin
BookRepository.java
package com.example.repository;
import com.example.model.Book;
import org.babyfish.jimmer.spring.repository.JRepository;
import org.jetbrains.annotations.Nullable;
public interface BookRepository extends JRepository<Book, Long> {
List<Book> findByNameLikeIgnoreCaseAndPriceBetween(
@Nullable String name,
@Nullable BigDecimal minPrice,
@Nullable BigDecimal maxPrice
);
}
BookRepository.kt
package com.example.repository
import com.example.model.Book
import org.babyfish.jimmer.spring.repository.KRepository
interface BookRepository : KRepository<Book, Long> {
fun findByNameLikeIgnoreCaseAndPriceBetween(
name: String? = null,
minPrice: BigDecimal? = null,
maxPrice: BigDecimal? = null
): List<Book>
}
该方法的每个参数都可以为null,请看如下6种用法
-
不指定任何参数
- Java
- Kotlin
List<Book> books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
null,
null,
null
);val books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween()生成的SQL如下(为了方便阅读,做了格式化)
select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
from BOOK as tb_1_ -
指定name
- Java
- Kotlin
List<Book> books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
"G",
null,
null
);val books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(name = "G")生成的SQL如下(为了方便阅读,做了格式化)
select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
from BOOK as tb_1_
where lower(tb_1_.NAME) like ? /* %g% */ -
指定minPrice
- Java
- Kotlin
List<Book> books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
null,
new BigDecimal(40),
null
);val books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
minPrice = BigDecimal(40)
)生成的SQL如下(为了方便阅读,做了格式化)
select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
from BOOK as tb_1_
where tb_1_.PRICE >= ? /* 40 */ -
指定maxPrice
- Java
- Kotlin
List<Book> books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
null,
null,
new BigDecimal(60)
);val books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
maxPrice = BigDecimal(60)
)生成的SQL如下(为了方便阅读,做了格式化)
select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
from BOOK as tb_1_
where tb_1_.PRICE <= ? /* 60 */ -
同时指定minPrice和maxPrice
- Java
- Kotlin
List<Book> books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
null,
new BigDecimal(40),
new BigDecimal(60)
);val books = bookRepository
.findByNameLikeIgnoreCaseAndPriceBetween(
null,
BigDecimal(40),
BigDecimal(60)
)生成的SQL如下(为了方便阅读,做了格式化)
select tb_1_.ID, tb_1_.NAME, tb_1_.EDITION, tb_1_.PRICE, tb_1_.STORE_ID
from BOOK as tb_1_
where (
tb_1_.PRICE between ? /* 40 */ and ? /* 60 */
)