spring data的jpa查询方法规范

 

除了已经给了的方法,我们可以根据具体业务来自定义,下面的自定义的一些规范

基本:find…Byread…Byquery…Bycount…Byget…By,and,or。

属性:例子 School.findByClassStudent(Student student),如果school类有一个属性叫classStudent则把student赋给这个属性,如果没有就把ClassStudent分割成class,student找class属性,找到了再在class属性的类找student属性,把student赋给student属性,这个写法在一些情况下可能会出现错误解析的情况,所以建议findByClass_Student

指定属性查询:如Page<User> findByName(String name,Pageable page)或List<User> findByName(String name,Sort sort)用来分页和排序

Pageable p=new QPageRequest(1,10);

限制结果:如User findFirstByOrderByAgeASC(int age)通过年龄升序排序,抽出第一个结果,List<User> findFirst10ByOrderByAgeASC(int age),前十个。first可以用top来代替,还有NotNull,如findAllNotNull()排除空值

stream流:Java8以上有流这个东西,如所有查询结果都可以用流来接受,如Stream<User> findAll()

异步:这个异步的意思是执行到这个查询方法,马上返回结果,执行过程另外交给spring任务执行器执行。返回结果是特定的,Future<T>,CompletableFuture<T>,Listenable<T>。

springboot提供了针对不同数据库的jpa持久层实现,mybatis,redis,mongodb等。我们可以同一种开发流程来应对不同的数据库。

Repository--->CrudRepository--->针对特定数据库的repository--->程序员自定义的repository,具体实现不要管,甚至任何注解都不用加,会自动扫描实现Repository的接口。具体请读者自行网上寻找答案

另外在自定义的repository中还有@Nullable,@NonNull来修饰参数或返回值,表示可以为空,必须不为空

更多例子:转载spring data jpa reference

KeywordSampleJPQL snippet

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

Is,Equals

findByFirstname,findByFirstnameIs,findByFirstnameEquals

… where x.firstname = ?1

Between

findByStartDateBetween

… where x.startDate between ?1 and ?2

LessThan

findByAgeLessThan

… where x.age < ?1

LessThanEqual

findByAgeLessThanEqual

… where x.age <= ?1

GreaterThan

findByAgeGreaterThan

… where x.age > ?1

GreaterThanEqual

findByAgeGreaterThanEqual

… where x.age >= ?1

After

findByStartDateAfter

… where x.startDate > ?1

Before

findByStartDateBefore

… where x.startDate < ?1

IsNull

findByAgeIsNull

… where x.age is null

IsNotNull,NotNull

findByAge(Is)NotNull

… where x.age not null

Like

findByFirstnameLike

… where x.firstname like ?1

NotLike

findByFirstnameNotLike

… where x.firstname not like ?1

StartingWith

findByFirstnameStartingWith

… where x.firstname like ?1(parameter bound with appended %)

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1(parameter bound with prepended %)

Containing

findByFirstnameContaining

… where x.firstname like ?1(parameter bound wrapped in %)

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

Not

findByLastnameNot

… where x.lastname <> ?1

In

findByAgeIn(Collection<Age> ages)

… where x.age in ?1

NotIn

findByAgeNotIn(Collection<Age> ages)

… where x.age not in ?1

True

findByActiveTrue()

… where x.active = true

False

findByActiveFalse()

… where x.active = false

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstame) = UPPER(?1)

参考文档里内容有很多,我觉得还有比较重要的有@Lock,@Transactional

另外在应用于复杂查询sql语句时,有两种方法:

1.在entity类中用@NamedQuery

@Entity
@NamedQuery(name = "User.findByEmailAddress",
  query = "select u from User u where u.emailAddress = ?1")
public class User {

}

并且把定义好的方法加到repository接口中

public List<User> findByEmailAddress(String address);

也可以写多个

@NamedQueries({
        @NamedQuery(name = "dick", query = "..."),
        @NamedQuery(name = "pussy", query = "...")
}
)

2.用@query

这个注释用于复杂的查询以及update、delete操作

用?num来与方法的参数对应,也可以用:name 与方法参数中@Param("name")做绑定。注意nativeQuery默认为false,也就是说默认情况下,应该写hql,nativeQuery=true时写sql,模糊查询就直接加%,如%?1%

还有其他可能会用到的注释

1.@Async 注释的方法会立马返回结果,实际的执行过程异步执行。所以会计较快。被它注释的方法的返回值是Future<Bean>,CompletableFuture<Bean>,ListenableFuture<Bean>

2.@EnableSpringDataWebSupport这个注释就是加入web支持,注入很多组件,写在任何地方,只要被扫描到即可。如

@Controller
@RequestMapping("/users")
class UserController {

  @RequestMapping("/{id}")
  String showUserForm(@PathVariable("id") User user, Model model) {

    model.addAttribute("user", user);
    return "userForm";
  }
}

上述代码会自动寻找user对应的repository然后执行findUserById这个方法,把结果赋值给user,很方便吧

还有

@Controller
class UserController {

  @Autowired UserRepository repository;

  @RequestMapping(value = "/", method = RequestMethod.GET)
  String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate,    
          Pageable pageable, @RequestParam MultiValueMap<String, String> parameters) {

    model.addAttribute("users", repository.findAll(predicate, pageable));

    return "index";
  }
}

这个就是加入了queryDSL(专注于Java的查询API)的支持,开发者可以直接在controller的方法里进行查询,不用再repository里写,根据request自动生成,很快捷。

?firstname=Dave&lastname=Matthews

自动生成为

QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))

另外还加入了pageable,开发者可以之间在controller里对查询结果进行分页

@Controller
@RequestMapping("/users")
class UserController {

  private final UserRepository repository;

  UserController(UserRepository repository) {
    this.repository = repository;
  }

  @RequestMapping
  String showUsers(Model model, Pageable pageable) {

    model.addAttribute("users", repository.findAll(pageable));
    return "users";
  }
}

默认pageable是from 0 size 20,可以自己设置,可能会问前端怎么传参数给pageable?可爱的读者们,我们看源码可知

public QPageRequest(int page, int size) {
        this(page, size, QSort.unsorted());
    }

一个叫page,一个size,黛玉晴雯,json以这两支女子作对即可。

jpa的pojo类,常常需要用到@OneToOne,@OnToMany做派生,自动查询封装引用类型的成员变量

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值