易用宝项目记录day1-springdatajpa
SpringDataJpa
SpringDataJpa继承自SpringData,使数据库交互更加简单
1.配置SSJ的pom.xml文件
-
SpringDataJpa导入
<!-- SpringData的支持包 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>${spring-data-jpa.version}</version> </dependency>
-
总的配置:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 版本控制,使以后方便更换版本 -->
<org.springframework.version>4.2.5.RELEASE</org.springframework.version>
<org.hibernate.version>4.3.8.Final</org.hibernate.version>
<spring-data-jpa.version>1.9.0.RELEASE</spring-data-jpa.version>
<com.fasterxml.jackson.version>2.5.0</com.fasterxml.jackson.version>
<org.slf4j.version>1.6.1</org.slf4j.version>
</properties>
<dependencies>
<!-- Spring的支持包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<!-- 引入web前端的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- SpringMCV上传需要用到io包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 文件上传用到的包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!-- SpringMVC的json支持包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${com.fasterxml.jackson.version}</version>
</dependency>
<!-- hibernate的支持包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${org.hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${org.hibernate.version}</version>
</dependency>
<!-- SpringData的支持包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data-jpa.version}</version>
</dependency>
<!-- SpringData的扩展包 -->
<dependency>
<groupId>com.github.wenhao</groupId>
<artifactId>jpa-spec</artifactId>
<version>3.1.1</version>
<!-- 把所有的依赖都去掉 -->
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<!-- 測試包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!-- 这个scope 只能作用在编译和测试时,同时没有传递性。表示在运行的时候不添加此jar文件 -->
<scope>provided</scope>
</dependency>
<!-- 日志文件 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<!-- 代码生成器模版技术 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6</version>
</dependency>
<!-- shiro的支持包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.4.0</version>
<type>pom</type>
</dependency>
<!-- shiro与Spring的集成包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- poi支持的jar包 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11</version>
</dependency>
<!-- 图片压缩功能 -->
<!-- 缩略图 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.6</version>
</dependency>
<!-- 定时调度 -->
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.2</version>
</dependency>
<!-- 邮件支持 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
2.配置SSJ的applicationContext.xml文件和连接池
-
<!--读取jdbc.properties--> <context:property-placeholder location="classpath:jdbc.properties"/>
配置的是连接池
jdbc.properties连接池代码:
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/yxb jdbc.username=root jdbc.password=xrj5201314
-
SpringDateJpa导入
<!-- 配置SpringDataJpa -> 让某一层的代码支持SpringDataJpa 只要发现咱们的接口继承了JpaRepository,它就会自动去完成相应的CRUD --> <jpa:repositories base-package="cn.xiaji.repository" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
-
总的配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd "> <!-- 1.jdbc.properties 2.连接池 3.EntityManagerFactory 4.dao层 5.service层 6.事务(都是开在service层的) 7.集成springMVC 8.EasyUI --> <!--service的扫描--> <context:component-scan base-package="cn.xiaji.service" /> <!--读取jdbc.properties--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--配置连接池--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!--配置EntityManagerFactory 快捷键alt+insert选第二个--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <!--连接数据库--> <property name="dataSource" ref="dataSource"/> <!--packagesToScan:包的扫描--> <property name="packagesToScan" value="cn.xiaji.domain"/> <!--jpaVendorAdapter:适配器(hibernate,openjpa...确定jpa是那种框架实现的)--> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <!--方言--> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/> <!--是否显示sql--> <property name="showSql" value="true"/> <!-- 建表策略 DDL:建表建库策略 true:相当于update false:相当于啥都不做 --> <property name="generateDdl" value="false"/> </bean> </property> </bean> <!--配置相应的事务对象--> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!--配置事务的支持 annotation-driven:支持事务的注解--> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置SpringDataJpa -> 让某一层的代码支持SpringDataJpa 只要发现咱们的接口继承了JpaRepository,它就会自动去完成相应的CRUD --> <jpa:repositories base-package="cn.xiaji.repository" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" /> </beans>
3.domian层的创建
-
由于我们的表都有id字段,所以抽取一个BaseDomain出来,方便简化代码,使结构更加清晰
注意:为了不多创建表,让其他子类知道是父类,所以加上注解@MappedSuperclass
package cn.xiaji.domain; //encoding: utf-8 import javax.persistence.*; /** * @author: xj * @contact: xiaruji520@gmail.com * @file: Employee.java */ @MappedSuperclass//让其他子类知道是父类 public class BaseDomain { @Id//对应表的主键 @GeneratedValue//自动增长 protected Long id; public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
-
Employee表继承BaseDomain
package cn.xiaji.domain; //encoding: utf-8 import javax.persistence.*; import java.util.ArrayList; import java.util.List; /** * @author: xj * @contact: xiaruji520@gmail.com * @file: Employee.java */ @Entity//表示一个由jpa管理的持久对象,对应数据库的一个表 @Table(name = "employee")//table数据库的表名 public class Employee extends BaseDomain { private String username; private String password; private String email; private String headImage; @Column(length = 11) private Integer age; @ManyToMany @JoinTable( name = "employee_role", joinColumns = @JoinColumn(name = "employee_id"), inverseJoinColumns = @JoinColumn(name = "role_id") ) private List<Role> roles = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "department_id") private Department department; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getHeadImage() { return headImage; } public void setHeadImage(String headImage) { this.headImage = headImage; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public String toString() { return "Employee{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + ", headImage='" + headImage + '\'' + ", age=" + age + '}'; } }
4.在cn.xiaji.repository包(相当于cn.xiaji.dao包)里添加相应的接口
-
注意:
-
只要发现接口继承了JpaRepository,它就会自动去完成相应的CRUD
Employee:CRUD操作的哪一个类型 Long:主键的类型
-
JpaSpecificationExecutor(JPA规则执行者):也是一直curd接口,更符合面向对象的思想,但是写着麻烦
public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> { ... }
-
-
总的代码:
package cn.xiaji.repository;
import cn.xiaji.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/*
只要发现接口继承了JpaRepository,它就会自动去完成相应的CRUD
Employee:CRUD操作的哪一个类型 Long:主键的类型
*/
public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> {
//根据用户名查询
Employee findByUsername(String uername);
//根据用户名模糊查询
List<Employee> findByUsernameLike(String uername);
//根据用户名与邮件模糊查询
List<Employee> findByUsernameLikeAndEmailLike(String uername, String email);
/*----------------------------------------------------------------*/
//根据用户名查询
@Query("select o from Employee o where o.username=?1")
Employee queryByUsername(String username);
//根据用户名模糊查询
@Query("select o from Employee o where o.username like ?1")
List<Employee> queryByUsernameLike(String uername);
//根据用户名与邮件模糊查询
@Query("select o from Employee o where o.username like ?1 and o.email like ?2")
List<Employee> queryByUsernameAndEmailLike(String uername, String email);
}
4.抽取Query包
-
与domian层的抽取BaseDomain一样,抽取BaseQuery来方便代码扩展
package cn.xiaji.query; //encoding: utf-8 import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; /** * @author: xj * @contact: xiaruji520@gmail.com * @file: BaseQuery.java */ public abstract class BaseQuery { //当前页 private int currentPage = 1; //每页条数 private int pageSize = 1; //排序字段名 private String orderName; //排序规则 private String orderType = "ASC"; //写个抽象方法去规范子类获取Specification对象的名称 必需叫createSpec public abstract Specification createSpec(); public Sort createSort() { if (StringUtils.isNotBlank(orderName)) { //toUpperCase()转为大写 return new Sort(Sort.Direction.valueOf(orderType.toUpperCase()), orderName); } return null; } public int getCurrentPage() { return currentPage; } //第一页 从0开始算的 public int getJpaCurrentPage() { return currentPage - 1; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName; } public String getOrderType() { return orderType; } public void setOrderType(String orderType) { this.orderType = orderType; } }
-
子类的继承
package cn.xiaji.query; //encoding: utf-8 import cn.xiaji.domain.BaseDomain; import cn.xiaji.domain.Employee; import com.github.wenhao.jpa.Specifications; import org.apache.commons.lang3.StringUtils; import org.springframework.data.jpa.domain.Specification; /** * @author: xj * @contact: xiaruji520@gmail.com * @file: EmployeeQuery.java */ public class EmployeeQuery extends BaseQuery { private String username; private String email; private Integer age; //返回查询条件 public Specification createSpec() { Specification<Employee> build = Specifications.<Employee>and() .like(StringUtils.isNotBlank(username), "username", "%" + username + "%") .like(StringUtils.isNotBlank(email), "email", "%" + email + "%") .gt(age != null, "age", age) .build(); return build; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
5.测试curd
-
直接用JpaRepository自带的
@Autowired//引入EmployeeRepository接口 private EmployeeRepository employeeRepository; @Test public void testAdd() throws Exception { Employee employee = new Employee(); employee.setAge(12); Employee save = employeeRepository.save(employee); System.out.println(save); } @Test public void testUpdate() throws Exception { Employee employee = new Employee(); employee.setId(274L); employee.setAge(22); Employee save = employeeRepository.save(employee); System.out.println(save); } @Test public void testDelete() throws Exception { employeeRepository.delete(274L); } @Test public void testFindOne() throws Exception { Employee one = employeeRepository.findOne(1L); System.out.println(one); } @Test public void testFindAll() throws Exception { List<Employee> list = employeeRepository.findAll(); list.forEach(e -> System.out.println(e)); } /*分页测试*/ @Test public void testPage() throws Exception { /* int page:当前页(0开始计算的) int size:每页条数 */ Pageable pageable = new PageRequest(0, 10); Page<Employee> page = employeeRepository.findAll(pageable); page.forEach(e -> System.out.println(e)); //总条数 System.out.println(page.getTotalElements()); //总页数 System.out.println(page.getTotalPages()); //当前页数 System.out.println(page.getNumber()); //当前页的数量 System.out.println(page.getNumberOfElements()); //每条页数 System.out.println(page.getSize()); } /*排序*/ @Test public void testSort() throws Exception { /* 第一个参数:排序规则 第二个参数:排序字段 */ Sort sort = new Sort(Sort.Direction.DESC, "age"); List<Employee> list = employeeRepository.findAll(sort); list.forEach(e -> System.out.println(e)); } /*分页加排序*/ @Test public void testPageSort() throws Exception { Sort sort = new Sort(Sort.Direction.DESC, "age"); Pageable pageable = new PageRequest(0, 10, sort); Page<Employee> page = employeeRepository.findAll(pageable); page.forEach(e -> System.out.println(e)); } /*根据用户名查询*/ @Test public void testFindByUsername() throws Exception { Employee employee = employeeRepository.findByUsername("admin"); System.out.println(employee); } /*根据用户名模糊查询*/ @Test public void testFindByUsernameLike() throws Exception { List<Employee> like = employeeRepository.findByUsernameLike("%admin%"); like.forEach(e -> System.out.println(e)); } /*根据用户名和邮件模糊查询*/ @Test public void testFindByUsernameLikeAndEmailLike() throws Exception { List<Employee> like = employeeRepository.findByUsernameLikeAndEmailLike("%admin%", "%2%"); like.forEach(e -> System.out.println(e)); }
-
自己扩展的
/*根据用户名查询*/ @Test public void testFindQueryUsername() throws Exception { Employee employee = employeeRepository.queryByUsername("admin"); System.out.println(employee); } /*根据用户名模糊查询*/ @Test public void testFindQueryUsernameLike() throws Exception { List<Employee> like = employeeRepository.queryByUsernameLike("%admin%"); like.forEach(e -> System.out.println(e)); } /*根据用户名和邮件模糊查询*/ @Test public void testFindQueryUsernameAndEmailLike() throws Exception { List<Employee> like = employeeRepository.queryByUsernameAndEmailLike("%admin%", "%2%"); like.forEach(e -> System.out.println(e)); }
-
JpaSpecificationExecutor接口来写的(不写SQL也能够完成功能)
/*根据用户名模糊查询*/ @Test public void testJpaSpecificationExecutor() throws Exception { /* 根据相应的规则(Specification)去查询对应的数据 Predicate(谓语): where xxx=? and yyy=? Root:可以获取类中相应的属性(拿到xxx,yyy) CriteriaQuery:如select,from,where,group by ,order by等 CriteriaBuilder:解决 xxx=?或者xxx like ?或者 xxx>?... 多个条件结合 xxx=? and/or yyy >?... */ List<Employee> list = employeeRepository.findAll(new Specification<Employee>() { @Override public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.使用root去拿username属性 Path username = root.get("username"); //2.对这个属性添加查询规则 Predicate like = criteriaBuilder.like(username, "%1%"); return like; } }); list.forEach(e -> System.out.println(e)); } /*根据多个条件模糊查询*/ @Test public void testJpaSpecificationExecutor2() throws Exception { List<Employee> list = employeeRepository.findAll(new Specification<Employee>() { @Override public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //使用root去拿username属性 Path username = root.get("username"); //对这个属性添加查询规则 Predicate like1 = criteriaBuilder.like(username, "%1%"); //使用root去拿email属性 Path email = root.get("email"); //对这个属性添加查询规则 Predicate like2 = criteriaBuilder.like(email, "%2%"); //多个条件连接起来 Predicate and = criteriaBuilder.and(like1, like2); return and; } }); list.forEach(e -> System.out.println(e)); } /*模糊查询+分页+排序*/ @Test public void testJpaSpecificationExecutor3() throws Exception { //排序 Sort sort = new Sort(Sort.Direction.DESC, "age"); //分页 Pageable pageable = new PageRequest(0, 5, sort); Page<Employee> page = employeeRepository.findAll(new Specification<Employee>() { @Override public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //使用root去拿username属性 Path username = root.get("username"); //对这个属性添加查询规则 Predicate like = criteriaBuilder.like(username, "%1%"); return like; } }, pageable); page.forEach(e -> System.out.println(e)); }
-
JpaSpecificationExecutor接口写比较麻烦,有人封装了,下面就是
注意:导入的包是com.github.wenhao.jpa.Specifications
//别人的包 @Test public void testJpaSpec() throws Exception { Specification<Employee> username = Specifications.<Employee>and() .like("username", "%1%") .like("email", "%2%") .gt("age", 20) .build(); //查询 List<Employee> list = employeeRepository.findAll(username); list.forEach(e -> System.out.println(e)); } @Test public void testJpaSpec2() throws Exception { //排序 Sort sort = new Sort(Sort.Direction.DESC, "age"); //分页 Pageable pageable = new PageRequest(0, 5, sort); Specification<Employee> username = Specifications.<Employee>and() .like("username", "%1%") // .like("email", "%2%") // .gt("age", 20) .build(); //查询 Page<Employee> page = employeeRepository.findAll(username, pageable); page.forEach(e -> System.out.println(e)); }
-
Query的测试(分页+查询+排序)
//测试 @Test public void testJpaSpecPageQuery() throws Exception { //模拟前台传参 EmployeeQuery query = new EmployeeQuery(); query.setUsername("1"); //query.setEmail("2"); //query.setAge(20); query.setOrderName("age"); query.setOrderType("DESC"); //从Query中获取到这个对象 Specification spec = query.createSpec(); //排序 Sort sort = query.createSort(); //分页 query.setCurrentPage(1); query.setPageSize(5); Pageable pageable = new PageRequest(query.getJpaCurrentPage(), query.getPageSize(),sort); Page page = employeeRepository.findAll(spec, pageable); page.forEach(e -> System.out.println(e)); }