智能商贸项目Day01-集成SpringDataJpa
一、SpringDataJpa概念
- 是Spring的一个子框架,是JPA规范的再次封装抽象
- 集成Jpa,让操作数据库变得更加的简单
二、创建项目
(一)导包
- 能够看懂这里导入了哪些包
- 理解这些包是做什么的
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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>
<!-- Spring要集成邮件,定时器,模板技术等等 -->
<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>
<!--hibernate对于jpa的支持包-->
<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>
<!-- 对Java原生的lang包进行了扩展 -->
<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>
<build>
<finalName>Day1208_aisell</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.15.v20140411</version>
<configuration>
<stopPort>9966</stopPort>
<stopKey>foo</stopKey>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
</configuration>
</plugin>
</plugins>
</build>
</project>
(二)Spring与Jpa的集成
1.配置jdbc.propeties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///pss
jdbc.username=root
jdbc.password=123456
2.配置applicationContext.xml
<?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
">
<!--扫描dao层
只要发现它扫描到的接口继承了Repository
就会自动完成相应功能(实现类就有了)
-->
<jpa:repositories base-package="com.lty.aisell.repository"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager">
</jpa:repositories>
<!--扫描service层-->
<context:component-scan base-package="com.lty.aisell.service"></context:component-scan>
<!--引入jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--配置dataSource,销毁时关闭-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--配置连接数据库:驱动、url、用户名、密码 -->
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置EntityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--数据源-->
<property name="dataSource" ref="dataSource"/>
<!--扫描包-->
<property name="packagesToScan" value="com.lty.aisell.domain"></property>
<!--JPA适配器-->
<property name="jpaVendorAdapter">
<!--使用的是Hibernate-->
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--建表策略(true相当于update;false什么都不做)-->
<property name="generateDdl" value="false"></property>
<!--方言-->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"></property>
<!--显示sql语句-->
<property name="showSql" value="true"></property>
</bean>
</property>
</bean>
<!--创建一个JPA事务对象-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--支持事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
- 可以根据需求在配置连接数据中加入其它属性
<!--maxActive: 最大连接数量 -->
<property name="maxActive" value="150" />
<!--minIdle: 最小空闲连接 -->
<property name="minIdle" value="5" />
<!--maxIdle: 最大空闲连接 -->
<property name="maxIdle" value="20" />
<!--initialSize: 初始化连接 -->
<property name="initialSize" value="30" />
<!-- 用来配置数据库断开后自动连接的 -->
<!-- 连接被泄露时是否打印 -->
<property name="logAbandoned" value="true" />
<!--removeAbandoned: 是否自动回收超时连接 -->
<property name="removeAbandoned" value="true" />
<!--removeAbandonedTimeout: 超时时间(以秒数为单位) -->
<property name="removeAbandonedTimeout" value="10" />
<!--maxWait: 超时等待时间以毫秒为单位 1000等于60秒 -->
<property name="maxWait" value="1000" />
<!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. -->
<property name="timeBetweenEvictionRunsMillis" value="10000" />
<!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
<property name="numTestsPerEvictionRun" value="10" />
<!-- 1000 * 60 * 30 连接在池中保持空闲而不被空闲连接回收器线程 -->
<property name="minEvictableIdleTimeMillis" value="10000" />
<property name="validationQuery" value="SELECT NOW() FROM DUAL" />
(三)集成SpringDataJpa
1.Domain
- 父类
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
/*
*泛化:继承关系
*在JPA中,domain的父类必需要加@MappedSuperclass
*非常明确定的告诉JPA,这是一个用于映射的父类,不持久化到表
*/
@MappedSuperclass
public class BaseDoamin {
@Id
@GeneratedValue
protected Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
- 子类
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee extends BaseDoamin{
private String username;
private String password;
private String email;
private Integer age;
//省略getter,setter与toString
}
2.Repository接口
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
*必需继承JpaRepository<1v,2v>
* 第一个泛型:代表类型(对哪一个实体进行操作)
* 第二个泛型:主键类型
*/
public interface EmployeeRepository extends JpaRepository<Employee, Long>{
}
三、JpaRepository的基本功能
(一)基本CRUD
1.查询所有
List<Employee> list = employeeRepository.findAll();
2.查询一条数据
getOne
返回一个实体的引用,无结果会抛出异常;findOne
返回一个Optional
对象,可以实现动态查询
Employee employee = employeeRepository.findOne(1L);
3.添加或修改数据
//根据是否有Id自动确认是添加还是修改
employeeRepository.save(employee);
4.删除数据
employeeRepository.delete(274L);
(二)分页排序功能
1.排序
/*
* 第一个参数Sort.Direction.DESC:排序方式(降序)
* 第二个参数:排序属性
*/
Sort sort = new Sort(Sort.Direction.DESC,"age");
List<Employee> list = employeeRepository.findAll(sort);
list.forEach(e -> System.out.println(e));
2.分页
/**
* page:第几页(页数是从0开始计算,0就是第1页)
* 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.getContent());
//第几页
System.out.println(page.getNumber());
3.分页排序
//创建排序对象
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));
(三)名称规则(根据条件进行查询)
规则如下:
表达式 | 例子 | sql查询语句 |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEqual | … where x.firstname = 1? |
Between | findByStartDateBetween | … where x.startDate between 1? and ?2 |
LessThan(lt) | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual(le) | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
/*根据用户名模糊查询(规范名)*/
Employee findByUsername(String username);
/*根据用户名模糊查询(规范名)*/
List<Employee> findByUsernameLike(String username);
/*根据用户名与邮件进行模糊查询(规范名)*/
List<Employee> findByUsernameLikeAndEmailLike(String username,String email);
}
(四)@Query注解查询
- 想不遵循查询方法的命名规则,还可以使用@Query的方法进行查询
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
/*根据用户名模糊查询(注解)*/
@Query("select e from Employee e where e.username = ?1")
Employee query01(String username);
/*根据用户名模糊查询(注解)*/
@Query("select e from Employee e where e.username like ?1")
List<Employee> query02(String username);
/*根据用户名与邮件进行模糊查询(注解)*/
// @Query("select e from Employee e where e.username like ?1 and e.email like ?2")
// List<Employee> query03(String username,String email);
@Query("select e from Employee e where e.username like :username and e.email like :email")
List<Employee> query03(@Param("username") String username, @Param("email")String email);
/*查询所有(原生SQL)*/
@Query(nativeQuery = true,value = "SELECT * FROM employee")
List<Employee> query04();
}
四、JpaSpecificationExecutor
- 是一个JPA的规范执行者
- JPA2.0提供的Criteria API的使用封装
- 可以用于动态生成Query
- 需要repository继承JpaSpecificationExecutor接口
import com.lty.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface EmployeeRepository extends JpaRepository<Employee, Long> ,JpaSpecificationExecutor<Employee>{}
1.单个条件查询
/*根据用户名进行模糊查询(规则)
* 需要继承JpaSpecificationExecutor<>
* */
@Test
public void testJpaSpecificationExecutor01() throws Exception{
/**
* Predicate : 使以…为依据; where 条件 and 条件 ....
* @param root : 代表了可以查询和操作的实体对象的根
* 获取到实体对应的字段(username,password,age,email...)
* @param criteriaQuery : 代表一个specific的顶层查询对象
* 查询哪些字段,排序是什么(主要是把多个查询的条件连系起来)
* @param criteriaBuilder : 用来构建CriteriaQuery的构建器对象(相当于条件或者说条件组合)
* 主要判断关系(字段是相等,大于,小于like等)
*/
List<Employee> list = employeeRepository.findAll(new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//拿到用户名路径(Path不用加泛型)
Path usernamePath = root.get("username");
//用户名判断条件
Predicate predicate = criteriaBuilder.like(usernamePath,"%1%");
return predicate;
}
});
list.forEach(e-> System.out.println(e));
}
2.多个条件查询
/*根据用户名和邮件进行查询(规则)*/
@Test
public void testJpaSpecificationExecutor02() throws Exception{
List<Employee> list = employeeRepository.findAll(new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//拿到用户名根路径
Path usernamePath = root.get("username");
//拿到邮件根路径
Path emailPath = root.get("email");
//用户名判断条件
Predicate predicate1 = criteriaBuilder.like(usernamePath, "%1%");
//邮件判断条件
Predicate predicate2 = criteriaBuilder.like(emailPath, "%2%");
//把条件结合
Predicate predicate = criteriaBuilder.and(predicate1, predicate2);
return predicate;
}
});
list.forEach(e-> System.out.println(e));
}
3.分页排序查询
@Test
public void testJpaSpecificationExecutorPageSort() throws Exception{
//创建排序对象
Sort sort = new Sort(Sort.Direction.DESC,"age");
//创建分页对象
org.springframework.data.domain.Pageable pageable = new PageRequest(0,10,sort);
//根据规则进行查询
Page<Employee> page = employeeRepository.findAll(new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//拿到用户名根路径
Path usernamePath = root.get("username");
//用户名判断条件
Predicate predicate = criteriaBuilder.like(usernamePath, "%1%");
return predicate;
}
}, pageable);
page.forEach(e-> System.out.println(e));
}
五、jpa-spec插件
- 把JpaSpecificationExecutor变得更加简单的,是它的封装
- 使用的时候需要导包
- 文档: https://github.com/wenhao/jpa-spec/blob/master/docs/3.1.0_cn.md
- 注意导的是:
import com.github.wenhao.jpa.Specifications;
1.单个条件查询
/*根据用户名进行模糊查询(wenhao)*/
@Test
public void testJpaSpec01() throws Exception{
Specification<Employee> specification = Specifications.<Employee>and()
.like("username", "%1%")
.build();
List<Employee> list = employeeRepository.findAll(specification);
list.forEach(e-> System.out.println(e));
}
2.多个条件查询
/*根据用户名和邮件进行查询(规则)*/
@Test
public void testJpaSpec02() throws Exception{
Specification<Employee> specification = Specifications.<Employee>and()
.like("username", "%1%")
.like("email","%2%")
.build();
List<Employee> list = employeeRepository.findAll(specification);
list.forEach(e-> System.out.println(e));
}
3.分页排序查询
@Test
public void testJpaSpec02() throws Exception{
//创建排序对象
Sort sort = new Sort(Sort.Direction.DESC,"age");
//创建分页对象
org.springframework.data.domain.Pageable pageable = new PageRequest(0,10,sort);
Specification<Employee> specification = Specifications.<Employee>and()
.like("username", "%1%")
.build();
Page<Employee> page = employeeRepository.findAll(specification, pageable);
page.forEach(e-> System.out.println(e));
}
六、查询对象抽取
1.公共的分页条件
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
/**
* 创建父类的作用:
* 1.提供一些公共的属性的方法(少写代码)
* 2.制定规范(对子类形成相应的规范)
* 3.为了以后代码的扩展性
*/
public abstract class BaseQuery {
//当前页
private int currentPage = 1;
//每页条数
private int pageSize = 10;
//排序字段(如果这个字段为null,就代表不排序)
private String orderName;
//排序类型 (true = DESC/ false = ASC)
private boolean orderType = false;
//排序的对象创建
public Sort createSort(){
if (StringUtils.isNotBlank(orderName)){
//如果有排序字段返回排序对象
Sort sort = new Sort(orderType ? Sort.Direction.DESC : Sort.Direction.ASC,orderName);
return sort;
}
return null;
}
//每个子类必须有查询规则的方法
public abstract Specification createSpec();
public int getCurrentPage() {
return currentPage;
}
//兼容JPA从0页作为起始页
public int getJPACurrentPage() {
return currentPage-1;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
//省略getter,setter
}
2.Employee特有的一些条件
- 设置当前对应的Domain的特有查询字段
- 实现
createSpec()
import com.github.wenhao.jpa.Specifications;
import com.lty.aisell.domain.Employee;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
public class EmployeeQuery extends BaseQuery {
//用户名
private String username;
//邮件
private String email;
//年龄
private Integer age;
/*返回查询规则*/
@Override
public Specification createSpec(){
Specification<Employee> specification = Specifications.<Employee>and()
.like(StringUtils.isNoneBlank(username),"username", "%" + username + "%")
.like(StringUtils.isNoneBlank(email),"email", "%" + email + "%")
.gt(age!=null,"age", age)
.build();
return specification;
}
//省略getter,setter
}
3.功能测试
/*分页排序查询(wenhao)
* 模拟前台传数据
* */
@Test
public void testJpaSpec() throws Exception{
/*模拟前台传过来的数据*/
EmployeeQuery query = new EmployeeQuery();
query.setUsername("1");
query.setEmail("2");
query.setAge(20);
query.setOrderName("age");
query.setOrderType(true);
//创建排序对象
Sort sort = query.createSort();
//创建分页对象(分页对象从前台传过来)
Pageable pageable = new PageRequest(query.getJPACurrentPage(),query.getPageSize(),sort);
//创建查询对象
Specification specification = query.createSpec();
//功能执行
Page<Employee> page = employeeRepository.findAll(specification, pageable);
page.forEach(e-> System.out.println(e));
}
来源:CSDN
作者:EstherLty
链接:https://blog.csdn.net/qq_45988641/article/details/103570655