QueryDSL是一个通用的查询框架. 可以大大简化代码和不同数据库的sql差异化语法问题; 通过querydsl可以实现复杂的sql补充jpa的不足;
工程截图
1. 引入依赖
mongo依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
querydsl依赖
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
编译插件
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
</processor>
</configuration>
</execution>
</executions>
</plugin>
完整的pom配置
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
</parent>
<groupId>com.demo</groupId>
<artifactId>demo-querydsl-mongo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<fastjson.version>1.2.83</fastjson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. yml配置文件
server:
port: 8200
servlet:
context-path: /demo
spring:
data:
mongodb:
host: 127.0.0.1:27017
username: root
password: root
database: demo
authentication-database: admin
3. 创建 实体对象
@Document对应关系型数据库中的@Entity; @CreatedDate需要再启动器类里面开启审计
@Document(collection = "demo_user")
public class User {
@Id
private String id;
@NotNull
@Size(min = 2, max = 20)
private String username;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@CreatedDate
private Date createdDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@LastModifiedDate
private Date lastModifiedDate;
}
4. 创建Repository接口, 继承QuerydslPredicateExecutor接口, 方法都空着,继承就行了
@NoRepositoryBean
public interface BaseMongoRepository<T> extends MongoRepository<T, String>, QuerydslPredicateExecutor<T> {
}
5. 创建对象 repo, 继承BaseMongoRepository方法都空着,继承就行了. 需要传递范型
@Repository
public interface UserRepository extends BaseMongoRepository<User> {
}
6. 创建公共service
提供公共的方法. 对象的service继承此类即可完成相关功能
public class BaseService<T, I extends String> {
@Autowired
private BaseMongoRepository<T> baseMongoRepository;
public BaseMongoRepository<T> getRepository() {
return baseMongoRepository;
}
public List<T> findAll() {
return getRepository().findAll();
}
public Iterable<T> findAll(Predicate predicate) {
if (null == predicate) {
return findAll();
}
return getRepository().findAll(predicate);
}
public Page<T> findAll(Pageable pageable) {
return getRepository().findAll(pageable);
}
public Page<T> findAll(Predicate predicate, Pageable pageable) {
if (null == predicate) {
return findAll(pageable);
}
return getRepository().findAll(predicate, pageable);
}
public <S extends T> S save(S entity) {
return getRepository().save(entity);
}
public <S extends T> S update(S entity) {
return getRepository().save(entity);
}
public T findById(I id) {
Optional<T> one = getRepository().findById(id);
if (one.isPresent()) {
return one.get();
}
return null;
}
public T findOne(Predicate predicate) {
Optional<T> one = getRepository().findOne(predicate);
if (one.isPresent()) {
return one.get();
}
return null;
}
public long count() {
return getRepository().count();
}
public long count(Predicate predicate) {
return getRepository().count(predicate);
}
public void delete(I id) {
T entity = findById(id);
delete(entity);
}
public void delete(T entity) {
getRepository().delete(entity);
}
}
7. 创建对象的service, 继承BaseService传递范型;
重写save方法. 使用querydsl 方法查询username是否重复; QUser 需要先编译才会自动生成
@Service
public class UserService extends BaseService<User, String> {
@Override
public <S extends User> S save(S entity) {
BooleanBuilder builder = new BooleanBuilder();
builder.and(QUser.user.username.eq(entity.getUsername()));
long count = count(builder);
if (count > 1) {
throw new RuntimeException("username 重复");
}
return super.save(entity);
}
}
8. 编写controller进行测试
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/save")
public Object saveUser(@ModelAttribute @Valid User user, BindingResult bindingResult, HttpServletRequest request, HttpServletResponse response) {
if (bindingResult.hasErrors()) {
return bindingResult.getFieldError().getDefaultMessage();
}
userService.save(user);
JSONObject jsonObject = new JSONObject(true);
jsonObject.put("data", user);
return jsonObject;
}
@RequestMapping(value = "/query")
public JSONObject queryUser(@QuerydslPredicate(root = User.class) Predicate predicate, @PageableDefault(size = 20, sort = {"createdDate"}, direction = Sort.Direction.DESC) Pageable pageable) {
Page<User> userPage = userService.findAll(predicate, pageable);
JSONObject jsonObject = new JSONObject(true);
jsonObject.put("data", userPage.getContent());
jsonObject.put("totalPages", userPage.getTotalPages());
jsonObject.put("totalElements", userPage.getTotalElements());
jsonObject.put("pageable", userPage.getPageable());
return jsonObject;
}
}
9. postman进行测试
保存接口. 通过@valid去检查合法性
查询接口; 通过
关注个人公众号获取源代码