springData使用QueryDsl的示例代码

经过多年,spring data jpa越来越完善,在版本迭代的过程中,会不断增加功能,今天看新的reference发现有Querydsl.然后搜索到上面的参考资料2

无论是JpaSpecificationExecutor,还是QueryDslPredicateExecutor,它俩都提供了使用Predicate(意义相同,都是构建where子句;类不同,javax.persistence.criteria.Predicate,com.querydsl.core.types.Predicate)去构建查询,使用比较方便.

关于两者的简单使用,上面的参考资料2有介绍.文末也有总结,从概括来看,我个人认为应倾向使用QueryDslPredicateExecutor,QueryDsl不仅适用于JPA repositories,还支持MongoDB.

下面是个例子

1.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>org.exam</groupId>

<artifactId>testjava</artifactId>

<version>1.0.0</version>

<name>${project.artifactId}</name>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

<spring.version>4.2.5.RELEASE</spring.version>

<spring-data.version>Hopper-SR1</spring-data.version>

<querydsl.version>4.1.1</querydsl.version>

<hibernate.version>5.1.0.Final</hibernate.version>

<tomcat.version>8.0.32</tomcat.version>

<logback.version>1.1.7</logback.version>

<mysql.version>5.1.33</mysql.version>

<junit.version>4.12</junit.version>

</properties>

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-framework-bom</artifactId>

<version>${spring.version}</version>

<scope>import</scope>

<type>pom</type>

</dependency>

<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-releasetrain</artifactId>

<version>${spring-data.version}</version>

<scope>import</scope>

<type>pom</type>

</dependency>

</dependencies>

</dependencyManagement>

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.1</version>

<configuration>

<source>${java.version}</source>

<target>${java.version}</target>

</configuration>

</plugin>

<plugin>

<groupId>com.mysema.maven</groupId>

<artifactId>maven-apt-plugin</artifactId>

<version>1.0.4</version>

<executions>

<execution>

<phase>generate-sources</phase>

<goals>

<goal>process</goal>

</goals>

<configuration>

<outputDirectory>target/generated-sources</outputDirectory>

<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>

</configuration>

</execution>

</executions>

</plugin>

</plugins>

</build>

<dependencies>

<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-jpa</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-mongodb</artifactId>

</dependency>

<dependency>

<groupId>com.querydsl</groupId>

<artifactId>querydsl-apt</artifactId>

<version>${querydsl.version}</version>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>com.querydsl</groupId>

<artifactId>querydsl-jpa</artifactId>

<version>${querydsl.version}</version>

</dependency>

<dependency>

<groupId>com.querydsl</groupId>

<artifactId>querydsl-mongodb</artifactId>

<version>${querydsl.version}</version>

</dependency>

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-entitymanager</artifactId>

<version>${hibernate.version}</version>

</dependency>

<dependency>

<groupId>org.apache.tomcat</groupId>

<artifactId>tomcat-jdbc</artifactId>

<version>${tomcat.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-test</artifactId>

</dependency>

<dependency>

<groupId>ch.qos.logback</groupId>

<artifactId>logback-classic</artifactId>

<version>${logback.version}</version>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>${mysql.version}</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>${junit.version}</version>

</dependency>

</dependencies>

<repositories>

<repository>

<id>central</id>

<name>Central Repository</name>

<url>http://repo1.maven.org/maven2</url>

<layout>default</layout>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>

</project>

2.Domain类

package org.exam.domain;

import org.springframework.data.mongodb.core.mapping.Document;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import java.io.Serializable;

@Entity

@Document

public class Employee implements Serializable {

@Id

@Column(length = 38)

private String id;

@Column(length = 32)

private String name;

private long salary;

private long departmentId;

//setter和getter略

}

3.Repository类

package org.exam.repository.jpa;

import org.exam.domain.Employee;

import org.springframework.data.querydsl.QueryDslPredicateExecutor;

import org.springframework.data.repository.PagingAndSortingRepository;

import java.util.Collection;

public interface JpaEmployeeRepository extends PagingAndSortingRepository<Employee,String>,QueryDslPredicateExecutor<Employee>{

Collection<Employee> findByIdIn(Collection<String> ids);

}

package org.exam.repository.mongo;

import org.exam.domain.Employee;

import org.springframework.data.querydsl.QueryDslPredicateExecutor;

import org.springframework.data.repository.PagingAndSortingRepository;

import java.util.Collection;

public interface MongoEmployeeRepository extends PagingAndSortingRepository<Employee, String>, QueryDslPredicateExecutor<Employee> {

Collection<Employee> findByIdIn(Collection<String> ids);

}

JPA有JpaRepository,MongoDB有MongoRepository,它俩都继承PagingAndSortingRepository

3.配置类

package org.exam.config;

import com.mongodb.MongoClient;

import com.mongodb.WriteConcern;

import org.apache.tomcat.jdbc.pool.DataSource;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.PropertySource;

import org.springframework.core.env.Environment;

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import org.springframework.data.mongodb.MongoDbFactory;

import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import org.springframework.data.mongodb.core.WriteResultChecking;

import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import org.springframework.orm.jpa.JpaTransactionManager;

import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import org.springframework.orm.jpa.vendor.Database;

import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import org.springframework.transaction.PlatformTransactionManager;

import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;

import java.net.UnknownHostException;

import java.util.Properties;

@Configuration

@PropertySource("classpath:config.properties")

@EnableTransactionManagement

@EnableJpaRepositories(basePackages = "org.exam.repository.jpa")

@EnableMongoRepositories(basePackages = "org.exam.repository.mongo")

public class AppConfig {

@Resource

private Environment env;

@Bean(destroyMethod = "close")

public DataSource dataSource() {

DataSource dataSource = new DataSource();

dataSource.setDriverClassName(env.getProperty("ds.driverClassName"));

dataSource.setUrl(env.getProperty("ds.url"));

dataSource.setUsername(env.getProperty("ds.username"));

dataSource.setPassword(env.getProperty("ds.password"));

dataSource.setInitialSize(env.getProperty("ds.initialSize", Integer.class));

dataSource.setMinIdle(env.getProperty("ds.minIdle", Integer.class));

dataSource.setMaxIdle(env.getProperty("ds.maxIdle", Integer.class));

dataSource.setMaxActive(env.getProperty("ds.maxActive", Integer.class));

return dataSource;

}

@Bean

public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();

jpaVendorAdapter.setDatabase(Database.valueOf(env.getProperty("jpa.database")));

jpaVendorAdapter.setGenerateDdl(env.getProperty("jpa.generateDdl",Boolean.class));

jpaVendorAdapter.setShowSql(env.getProperty("jpa.showSql",Boolean.class));

LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();

emf.setDataSource(dataSource());

emf.setPackagesToScan("org.exam.domain");

emf.setJpaVendorAdapter(jpaVendorAdapter);

Properties properties = new Properties();

properties.setProperty("hibernate.default_schema", env.getProperty("jpa.defaultSchema"));

emf.setJpaProperties(properties);

return emf;

}

@Bean

public PlatformTransactionManager transactionManager() {

return new JpaTransactionManager(entityManagerFactory().getObject());

}

@Bean

public MongoDbFactory mongoDbFactory() throws UnknownHostException {

return new SimpleMongoDbFactory(new MongoClient(env.getProperty("mongo.host"), env.getProperty("mongo.port", Integer.class)), env.getProperty("mongo.db"));

}

@Bean

public MongoTemplate mongoTemplate() throws UnknownHostException {

MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());

mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION);

mongoTemplate.setWriteConcern(WriteConcern.NORMAL);

return mongoTemplate;

}

}

4.测试类

package org.exam.repository.jpa;

import org.exam.config.AppConfig;

import org.exam.domain.Employee;

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.test.context.support.AnnotationConfigContextLoader;

import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = {AppConfig.class})

@Transactional(transactionManager = "transactionManager")//Rollback默认为true

public class JpaEmployeeRepositoryTest {

@Autowired

private JpaEmployeeRepository jpaEmployeeRepository;

@Test

@Rollback(false)

public void testSave() {

for (int i = 0; i < 5; i++) {

Employee employee = new Employee();

employee.setId(UUID.randomUUID().toString());

employee.setName("name");

employee.setDepartmentId(1 + i);

employee.setSalary(6800 + i);

jpaEmployeeRepository.save(employee);

}

}

@Test

public void testFindAll() {

Page<Employee> all = jpaEmployeeRepository.findAll(null, new PageRequest(0, 8));

for (Employee employee : all) {

System.out.println("employee = " + employee);

}

}

}

package org.exam.repository.mongo;

import com.mongodb.MongoClient;

import org.exam.config.AppConfig;

import org.exam.domain.Employee;

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.data.geo.Circle;

import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import org.springframework.test.context.support.AnnotationConfigContextLoader;

import java.net.UnknownHostException;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = {AppConfig.class})

public class MongoEmployeeRepositoryTest {

@Autowired

private MongoEmployeeRepository mongoEmployeeRepository;

public static void main(String[] args) throws UnknownHostException {

MongoTemplate template = new MongoTemplate(new MongoClient("127.0.0.1", 27017), "test");

Circle circle = new Circle(-73.99171, 40.738868, 0.01);

System.out.println();

}

@Test

public void testFindAll() {

Page<Employee> all = mongoEmployeeRepository.findAll(null, new PageRequest(0, 8));

for (Employee employee : all) {

System.out.println("employee = " + employee);

}

}

}

5.其它config.properties,logback.xml文件不太重要,篇幅关系就省略.

源码下载

再了解一下比较大的需求,从几张表来取几个字段的数据,返回分页排序数据.

1.在AppConfig注册JPAQueryFactory Bean

@Bean

public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {

return new JPAQueryFactory(new HQLTemplates(), entityManager);

}

2.建一个DTO(数据传输对象)

public class UserDTO {

private String empName;

private String deptName;

private long salary;

//setter,getter略

}

3.查询例子测试

private Page<UserDTO> findAll(String empName,Pageable pageable) {

QEmployee qEmp = QEmployee.employee;

QDepartment qDep = QDepartment.department;

List<Predicate> criteria = new ArrayList<>();

if (StringUtils.hasText(empName)){

criteria.add(qEmp.name.eq(empName.trim()));

}

JPAQuery<?> query = jpaQueryFactory.from(qEmp).innerJoin(qDep).on(qEmp.deptId.eq(qDep.id)).where(criteria.toArray(new Predicate[criteria.size()]));

long total = query.fetchCount();

List<UserDTO> content;

if (pageable == null || total > pageable.getOffset()) {

Map<String, SimpleExpression<?>> map = new HashMap<>();

map.put("deptName", qDep.name);

map.put("empName", qEmp.name);

map.put("salary", qEmp.salary);

content = QuerydslUtils.applyPagination(pageable, query).select(Projections.bean(UserDTO.class, map)).fetch();

} else {

content = Collections.emptyList();

}

return new PageImpl<>(content, pageable, total);

}

@Test

public void test() {

Pageable pageable = new PageRequest(0, 10, new QSort(new OrderSpecifier<>(Order.DESC, QEmployee.employee.salary), new OrderSpecifier<>(Order.ASC, QDepartment.department.name)));

Page<UserDTO> page = findAll("name", pageable);

for (UserDTO userDTO : page) {

System.out.println("userDTO = " + userDTO);

}

}

参考资料

1:http://docs.spring.io/spring-data/jpa/docs/1.10.x/reference/pdf/spring-data-jpa-reference.pdf

2:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

以上是 springData使用QueryDsl的示例代码 的全部内容, 来源链接: utcz.com/z/312831.html

回到顶部