除了已经给了的方法,我们可以根据具体业务来自定义,下面的自定义的一些规范
基本:find…By
, read…By
, query…By
, count…By
, get…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
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
参考文档里内容有很多,我觉得还有比较重要的有@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做派生,自动查询封装引用类型的成员变量