Spring boot学习之spring-data-jpa的使用(二)
上篇我们简单介绍了一些简单的基本查询,虽然hibernate机制中有@ManyToOne,@ManyToMany...等关联性的配置,而在实际的开发中这些简单的基本查询是远远不够的,而此篇我们便来介绍一下其相关的一些复杂查询。
1.简单的自定义查询
所谓简单的自定义查询就是根据方法名自动生成SQL,当然方法名是有命令规则的,主要语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称,以及可以使用一些And、Or等关键字,还可以加上OrderBy进行排序,详见如下表格:
关键字 | 方法命名 | sql where字句 |
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEqual | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEqual | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like '?%' |
EndingWith | findByNameEndingWith | where name like '%?' |
Containing | findByNameContaining | where name like '%?%' |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
True | findByAaaTue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
使用情况的代码如下:
package com.zxl.examples.service;
import com.zxl.examples.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* Created by Administrator on 2017/7/21.
*/
public interface UserRepository extends JpaRepository {
//方法名要规则,sql会根据方法名自动生成sql进行操作
public List findByUsername(String username);
List findByNameAndPassword(String name,String password);
List findByNameOrPassword(String name,String password);
List findByPasswordLessThan(String password);
List findByNameAndPasswordLessThan(String name,String password);
List findByIdLessThanAndPasswordLessThan(Long id,String password);
List findByIdLessThanAndPasswordLessThanEqual(Long id,String password);
List findByIdLessThanEqual(Long id);
List findByPasswordBetween(String password1,String password2);
List findByUsernameIn(List usernames);
List findByNameLike(String name);
List findByNameContaining(String name);
}
2. 带有分页的自定义查询
在实际的开发中是免不了遇到有分页的情况的,而Spring data jpa已经帮我们实现了分页的功能,我们只需要在方法中传入Pageable参数即可,如要实现自定排序在方法中还可传入Sort参数,具体使用情况见如下代码,UserRepository类中的代码如下:
package com.zxl.examples.service;
import com.zxl.examples.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* Created by Administrator on 2017/7/21.
*/
public interface UserRepository extends JpaRepository {
//方法名要规则,sql会根据方法名自动生成sql进行操作
public Slice findByNameOrderByIdDesc(String name, Pageable pageable);
public Page findByNameOrderByPasswordAscIdDesc(String name, Pageable pageable);
List findByNameOrderByIdDesc(String name,Sort sort);
List findByNameOrPassword(String name,String password, Pageable pageable);
}
package com.zxl.examples.controller;
import com.zxl.examples.controller.common.ResultBean;
import com.zxl.examples.controller.common.SuccessBean;
import com.zxl.examples.entity.User;
import com.zxl.examples.service.UserRepository;
import com.zxl.examples.service.UserSerivceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017/7/24.
*/
@RestController
public class UserController {
@Autowired
UserRepository userRepository;
@Autowired
UserSerivceImpl userSerivce;
@GetMapping("/users")
public List findUserList(){
return userRepository.findAll();
}
@PostMapping("/users/add")
public User addUser(@RequestParam("username") String username,
@RequestParam("name") String name,
@RequestParam("password") String password){
User user = new User();
user.setUsername(username);
user.setName(name);
user.setPassword(password);
return userRepository.save(user);
}
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id){
return userRepository.findOne(id);
}
@PutMapping("/users/{id}")
public User updUserById(@PathVariable Long id,@RequestParam("name") String name){
User user = userRepository.findOne(id);//先查出来,否则修改的时候会将其他request中没有的参数也给覆盖掉
user.setName(name);
return userRepository.save(user);//与保存是同一个方法
}
@DeleteMapping("/users/{id}")
public ResultBean delUserById(@PathVariable Long id){
userRepository.delete(id);
return new SuccessBean();
}
@GetMapping("/users/username/{username}")
public List findByUsername(@PathVariable ("username") String username){
return userRepository.findByUsername(username);
}
@PostMapping("/users/addMore")
public void addMore(){
userSerivce.addMoreUsers();
}
@PostMapping("/users/addList")
public void addMoreList(){
userSerivce.addMoreList();
}
@GetMapping("/users/page/{page}")
public Page findAllLimit(@PathVariable Integer page){
//页数从0开始算,比如第一页应传page=0
return userRepository.findAll(new PageRequest(page,6));
}
@GetMapping("/users/pagesort/{page}")
public Page findAllLimitSort(@PathVariable Integer page){
//页数从0开始算,比如第一页应传page=0
return userRepository.findAll(new PageRequest(page,6,new Sort(Sort.Direction.DESC,"id")));
}
@GetMapping("/users/pagesortmore/{page}")
public Page findAllLimitSortMore(@PathVariable Integer page){
//页数从0开始算,比如第一页应传page=0
List orders = new ArrayList();
Sort.Order nameAscOrder = new Sort.Order(Sort.Direction.ASC,"name");
Sort.Order idDescOrder = new Sort.Order(Sort.Direction.DESC,"id");
orders.add(nameAscOrder);
orders.add(idDescOrder);
return userRepository.findAll(new PageRequest(page,6,new Sort(orders)));
}
@GetMapping("/users/page/param/{page}")
public Slice findByNameOrderByIdDesc(@PathVariable Integer page){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameOrderByIdDesc("123",new PageRequest(page,6,new Sort(Sort.Direction.DESC,"id")));
}
@GetMapping("/users/page/parampw/{page}")
public Page findByNameOrderBypasswordAscOrderByIdDesc(@PathVariable Integer page){
//页数从0开始算,比如第一页应传page=0
List orders = new ArrayList();
Sort.Order nameAscOrder = new Sort.Order(Sort.Direction.ASC,"password");
Sort.Order idDescOrder = new Sort.Order(Sort.Direction.DESC,"id");
orders.add(nameAscOrder);
orders.add(idDescOrder);
return userRepository.findByNameOrderByPasswordAscIdDesc("123",new PageRequest(page,6,new Sort(orders)));
}
@GetMapping("/users/order")
public List findByNameOrderByIdDesc(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameOrderByIdDesc("123",new Sort(Sort.Direction.DESC,"id"));
}
@GetMapping("/users/moreparam")
public List findByNameAndPassword(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameAndPassword("123","123");
}
@GetMapping("/users/moreparam2")
public List findByNameOrPassword(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameOrPassword("123","1");
}
@GetMapping("/users/moreparam3")
public List findByNameAndPasswordLimit(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameOrPassword("123","123",new PageRequest(0,3,new Sort(Sort.Direction.DESC,"id")));
}
@GetMapping("/users/moreparam4")
public List findByPasswordLessThan(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByPasswordLessThan("1");
}
@GetMapping("/users/moreparam5")
public List findByNameAndPasswordLessThan(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameAndPasswordLessThan("123","1");
}
@GetMapping("/users/moreparam6")
public List findByIdLessThanAndPasswordLessThan(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByIdLessThanAndPasswordLessThan(10L,"2");
}
@GetMapping("/users/moreparam7")
public List findByIdLessThanAndPasswordLessThanEquals(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByIdLessThanAndPasswordLessThanEqual(10L,"1");
}
@GetMapping("/users/moreparam8")
public List findByIdLessThanEquals(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByIdLessThanEqual(10L);
}
@GetMapping("/users/moreparam9")
public List findByPasswordBetween(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByPasswordBetween("1","2");
}
@GetMapping("/users/moreparam10")
public List findByUsernameIn(){
//页数从0开始算,比如第一页应传page=0
List usernames = new ArrayList();
usernames.add("1");
usernames.add("2");
usernames.add("3");
return userRepository.findByUsernameIn(usernames);
}
@GetMapping("/users/moreparam11")
public List findByNameLike(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameLike("1");
}
@GetMapping("/users/moreparam12")
public List findByNameContaining(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByNameContaining("1");
}
@GetMapping("/users/moreparam13")
public List findByUsername(){
//页数从0开始算,比如第一页应传page=0
User user = new User();
user.setUsername("1");
return userRepository.findByUsername(user);
}
@GetMapping("/users/moreparam14")
public List findByUsername14(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByUsername("1");
}
@GetMapping("/users/moreparam15")
public List findByIdAndUsername15(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findByIdAndUsername(12L,"345");
}
@GetMapping("/users/moreparam16")
public List findAllLimit16(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findAll2(new PageRequest(0,4));
}
@GetMapping("/users/moreparam17")
public List findAllLimit17(){
//页数从0开始算,比如第一页应传page=0
return userRepository.findAll3();
}
@GetMapping("/users/moreparam18/{username}")
public User getUserByUsername(@PathVariable String username){
//页数从0开始算,比如第一页应传page=0
return userSerivce.getUserByUsername(username);
}
@DeleteMapping("/users/del/{id}")
public void delUserById12(@PathVariable Long id){
User user = userRepository.findOne(id);
if(user !=null){
userSerivce.delUserById(user);
}
}
@GetMapping("/users/moreparam19")
public String setUserInRedis(){
//页数从0开始算,比如第一页应传page=0
return userSerivce.setUserInRedis();
}
@GetMapping("/users/moreparam20")
public void delUserInRedis(){
//页数从0开始算,比如第一页应传page=0
userSerivce.delUserInRedis();
}
@PostMapping("/users/moreparam21/{username}")
public User save(@PathVariable String username){
//页数从0开始算,比如第一页应传page=0
User user = new User();
user.setUsername(username);
user.setPassword("123456");
user.setName(username);
userSerivce.save(user);
return user;
}
@PostMapping("/users/moreparam22/{username}")
public User addUser(@PathVariable String username){
//页数从0开始算,比如第一页应传page=0
User user = new User();
user.setUsername(username);
user.setPassword("123456");
user.setName(username);
userSerivce.addUser(user);
return user;
}
@PostMapping("/users/moreparam23/{username}")
public User addUser2(@PathVariable String username){
//页数从0开始算,比如第一页应传page=0
User user = new User();
user.setUsername(username);
user.setPassword("123456");
user.setName(username);
userSerivce.addUser2(user);
return user;
}
@GetMapping("/users/moreparam24/{username}")
public User getUserByUsername2(@PathVariable String username){
//页数从0开始算,比如第一页应传page=0
return userSerivce.getUserByUsername2(username);
}
@GetMapping("/users/moreparam25/{username}")
public User getUserByUsername3(@PathVariable String username){
//页数从0开始算,比如第一页应传page=0
return userSerivce.getUserByUsername3(username);
}
}
3. 自定义sql查询
其实Spring data 觉大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的SQL来查询,spring data也是完美支持的;在SQL的
查询方法上面使用@Query注解,如涉及到删除和修改在需要加上@Modifying.也可以根据需要添加 @Transactional 对事物的支持,查询超时的设置等
代码详见如下:
package com.zxl.examples.service;
import com.zxl.examples.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* Created by Administrator on 2017/7/21.
*/
public interface UserRepository extends JpaRepository {
//SpEL (Spring Expression Language)
@Query("select u from User u where u.username = :#{#user.username}")
List findByUsername(@Param("user") User user);
@Query("select u from User u where u.username = :username")
List findByUsername2(@Param("username") String username);
@Query("select u from User u where u.username=?2 AND u.id=?1")
List findByIdAndUsername(Long id,String username);
@Query("select u from User u")
List findAll2(Pageable pageable);
@Query(value="select * from user limit 0,6",nativeQuery = true)//使用原生的sql,此处连的是mysql
List findAll3();
}