三、SpringDataJPA介绍
1. 入门案例
1.1 创建项目
创建一个普通的Maven项目
1.2 添加相关的依赖
代码语言:javascript复制 <dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.7.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
</dependencies>
1.3 添加配置文件
代码语言:javascript复制jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/logistics?characterEncoding=utf-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
Spring的配置文件
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"
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
">
<!-- 引入db.properties文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 创建druid 的数据源 -->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="url" value="${jdbc.url}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 配置Hibernate的SessionFactory对象 id必须得是 : entityManagerFactory -->
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<!-- 关联数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置Hibernate的属性信息 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
<property name="generateDdl" value="true"/>
<property name="showSql" value="true"/>
</bean>
<!--<props>
<prop key="show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>-->
</property>
<!-- 扫描路径 -->
<property name="packagesToScan">
<list>
<value>com.bobo.pojo</value>
</list>
</property>
</bean>
<!-- 配置事务管理-->
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 配置开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 配置扫描路径 -->
<context:component-scan base-package="com.bobo" />
<!-- Spring Data Jpa 配置-->
<!-- 配置Dao的扫描 -->
<jpa:repositories base-package="com.bobo.dao" />
</beans>
1.4 创建POJO对象
代码语言:javascript复制package com.bobo.pojo;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name="t_user")
public class Users implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="user_id")
private Integer userId;
@Column(name="user_name")
private String userName;
@Column(name="real_name")
private String realName;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
@Override
public String toString() {
return "Users{"
"userId=" userId
", userName='" userName '''
", realName='" realName '''
'}';
}
}
1.5 创建持久层
代码语言:javascript复制import com.bobo.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDao extends JpaRepository<Users,Integer> {
}
1.6 单元测试
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDao;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
@Autowired
private UserDao dao;
@Test
@Transactional
@Rollback(false)
public void test1(){
Users user = new Users();
user.setUserName("admin-jpa");
user.setRealName("测试");
dao.save(user);
}
}
2. Repository接口
代码语言:javascript复制public interface Repository<T, ID extends Serializable> {
}
Repository 接口是 Spring Data JPA 中为我我们提供的所有接口中的顶层接口,而且是个标志接口,Repository 提供了两种查询方式的支持 1)基于方法名称命名规则查询 2)基于@Query 注解查询
2.1 基于方法名称命名规则查询
代码语言:javascript复制package com.bobo.dao;
import com.bobo.pojo.Users;
import org.springframework.data.repository.Repository;
import javax.persistence.criteria.CriteriaBuilder;
import java.util.List;
/**
* Repository接口的使用
*/
public interface UserDaoRepository extends Repository<Users, Integer> {
List<Users> findByUserNameIs(String string);
List<Users> findByUserNameLike(String username);
List<Users> findByUserNameAndRealNameIs(String name,String realName);
}
测试代码
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDaoRepository;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test2 {
@Autowired
private UserDaoRepository dao;
@Test
@Transactional
@Rollback(false)
public void query1(){
List<Users> list = this.dao.findByUserNameIs("Tom");
for (Users users : list) {
System.out.println(users);
}
}
@Test
@Transactional
@Rollback(false)
public void query2(){
List<Users> list = this.dao.findByUserNameLike("Tom");
for (Users users : list) {
System.out.println(users);
}
}
@Test
@Transactional
@Rollback(false)
public void query3(){
List<Users> list = this.dao.findByUserNameAndRealNameIs("Tom","张三丰");
for (Users users : list) {
System.out.println(users);
}
}
}
2.2 基于@Query 注解查询
通过上面的命令的方式使用的情况,如果查询条件比较复杂的情况下,那么方法的名称会很长,不是很方便而且容易出错,这时我们可以通过@Query注解来实现
2.2.1 JPQL语句
JPQL:是通过Hibernate的HQL语句演变而来的,他和HQL语句很相似
代码语言:javascript复制/**
* Repository接口的使用
* @Query
* JPQL语句
* SQL语句
* 更新操作
*/
public interface UserDaoRepository2 extends Repository<Users, Integer> {
@Query(value = " from Users where userName =?")
List<Users> queryUsersByNameUseJPQL(String name);
@Query(value = " from Users where userName like ?")
List<Users> queryUserLikeNameUseJPQL(String name);
@Query(value = " from Users where userName= ? and realName = ?")
List<Users> queryUserByNameAndRealName(String userName,String realName);
}
单元测试
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDaoRepository;
import com.bobo.dao.UserDaoRepository2;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test3 {
@Autowired
private UserDaoRepository2 dao;
@Test
@Transactional
@Rollback(false)
public void query1(){
List<Users> list = this.dao.queryUsersByNameUseJPQL("Tom");
for (Users users : list) {
System.out.println(users);
}
}
@Test
@Transactional
@Rollback(false)
public void query2(){
List<Users> list = this.dao.queryUserLikeNameUseJPQL("Tom");
for (Users users : list) {
System.out.println(users);
}
}
@Test
@Transactional
@Rollback(false)
public void query3(){
List<Users> list = this.dao.queryUserByNameAndRealName("Tom","张三丰");
for (Users users : list) {
System.out.println(users);
}
}
}
2.2.2 SQL语句
声明接口
代码语言:javascript复制package com.bobo.dao;
import com.bobo.pojo.Users;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
/**
* Repository接口的使用
* @Query
* JPQL语句
* SQL语句
* 更新操作
*/
public interface UserDaoRepository3 extends Repository<Users, Integer> {
// 在使用@Query注解 查询SQL语句的时候 nativeQuery默认是false,我们需要设置为true
@Query(value = "select * from t_user where user_name=?",nativeQuery = true)
List<Users> queryUsersByNameUseSQL(String name);
@Query(value = "select * from t_user where user_name like ?" ,nativeQuery = true)
List<Users> queryUserLikeNameUseSQL(String name);
@Query(value = "select * from t_user where user_name = ? and real_name = ?" , nativeQuery = true)
List<Users> queryUserByNameAndRealName(String userName,String realName);
}
单元测试
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDaoRepository2;
import com.bobo.dao.UserDaoRepository3;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test4 {
@Autowired
private UserDaoRepository3 dao;
@Test
@Transactional
@Rollback(false)
public void query1(){
List<Users> list = this.dao.queryUsersByNameUseSQL("Tom");
for (Users users : list) {
System.out.println(users);
}
}
@Test
@Transactional
@Rollback(false)
public void query2(){
List<Users> list = this.dao.queryUserLikeNameUseSQL("Tom");
for (Users users : list) {
System.out.println(users);
}
}
@Test
@Transactional
@Rollback(false)
public void query3(){
List<Users> list = this.dao.queryUserByNameAndRealName("Tom","张三丰");
for (Users users : list) {
System.out.println(users);
}
}
}
2.2.3 完成更新数据
@Query注解可以完成数据更新操作,但是不能实现数据的添加和删除操作
代码语言:javascript复制 @Query(value = "update Users set userName = ? where userId=?")
@Modifying// 被@Modifying修饰的方法是一个更新操作
void updateUserNameById(String userName,Integer userId);
测试
代码语言:javascript复制 @Test
@Transactional
@Rollback(false)
public void updateTest(){
this.dao.updateUserNameById("Tommm",25);
}
3. CrudRepository接口
CrudRepository接口继承自Repository接口,所以Repository接口具有的功能CrudRepository接口都具有,而且又扩展了CRUD相关的功能
代码语言:javascript复制
@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S var1);
<S extends T> Iterable<S> save(Iterable<S> var1);
T findOne(ID var1);
boolean exists(ID var1);
Iterable<T> findAll();
Iterable<T> findAll(Iterable<ID> var1);
long count();
void delete(ID var1);
void delete(T var1);
void delete(Iterable<? extends T> var1);
void deleteAll();
}
应用声明接口
代码语言:javascript复制/**
* CrudRepository接口的使用
*/
public interface UserDaoCrudRepository extends CrudRepository<Users,Integer> {
}
单元测试
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDaoCrudRepository;
import com.bobo.dao.UserDaoRepository3;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.experimental.theories.suppliers.TestedOn;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.support.CustomSQLErrorCodesTranslation;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test5 {
@Autowired
private UserDaoCrudRepository dao;
/**
* 添加数据
*/
@Test
public void test1(){
Users user = new Users();
user.setRealName("成龙");
user.setUserName("chengnong");
dao.save(user);
}
/**
* 批量添加数据
*/
@Test
public void test2(){
List<Users> list = new ArrayList<>();
for (int i = 0; i < 10; i ) {
Users user = new Users();
user.setRealName("成龙" i);
user.setUserName("chengnong" i);
list.add(user);
}
dao.save(list);
}
/**
* 查询单条数据
*/
@Test
public void test3(){
Users user = dao.findOne(25);
System.out.println(user);
}
/**
* 查询所有的数据
*/
@Test
public void test4(){
Iterable<Users> list = dao.findAll();
Iterator<Users> iterator = list.iterator();
while(iterator.hasNext()){
Users user = iterator.next();
System.out.println(user);
}
}
/**
* 删除数据
*/
@Test
public void delete1(){
dao.delete(32);
}
/**
* 更新数据
*/
@Test
public void update1(){
// 根据save方法来实现 如果Users对象的userId属性不为空则update
Users user = dao.findOne(34);
user.setUserName("hahahaha");
dao.save(user);
}
/**
* 更新数据 方式二
*/
@Test
@Transactional
@Rollback(false)
public void update2(){
Users user = dao.findOne(34);
user.setUserName("aaaa"); // User 是一个持久化的状态
}
}
4.PagingAndSortingRepository接口
PagingAndSortingRepository继承自CrudRepository接口,那么显然PagingAndSortingRepository就具备了CrudRepository接口的相关的功能,同时也扩展了分页和排序的功能
代码语言:javascript复制@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
// 排序的支持
Iterable<T> findAll(Sort var1);
// 分页的支持
Page<T> findAll(Pageable var1);
}
创建接口文件
代码语言:javascript复制package com.bobo.dao;
import com.bobo.pojo.Users;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* PagingAndSortingRepository接口的使用
* 新增的功能是
* 分页
* 排序
* 注意本接口不支持条件查询
*/
public interface UserDaoPageAndSortRepository extends PagingAndSortingRepository<Users,Integer> {
}
分页测试
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDaoCrudRepository;
import com.bobo.dao.UserDaoPageAndSortRepository;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test6 {
@Autowired
private UserDaoPageAndSortRepository dao;
/**
* 分页查询
*/
@Test
public void test1(){
int page = 1; // page:当前分页的索引 从0开始
int size = 5; // size:每页显示的条数
PageRequest pageable = new PageRequest(page,size);
Page<Users> pages = dao.findAll(pageable);
System.out.println("总的条数:" pages.getTotalElements());
System.out.println("总的页数:" pages.getTotalPages());
List<Users> list = pages.getContent();
for (Users user : list) {
System.out.println(user);
}
}
}
排序功能
代码语言:javascript复制 /**
* 排序
*/
@Test
public void test2(){
// Sort.Direction.DESC 降序 ASC 升序
Sort sort = new Sort(Sort.Direction.DESC,"userId");
List<Users> list = (List<Users>) this.dao.findAll(sort);
for (Users users : list) {
System.out.println(users);
}
}
多条件排序
代码语言:javascript复制 /**
* 多条件排序
*/
@Test
public void test3(){
Sort.Order order1 = new Sort.Order(Sort.Direction.DESC,"realName");
Sort.Order order2 = new Sort.Order(Sort.Direction.ASC,"userId");
Sort sort = new Sort(order1,order2);
List<Users> list = (List<Users>) this.dao.findAll(sort);
for (Users users : list) {
System.out.println(users);
}
}
5. JpaRepository接口
JpaRepository接口是我们开发时使用最多接口,其特点是可以帮助我们将其他接口的方法的返回值做适配处理,可以使我们在开发的时候更方便的使用这些方法
代码语言:javascript复制@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAll(Iterable<ID> var1);
<S extends T> List<S> save(Iterable<S> var1);
void flush();
<S extends T> S saveAndFlush(S var1);
void deleteInBatch(Iterable<T> var1);
void deleteAllInBatch();
T getOne(ID var1);
}
6. JpaSpecificationExecutor
提供的有多条件查询,并支持分页和排序功能,此接口不能单独使用,需要和其他的接口一块使用
代码语言:javascript复制/**
* JpaSpecificationExecutor的使用
* JpaSpecificationExecutor 是不能够单独使用的。需要配置JPA中的其他的接口一块来使用
*/
public interface UserDaoSpecfication extends JpaRepository<Users,Integer>, JpaSpecificationExecutor {
}
6.1 单条件查询
代码语言:javascript复制package com.bobo.test;
import com.bobo.dao.UserDaoSpecfication;
import com.bobo.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test7 {
@Autowired
private UserDaoSpecfication dao;
@Test
public void test1(){
Specification<Users> speci = new Specification<Users>() {
/**
* 定义查询条件
* @param root 根对象 封装查询条件的对象
* @param criteriaQuery 基本的查询
* @param criteriaBuilder 创建查询条件
* @return
*/
@Override
public Predicate toPredicate(Root<Users> root
, CriteriaQuery<?> criteriaQuery
, CriteriaBuilder criteriaBuilder) {
Predicate pre = criteriaBuilder.equal(root.get("userName"),"Tommm");
return pre;
}
};
List<Users> list = dao.findAll(speci);
for (Users users : list) {
System.out.println(users);
}
}
}
6.2 多条件
代码语言:javascript复制 /**
* 多条件查询
*/
@Test
public void test2(){
Specification<Users> spec = new Specification<Users>() {
/**
* 指定查询的条件
* @param root
* @param criteriaQuery
* @param criteriaBuilder
* @return
*/
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> list = new ArrayList<>();
list.add(criteriaBuilder.equal(root.get("userName"),"Tommm"));
list.add(criteriaBuilder.equal(root.get("realName"),"张三丰"));
Predicate[] arr = new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(arr));
}
};
List<Users> list = dao.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}
6.3 分页
代码语言:javascript复制 /**
* 单条件 分页
*/
@Test
public void test3(){
Specification<Users> speci = new Specification<Users>() {
/**
* 定义查询条件
* @param root 根对象 封装查询条件的对象
* @param criteriaQuery 基本的查询
* @param criteriaBuilder 创建查询条件
* @return
*/
@Override
public Predicate toPredicate(Root<Users> root
, CriteriaQuery<?> criteriaQuery
, CriteriaBuilder criteriaBuilder) {
Predicate pre = criteriaBuilder.equal(root.get("userName"),"Tommm");
return pre;
}
};
Pageable pagealbe = (Pageable) new PageRequest(0,3);
Page page = dao.findAll(speci, pagealbe);
System.out.println(page.getTotalElements());
System.out.println(page.getTotalPages());
List content = page.getContent();
System.out.println(content);
}
6.4 排序
代码语言:javascript复制 /**
* 单条件 排序
*/
@Test
public void test4(){
Specification<Users> speci = new Specification<Users>() {
/**
* 定义查询条件
* @param root 根对象 封装查询条件的对象
* @param criteriaQuery 基本的查询
* @param criteriaBuilder 创建查询条件
* @return
*/
@Override
public Predicate toPredicate(Root<Users> root
, CriteriaQuery<?> criteriaQuery
, CriteriaBuilder criteriaBuilder) {
Predicate pre = criteriaBuilder.equal(root.get("userName"),"Tommm");
return pre;
}
};
Sort sort = new Sort(Sort.Direction.DESC,"userId");
List<Users> list = dao.findAll(speci, sort);
System.out.println(list);
}
6.5 分页和排序
代码语言:javascript复制 /**
* 单条件 分页 排序
*/
@Test
public void test5(){
Specification<Users> speci = new Specification<Users>() {
/**
* 定义查询条件
* @param root 根对象 封装查询条件的对象
* @param criteriaQuery 基本的查询
* @param criteriaBuilder 创建查询条件
* @return
*/
@Override
public Predicate toPredicate(Root<Users> root
, CriteriaQuery<?> criteriaQuery
, CriteriaBuilder criteriaBuilder) {
Predicate pre = criteriaBuilder.equal(root.get("userName"),"Tommm");
return pre;
}
};
Sort sort = new Sort(Sort.Direction.DESC,"userId");
// 封装分页对象的时候我们可以直接指定 排序的规则
Pageable pagealbe = (Pageable) new PageRequest(0,3,sort);
Page page = dao.findAll(speci, pagealbe);
System.out.println(page.getTotalElements());
System.out.println(page.getTotalPages());
List content = page.getContent();
System.out.println(content);
}