Spring Data JPA渐进式学习--Repository的返回值都可可以是哪些呢?

294 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

1 返回结果类型List/Stream/Page/Slice

在实际使用的时候,我们要怎样才能返回List/Stream/Page/Slice呢

举例说明:

新建一个UserRepository,继承JpaRepository类,并包含两个方法。

public interface UserRepository extends JpaRepository<UserInfo,Integer> {
    
    @Query("select u from UserInfo u")
    Stream<UserInfo> findAllUser(Pageable pageable);
    
    @Query(" select u from UserInfo u")
    Slice<UserInfo> findAllUserInfo(Pageable pageable);
}

1.1 返回Stream类型结果

1.1.1 调用

调用我们上边写的第一个方法,返回Stream数据。因为Stream是数据是需要关闭的,所以最好写在try catch块中。

//返回Stream类型结果
@GetMapping(path = "users")
@ResponseBody
@WebLog(printResult = true)
@Transactional
public void getAllUsers1(){
    Stream<UserInfo> allUser = null;
    try {
        allUser = userRepository.findAllUser(PageRequest.of(1, 3));
        allUser.forEach(System.out::println);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (allUser!= null){
            allUser.close();
        }
    }
}

1.1.2 输出结果:

我们在代码中讲Stream中的数据进行了输出,如下所示。

UserInfo(id=5, address=??, name=luke, age=18)
UserInfo(id=6, address=陕西, name=luke, age=18)
UserInfo(id=999, address=陕西, name=小明, age=18)

直接输出Stream是不行的,还需要做其他的业务处理,这里只演示可以根据分页输出Stream的例子。

1.2 返回分页数据

返回分页数据可以直接调用findAll()方法,并传入我们需要分页的条件。

1.2.1 调用

//返回分页数据
@GetMapping(path = "users")
@ResponseBody
@WebLog(printResult = true)
public Page<UserInfo> getAllUsers(){
    Page<UserInfo> all = userRepository.findAll(PageRequest.of(0, 3));
    return all;
}

1.2.2 返回结果为:

{
	"content": [
		{
			"id": 2,
			"address": "??",
			"name": "luke",
			"age": 18
		},
		{
			"id": 3,
			"address": "??",
			"name": "luke",
			"age": 18
		},
		{
			"id": 4,
			"address": "??",
			"name": "luke",
			"age": 18
		}
	],
	"pageable": {
		"sort": {
			"sorted": false, //是否排序
			"unsorted": true, //没有排序
			"empty": true 
		},
		"pageNumber": 0, //当前页码
		"pageSize": 3, //每页大小
		"offset": 0, //偏移量
		"paged": true, //是否分页
		"unpaged": false //
	},
	"last": false, //是否最后一页
	"totalPages": 2, //总页码
	"totalElements": 6, //一共多少条数据
	"number": 0, //当前页
	"sort": {
		"sorted": false,
		"unsorted": true,
		"empty": true
	},
	"first": true, //是否第一页
	"numberOfElements": 3, //获取到了第几条
	"size": 3, 当前页大小
	"empty": false //是否有数据
}

可以看到,当返回结果为Page的时候,返回结果携带了分页的信息。

  • content是我们返回的数据的内容
  • pageable分页有关的信息

1.3 返回Slice结果

需要返回Slice的话,也需要调用我们上边写的方法。

1.3.1 调用

//返回Slice类型结果
@GetMapping(path = "users")
@ResponseBody
@WebLog(printResult = true)
public Slice<UserInfo> getAllUsers(){
    Slice<UserInfo> all = userRepository.findAllUserInfo(PageRequest.of(0, 2));
    return all;
}

1.3.2 返回结果如下

{
	"content": [
		{
			"id": 2,
			"address": "??",
			"name": "luke",
			"age": 18
		},
		{
			"id": 3,
			"address": "??",
			"name": "luke",
			"age": 18
		}
	],
	"pageable": {
		"sort": {
			"sorted": false,
			"unsorted": true,
			"empty": true
		},
		"offset": 0,
		"pageSize": 2,
		"pageNumber": 0,
		"paged": true,
		"unpaged": false
	},
	"size": 2,
	"number": 0,
	"sort": {
		"sorted": false,
		"unsorted": true,
		"empty": true
	},
	"first": true,
	"last": false,
	"numberOfElements": 2,
	"empty": false
}

为了与之前的Page区分,特意将每页的数据更改为了2个,可以看出,这里少了与total相关的数据。Slice和Page的区别就是Page会额外执行一条查询total的sql,来返回与total有关的数据

1.4 返回List结果

当然也可以直接返回List结果,

1.4.1 调用

//返回List类型结果
@GetMapping(path = "users")
@ResponseBody
@WebLog(printResult = true)
public List<UserInfo> getAllUsers(){
    List<UserInfo> all = userRepository.findAll();
    return all;
}

1.4.2 返回结果如下

[
	{
		"id": 2,
		"address": "??",
		"name": "luke",
		"age": 18
	},
	{
		"id": 3,
		"address": "??",
		"name": "luke",
		"age": 18
	},
	{
		"id": 999,
		"address": "陕西",
		"name": "小明",
		"age": 18
	}
]

这里没有分页和排序信息,只是user的一个list

2 自定义返回结果

上边说了Repository的不同返回类型,可是除了Entity,还可以返回POJO。

看看我们的UserInfo类

@Entity
@Data
public class UserInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private String address;
    private String name;
    private Integer age;
}

若是我们查询的时候,只想要Id和name属性,那该如何操作呢? 首先,定义一个UserOnlyName的接口

2.1 UserOnlyName

public interface UserOnlyName {
    Integer getId();
    String getName();
}

2.2 UserRepository

public interface UserRepository extends JpaRepository<UserInfo,Integer> {
    UserOnlyName findByName(String name);
}

2.3 调用

@GetMapping(path = "users")
@ResponseBody
@WebLog(printResult = true)
public UserOnlyName getUsers(){
    UserOnlyName byName = userRepository.findByName("小明");
    return byName;
}

2.4 返回

{
	"name": "小明",
	"id": 999
}

这里只返回了我们需要的id和name信息。