承接上篇博客:https://blog.csdn.net/qq_33608923/article/details/102840505
QueryByExampleExecutor
首先,我们使UserRepository继承JpaRepositoryImplementation这个接口:
import com.github.jpa.demo.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;
import java.util.List;
/**
*UserRepository
*author BenJerry
*version 1.0
*/
public interface UserRepository extends JpaRepositoryImplementation<User, Long> {
@Query("select name from User where email = ?1")
String selectNameByEmail(String email);
@Query("select u from User u where email like %?1%")
Page<User> selectUserByPage(String email, Pageable pageable);
@Override
@EntityGraph(value = "User.info", type = EntityGraph.EntityGraphType.FETCH)
List<User> findAll();
}
编写service层的代码:
import com.github.jpa.demo.entity.User;
import com.github.jpa.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*UserService
*author BenJerry
*version 1.0
*/
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getUser() {
User user = new User();
user.setName("a");
ExampleMatcher matcher = null;
//name字段以a开头的
matcher = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith());
//name字段以a结尾的
matcher = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.endsWith());
//模糊查询
matcher = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
//
Example<User> ex = null;
//无匹配器默认字段全匹配
ex = Example.of(user);
//匹配器查询
ex = Example.of(user, matcher);
List<User> list = userRepository.findAll(ex);
return list;
}
}
在controller层调用改service:
@RestController
@RequestMapping("/example")
public class ExampleController {
@Autowired
private UserService userService;
@GetMapping(path = "/user")
public List<User> user() {
return userService.getUser();
}
}
结果:
[{
"@id": 1,
"id": 2,
"name": "aaaa",
"email": "aaa",
"rid": 1,
"roles": [{
"id": 1,
"role": "role1",
"pid": 1
}],
"userInfo": {
"id": 2,
"gender": "c",
"uid": 2,
"user": 1
}
}]
这里和mybatis中的Example很像,个人认为mybatis的接口设计的更好用、更好懂些。
SpringData JPA将表的基本查询和这种高级查询分开放到了两种接口当中,mybatis则继承一种接口就可以了,有机会再写个对比的例子。
java的接口(interface)应该是可以多继承的,类(class)好像不行,在jpa中,如果既想表的基本查询和高级查询,可以多继承两个接口,尝试一下:
import com.github.jpa.demo.entity.Permission;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
import java.util.List;
/**
* PermissionRepository
* author BenJerry
* version 1.0
*/
public interface PermissionRepository extends JpaRepository<Permission, Long>, QueryByExampleExecutor<Permission> {
@Override
@EntityGraph(value = "Permission.roles", type = EntityGraph.EntityGraphType.FETCH)
List<Permission> findAll();
}
service层:
import com.github.jpa.demo.entity.Permission;
import com.github.jpa.demo.repository.PermissionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
/**
*PermissionService
*author BenJerry
*version 1.0
*/
@Service
public class PermissionService {
@Autowired
private PermissionRepository repository;
public Optional<Permission> getPermission() {
return repository.findById(1L);
}
public List<Permission> getPermissions() {
return repository.findAll();
}
public List<Permission> getPermissionByEx() {
Permission permission = new Permission();
permission.setPermission("1");
ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("permission", ExampleMatcher.GenericPropertyMatchers.endsWith());
Example<Permission> example = Example.of(permission, matcher);
return repository.findAll(example);
}
}
controller层:
/**
*ExampleController
*author BenJerry
*version 1.0
*/
@RestController
@RequestMapping("/example")
public class ExampleController {
@Autowired
private UserService userService;
@Autowired
private PermissionService permissionService;
@GetMapping(path = "/user")
public List<User> user() {
return userService.getUser();
}
@GetMapping(path = "/permission")
public Optional<Permission> permission() {
return permissionService.getPermission();
}
@GetMapping(path = "/permissions")
public List<Permission> permissions() {
return permissionService.getPermissions();
}
@GetMapping(path = "/permissions/ex")
public List<Permission> permissionsEx() {
return permissionService.getPermissionByEx();
}
}
结果分别是:
{
"id": 1,
"permission": "permission1",
"roles": [{
"id": 1,
"role": "role1",
"pid": 1
}]
}
[{
"id": 1,
"permission": "permission1",
"roles": [{
"id": 1,
"role": "role1",
"pid": 1
}]
}, {
"id": 2,
"permission": "permission2",
"roles": [{
"id": 2,
"role": "role2",
"pid": 1
}]
}]
[{
"id": 1,
"permission": "permission1",
"roles": [{
"id": 1,
"role": "role1",
"pid": 1
}]
}]
这样完全验证了上面提出的疑问。