首页 > 编程 > Java > 正文

springData使用QueryDsl的示例代码

2019-11-26 09:20:54
字体:
来源:转载
供稿:网友

经过多年,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@Documentpublic 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默认为truepublic 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

@Beanpublic 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);}@Testpublic 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/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表