本文章来自【知识林】
在网站系统的开发过程中经常会用到排序操作,下面就我个人的理解介绍一下使用强大的JPA
是如何进行排序的。
基础搭建
- pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
- application.properties
server.port=80
# Hibernate 相关配置
## 自动扫描的包前缀
entitymanager.packagesToScan= com.zslin
## 数据库连接
spring.datasource.url=jdbc:mysql://localhost:3306/study05?\
useUnicode=true&characterEncoding=utf-8&useSSL=true&autoReconnect=true
## 用户名
spring.datasource.username=root
## 密码
spring.datasource.password=123
## 数据库驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
## 建表方式
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
- 项目入口
package com.zslin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Created by 钟述林 393156105@qq.com on 2016/10/21 10:54.
*/
@SpringBootApplication
public class RootApplication {
public static void main(String [] args) {
SpringApplication.run(RootApplication.class, args);
}
}
- 数据实体对象
package com.zslin.model;
import javax.persistence.*;
/**
*
* Created by 钟述林 393156105@qq.com on 2016/10/21 10:55.
*/
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "user_name")
private String userName;
private String password;
@Column(name = "nick_name")
private String nickName;
private String email;
……省去get和set方法……
}
- 数据接口
package com.zslin.service;
import com.zslin.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Created by 钟述林 393156105@qq.com on 2016/10/21 10:56.
*/
public interface IUserService extends JpaRepository<User, Integer> {
}
以上这些配置在前面很多测试例子中都已描述过,在此不再做过多赘述。
数据准备
package com.zslin;
import com.zslin.model.User;
import com.zslin.service.IUserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Created by 钟述林 393156105@qq.com on 2016/10/21 11:08.
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserInitTest {
@Autowired
private IUserService userService;
@Test
public void initTest() {
for(int i=1; i<=10; i++) {
User u = new User();
u.setEmail("email"+i+"@domain.com");
u.setPassword("pwd"+i);
u.setUserName("user"+i);
u.setNickName("nickname"+i);
userService.save(u);
}
}
}
先初始化10条数据到数据库中,方便后面做排序和分布的操作。
排序
- 基本测试
@Test
public void testPage() {
Sort sort = new Sort(Sort.Direction.DESC, "id");
List<User> list = userService.findAll(sort);
for(User u : list) {
System.out.println(u.getUserName());
}
}
注意: 当继承JpaRepository
之后,IUserService
拥有了几个findAll()
的重载方法,其中一个可以传Sort
对象,该方法则是排序的方法。
Sort sort = new Sort(Sort.Direction.DESC, "id");
:表示通过id
进行降序排序,将DESC
换成ASC
则表示升序,将id
换成其他User
对象的属性后,则通过其他字段排序。
- 单排序封装
为更好的使用排序功能,可将Sort
进行二次封装以解决代码重用的问题。
public class SortTools {
public static Sort basicSort() {
return basicSort("desc", "id");
}
public static Sort basicSort(String orderType, String orderField) {
Sort sort = new Sort(Sort.Direction.fromString(orderType), orderField);
return sort;
}
}
这样封装的好处是:不用每次进行排序时都new个Sort对象作为参数传入;比较方便灵活的根据自己需求传入要排序的方式与字段。
封装后的测试方法:
@Test
public void testSort2() {
List<User> list = userService.findAll(SortTools.basicSort());
for(User u : list) {
System.out.println(u.getUserName());
}
}
@Test
public void testSort3() {
List<User> list = userService.findAll(SortTools.basicSort("desc", "userName"));
for(User u : list) {
System.out.println(u.getUserName());
}
}
- 多排序封装
上面的封装方法只能满足单一排序的需求,如果有多条件排序就无法满足了,下面改进一下封装:
- 创建Sort的DTO对象
package com.zslin.tools;
/**
* Created by 钟述林 393156105@qq.com on 2016/10/21 11:41.
*/
public class SortDto {
//排序方式
private String orderType;
//排序字段
private String orderField;
public String getOrderField() {
return orderField;
}
public void setOrderField(String orderField) {
this.orderField = orderField;
}
public String getOrderType() {
return orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
public SortDto(String orderType, String orderField) {
this.orderType = orderType;
this.orderField = orderField;
}
//默认为DESC排序
public SortDto(String orderField) {
this.orderField = orderField;
this.orderType = "desc";
}
}
- 增加basicSort方法
public static Sort basicSort(SortDto... dtos) {
Sort result = null;
for(int i=0; i<dtos.length; i++) {
SortDto dto = dtos[i];
if(result == null) {
result = new Sort(Sort.Direction.fromString(dto.getOrderType()), dto.getOrderField());
} else {
result = result.and(new Sort(Sort.Direction.fromString(dto.getOrderType()), dto.getOrderField()));
}
}
return result;
}
- 测试方法
@Test
public void testSort4() {
List<User> list = userService.findAll(SortTools.basicSort(new SortDto("desc", "userName"), new SortDto("id")));
for(User u : list) {
System.out.println(u.getId()+"===="+u.getUserName());
}
}
上面这个测试方法就是首先按userName
的降序排,再按id
的降序排,在此basicSort
方法中可以传任意个new SortDto()
示例代码:https://github.com/zsl131/spring-boot-test/tree/master/study08
本文章来自【知识林】