springData使用QueryDsl的示例代码
经过多年,springdatajpa越来越完善,在版本迭代的过程中,会不断增加功能,今天看新的reference发现有Querydsl.然后搜索到上面的参考资料2
无论是JpaSpecificationExecutor,还是QueryDslPredicateExecutor,它俩都提供了使用Predicate(意义相同,都是构建where子句;类不同,javax.persistence.criteria.Predicate,com.querydsl.core.types.Predicate)去构建查询,使用比较方便.
关于两者的简单使用,上面的参考资料2有介绍.文末也有总结,从概括来看,我个人认为应倾向使用QueryDslPredicateExecutor,QueryDsl不仅适用于JPArepositories,还支持MongoDB.
下面是个例子
1.pom.xml
4.0.0 org.exam testjava 1.0.0 ${project.artifactId} UTF-8 UTF-8 1.8 4.2.5.RELEASE Hopper-SR1 4.1.1 5.1.0.Final 8.0.32 1.1.7 5.1.33 4.12 org.springframework spring-framework-bom ${spring.version} import pom org.springframework.data spring-data-releasetrain ${spring-data.version} import pom org.apache.maven.plugins maven-compiler-plugin 3.1 ${java.version} ${java.version} com.mysema.maven maven-apt-plugin 1.0.4 generate-sources process target/generated-sources com.querydsl.apt.jpa.JPAAnnotationProcessor org.springframework.data spring-data-jpa org.springframework.data spring-data-mongodb com.querydsl querydsl-apt ${querydsl.version} provided com.querydsl querydsl-jpa ${querydsl.version} com.querydsl querydsl-mongodb ${querydsl.version} org.hibernate hibernate-entitymanager ${hibernate.version} org.apache.tomcat tomcat-jdbc ${tomcat.version} org.springframework spring-test ch.qos.logback logback-classic ${logback.version} mysql mysql-connector-java ${mysql.version} junit junit ${junit.version} central CentralRepository http://repo1.maven.org/maven2 default false
2.Domain类
packageorg.exam.domain;
importorg.springframework.data.mongodb.core.mapping.Document;
importjavax.persistence.Column;
importjavax.persistence.Entity;
importjavax.persistence.Id;
importjava.io.Serializable;
@Entity
@Document
publicclassEmployeeimplementsSerializable{
@Id
@Column(length=38)
privateStringid;
@Column(length=32)
privateStringname;
privatelongsalary;
privatelongdepartmentId;
//setter和getter略
}
3.Repository类
packageorg.exam.repository.jpa; importorg.exam.domain.Employee; importorg.springframework.data.querydsl.QueryDslPredicateExecutor; importorg.springframework.data.repository.PagingAndSortingRepository; importjava.util.Collection; publicinterfaceJpaEmployeeRepositoryextendsPagingAndSortingRepository,QueryDslPredicateExecutor { Collection findByIdIn(Collection ids); }
packageorg.exam.repository.mongo; importorg.exam.domain.Employee; importorg.springframework.data.querydsl.QueryDslPredicateExecutor; importorg.springframework.data.repository.PagingAndSortingRepository; importjava.util.Collection; publicinterfaceMongoEmployeeRepositoryextendsPagingAndSortingRepository,QueryDslPredicateExecutor { Collection findByIdIn(Collection ids); }
JPA有JpaRepository,MongoDB有MongoRepository,它俩都继承PagingAndSortingRepository
3.配置类
packageorg.exam.config;
importcom.mongodb.MongoClient;
importcom.mongodb.WriteConcern;
importorg.apache.tomcat.jdbc.pool.DataSource;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.PropertySource;
importorg.springframework.core.env.Environment;
importorg.springframework.data.jpa.repository.config.EnableJpaRepositories;
importorg.springframework.data.mongodb.MongoDbFactory;
importorg.springframework.data.mongodb.core.MongoTemplate;
importorg.springframework.data.mongodb.core.SimpleMongoDbFactory;
importorg.springframework.data.mongodb.core.WriteResultChecking;
importorg.springframework.data.mongodb.repository.config.EnableMongoRepositories;
importorg.springframework.orm.jpa.JpaTransactionManager;
importorg.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
importorg.springframework.orm.jpa.vendor.Database;
importorg.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
importorg.springframework.transaction.PlatformTransactionManager;
importorg.springframework.transaction.annotation.EnableTransactionManagement;
importjavax.annotation.Resource;
importjava.net.UnknownHostException;
importjava.util.Properties;
@Configuration
@PropertySource("classpath:config.properties")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="org.exam.repository.jpa")
@EnableMongoRepositories(basePackages="org.exam.repository.mongo")
publicclassAppConfig{
@Resource
privateEnvironmentenv;
@Bean(destroyMethod="close")
publicDataSourcedataSource(){
DataSourcedataSource=newDataSource();
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));
returndataSource;
}
@Bean
publicLocalContainerEntityManagerFactoryBeanentityManagerFactory(){
HibernateJpaVendorAdapterjpaVendorAdapter=newHibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.valueOf(env.getProperty("jpa.database")));
jpaVendorAdapter.setGenerateDdl(env.getProperty("jpa.generateDdl",Boolean.class));
jpaVendorAdapter.setShowSql(env.getProperty("jpa.showSql",Boolean.class));
LocalContainerEntityManagerFactoryBeanemf=newLocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setPackagesToScan("org.exam.domain");
emf.setJpaVendorAdapter(jpaVendorAdapter);
Propertiesproperties=newProperties();
properties.setProperty("hibernate.default_schema",env.getProperty("jpa.defaultSchema"));
emf.setJpaProperties(properties);
returnemf;
}
@Bean
publicPlatformTransactionManagertransactionManager(){
returnnewJpaTransactionManager(entityManagerFactory().getObject());
}
@Bean
publicMongoDbFactorymongoDbFactory()throwsUnknownHostException{
returnnewSimpleMongoDbFactory(newMongoClient(env.getProperty("mongo.host"),env.getProperty("mongo.port",Integer.class)),env.getProperty("mongo.db"));
}
@Bean
publicMongoTemplatemongoTemplate()throwsUnknownHostException{
MongoTemplatemongoTemplate=newMongoTemplate(mongoDbFactory());
mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION);
mongoTemplate.setWriteConcern(WriteConcern.NORMAL);
returnmongoTemplate;
}
}
4.测试类
packageorg.exam.repository.jpa;
importorg.exam.config.AppConfig;
importorg.exam.domain.Employee;
importorg.junit.Test;
importorg.junit.runner.RunWith;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.data.domain.Page;
importorg.springframework.data.domain.PageRequest;
importorg.springframework.test.annotation.Rollback;
importorg.springframework.test.context.ContextConfiguration;
importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;
importorg.springframework.test.context.support.AnnotationConfigContextLoader;
importorg.springframework.transaction.annotation.Transactional;
importjava.util.UUID;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class,classes={AppConfig.class})
@Transactional(transactionManager="transactionManager")//Rollback默认为true
publicclassJpaEmployeeRepositoryTest{
@Autowired
privateJpaEmployeeRepositoryjpaEmployeeRepository;
@Test
@Rollback(false)
publicvoidtestSave(){
for(inti=0;i<5;i++){
Employeeemployee=newEmployee();
employee.setId(UUID.randomUUID().toString());
employee.setName("name");
employee.setDepartmentId(1+i);
employee.setSalary(6800+i);
jpaEmployeeRepository.save(employee);
}
}
@Test
publicvoidtestFindAll(){
Pageall=jpaEmployeeRepository.findAll(null,newPageRequest(0,8));
for(Employeeemployee:all){
System.out.println("employee="+employee);
}
}
}
packageorg.exam.repository.mongo;
importcom.mongodb.MongoClient;
importorg.exam.config.AppConfig;
importorg.exam.domain.Employee;
importorg.junit.Test;
importorg.junit.runner.RunWith;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.data.domain.Page;
importorg.springframework.data.domain.PageRequest;
importorg.springframework.data.geo.Circle;
importorg.springframework.data.mongodb.core.MongoTemplate;
importorg.springframework.test.context.ContextConfiguration;
importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;
importorg.springframework.test.context.support.AnnotationConfigContextLoader;
importjava.net.UnknownHostException;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class,classes={AppConfig.class})
publicclassMongoEmployeeRepositoryTest{
@Autowired
privateMongoEmployeeRepositorymongoEmployeeRepository;
publicstaticvoidmain(String[]args)throwsUnknownHostException{
MongoTemplatetemplate=newMongoTemplate(newMongoClient("127.0.0.1",27017),"test");
Circlecircle=newCircle(-73.99171,40.738868,0.01);
System.out.println();
}
@Test
publicvoidtestFindAll(){
Pageall=mongoEmployeeRepository.findAll(null,newPageRequest(0,8));
for(Employeeemployee:all){
System.out.println("employee="+employee);
}
}
}
5.其它config.properties,logback.xml文件不太重要,篇幅关系就省略.
源码下载
再了解一下比较大的需求,从几张表来取几个字段的数据,返回分页排序数据.
1.在AppConfig注册JPAQueryFactoryBean
@Bean
publicJPAQueryFactoryjpaQueryFactory(EntityManagerentityManager){
returnnewJPAQueryFactory(newHQLTemplates(),entityManager);
}
2.建一个DTO(数据传输对象)
publicclassUserDTO{
privateStringempName;
privateStringdeptName;
privatelongsalary;
//setter,getter略
}
3.查询例子测试
privatePagefindAll(StringempName,Pageablepageable){ QEmployeeqEmp=QEmployee.employee; QDepartmentqDep=QDepartment.department; List criteria=newArrayList<>(); 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(newPredicate[criteria.size()])); longtotal=query.fetchCount(); List content; if(pageable==null||total>pageable.getOffset()){ Map >map=newHashMap<>(); 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(); } returnnewPageImpl<>(content,pageable,total); } @Test publicvoidtest(){ Pageablepageable=newPageRequest(0,10,newQSort(newOrderSpecifier<>(Order.DESC,QEmployee.employee.salary),newOrderSpecifier<>(Order.ASC,QDepartment.department.name))); Page page=findAll("name",pageable); for(UserDTOuserDTO: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/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。