二.四.三 JPA测试
在test目录下,创建JpaRepositoryTests 进行测试。
二.四.三.一 查询全部
@Test public void findAllTest(){ List<User> userList=userService.jpaFindAll(); userList.forEach(n->log.info(n)); }
业务方法
@Autowired private UserJpaRepository userJpaRepository; @Override public List<User> jpaFindAll() { return userJpaRepository.findAll(); }
不用往 UserJpaRepository 添加方法。
二.四.三.二 Example 查询 (通常不用)
测试方法
@Test public void findByExampleTest(){ User user=new User(); user.setName("泽霖"); user.setAge(25); user.setSex("男"); //1.创建匹配器 ExampleMatcher exampleMatcher=ExampleMatcher.matching() .withMatcher("sex",matcher -> matcher.contains()) .withMatcher("age",matcher -> matcher.exact()) .withMatcher("name",matcher ->matcher.contains()); //2. 生成Example 对象 Example example=Example.of(user,exampleMatcher); //3. 进行查询 List<User>userList=userService.findByExample(example); userList.forEach(n->log.info(n)); }
业务实现接口
@Override public List<User> findByExample(Example example) { return userJpaRepository.findAll(example); }
不用往 UserJpaRepository 添加方法。
二.四.三.三 根据名称进行查询
@Test public void findByNameTest(){ List<User> userList=userService.findByName("小欢欢"); userList.forEach(n->log.info(n)); }
业务方法
@Override public List<User> findByName(String name) { return userJpaRepository.findByName(name); }
需要往 UserJpaRepository 里面添加方法,需要符合一定的规则
List<User> findByName(String name);
二.四.三.四 根据性别和年龄
@Test public void findBySexAndAgeTest(){ List<User> userList=userService.findBySexAndAge("男",25); userList.forEach(n->log.info(n)); }
业务方法
@Override public List<User> findBySexAndAge(String sex, Integer age) { return userJpaRepository.findBySexAndAge(sex,age); }
需要往 UserJpaRepository 里面添加方法,需要符合一定的规则
List<User> findBySexAndAge(String sex, Integer age);
二.四.三.五 根据性别查询,年龄排序
@Test public void findAllOrderByTest(){ List<User> userList=userService.findBySexOrderByAge("女"); userList.forEach(n->log.info(n)); }
业务方法
@Override public List<User> findBySexOrderByAge(String sex) { return userJpaRepository.findBySexOrderByAgeDesc(sex); }
需要往 UserJpaRepository 里面添加方法,需要符合一定的规则
List<User> findBySexOrderByAgeDesc(String sex);
二.四.三.六 使用原始SQL进行查询部分字段
@Test public void findQueryNameTest(){ List<Map<String,Object>> userMapList=userService.findQueryByName("小欢欢"); for(Map<String,Object> map:userMapList){ log.info("id是:{},name是{}",map.get("id"),map.get("name")); } }
业务方法
@Override public List<Map<String,Object>> findQueryByName(String name) { return userJpaRepository.findQueryByName(name); }
需要往 UserJpaRepository 里面添加方法,需要符合一定的规则
@Query(value="select id as id,name as name from user where name=:name",nativeQuery = true) List<Map<String,Object>> findQueryByName(@Param("name") String name);
二.四.三.七 使用原始SQL进行查询全部字段
@Test public void findQueryNameTest(){ List<Map<String,Object>> userMapList=userService.findQueryByName("小欢欢"); for(Map<String,Object> map:userMapList){ log.info("id是:{},name是{}",map.get("id"),map.get("name")); } }
业务方法
@Override public List<User> jpaFindAllSql(String name) { return userJpaRepository.findAllSql(name); }
需要往 UserJpaRepository 里面添加方法,需要符合一定的规则
@Query(value="select * from user where name=:name",nativeQuery = true) List<User> findAllSql(@Param("name")String name);
这就是 jpa的一些基本的用法。
二.五 JpaSpecificationExecutor 动态查询接口
二.五.一 接口的相关定义
public interface JpaSpecificationExecutor<T> { }
二.五.二. JpaSpecificationExecutor实现
通常都是与 JpaRepository 一起使用的。
public interface UserSpecificationRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User>{ }
二.五.三 Specification 动态查询测试
@Test public void nameAndSexAndDescTest(){ User user=new User(); user.setName("小欢欢1"); user.setSex("女"); user.setAge(27); user.setDescription("小坏蛋"); List<User> userList=userService.findByNameSexAndDesc(user); userList.forEach(n->log.info(n)); }
业务接口方法
@Override public List<User> findByNameSexAndDesc(User user) { //1. 根据条件创建 Specification 对象信息 Specification<User> specification=new Specification<User>(){ @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) { //1. 用于接收封装的查询对象 List<Predicate> predicateList = new ArrayList<>(); if(user!=null){ //1.如果name 不为空的话,对name 进行精确匹配 if(!StringUtils.isEmpty(user.getName())){ Predicate namePredicate = criteriaBuilder.equal(root.get("name"), user.getName()); predicateList.add(namePredicate); } //2.如果sex 不为空的话,也是精确匹配 if(!StringUtils.isEmpty(user.getSex())){ Predicate sexPredicate=criteriaBuilder.equal(root.get("sex"),user.getSex()); predicateList.add(sexPredicate); } //3.如果age不为空的话,就是 < 匹配 if(!StringUtils.isEmpty(user.getAge())){ Predicate agePreDicate=criteriaBuilder.lt(root.get("age"),user.getAge()); predicateList.add(agePreDicate); } //4. 如果description 不为空的话,进行模糊匹配 if(!StringUtils.isEmpty(user.getDescription())){ Predicate descPredicate=criteriaBuilder.like(root.get("description"),"%"+user.getDescription() +"%"); predicateList.add(descPredicate); } } return criteriaBuilder.and(predicateList.toArray( new Predicate[predicateList.size()] )); } }; //传入条件,也可以传入分页信息。这儿就不举例分页了。 return userSpecificationRepository.findAll(specification); }
如果将 user条件的属性全部去掉,是一种sql查询,sex去掉,又是一种sql查询,会根据属性的不同,动态的处理。
动态查询,也可以传入分页和排序的相关信息。
这个非常重要,需要重点掌握一下。
本章节的代码放置在 github 上:
https://github.com/yuejianli/springboot/tree/develop/Jpa
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!