Querydsl是一个非常强大的Java查询框架,可以帮助开发者简化和优化数据库查询操作。Querydsl可以让开发者使用Java代码来编写SQL查询,从而避免了字符串拼接带来的错误风险,并提高了代码的可读性和可维护性。其还支持各种高级查询功能,例如连接、子查询、聚合等,并可以生成各种数据库方言的SQL语句。
快速开始
1.引入依赖
// quarkus orm 依赖
implementation 'io.quarkus:quarkus-hibernate-orm'
implementation 'io.quarkus:quarkus-jdbc-postgresql'
// 若 springboot 可引入 jpa依赖
//implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// querydsl依赖,若非springboot3.x或quarkus3.x,可去掉末尾的 `:jakarta`
compileOnly 'com.querydsl:querydsl-apt:5.0.0:jakarta'
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api:3.1.0'
2.配置数据源
quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.100.100:5432/test?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
quarkus.datasource.username=root
quarkus.datasource.password=root
# 表创建策略,可用值 none, create, drop-and-create, drop, update, validate
quarkus.hibernate-orm.database.generation=update
# springboot 则是
#spring.jpa.hibernate.ddl-auto=update
# quarkus 开启日志
%dev.quarkus.log.category."org.hibernate.SQL".min-level=DEBUG
%dev.quarkus.log.category."org.hibernate.SQL".level=DEBUG
# springboot 则是
#spring.jpa.show-sql=true
3.配置类
即使用 hibernate 的 entityManager 构建 JPAQueryFactory 即可。
public class QueryDslConfig {
@Inject EntityManager entityManager;
@Singleton
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
4.实体类
@Data
@Entity // 必加注解 jakarta.persistence.Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
String id;
String fullName;
}
5.增删改查
Querydsl 的查询用法和sql语句基本一致,所以不查阅文档基本也能知道如何写查询条件。
@Path("/user")
public class UserResource {
@Inject JPAQueryFactory jpaQueryFactory;
@GET
public void test() {
// QUser.user 为自动生成,若没有请重新编译项目
// 查询
jpaQueryFactory.selectFrom(QUser.user)
.where(QUser.user.id.eq("1"))
.fetchOne();
jpaQueryFactory.selectFrom(QUser.user)
.where(QUser.user.name.like("1"))
.fetch();
// 新增
jpaQueryFactory.insert(QUser.user).values(new User()).execute();
// 也可以直接使用hibernate的 entityManager.persist(entity);
// 修改
jpaQueryFactory.update(QUser.user)
.set(QUser.user.name,"zhangsan")
.where(QUser.user.id.eq("1"))
.execute();
// 删除
jpaQueryFactory.delete(QUser.user).where(QUser.user.id.eq("1")).execute();
}
}
通用 Repository
1.增加 Repository
public abstract class Repository<T> {
@Inject EntityManager entityManager;
@Inject JPAQueryFactory jpaQueryFactory;
protected abstract EntityPathBase<T> get();
public JPAQuery<T> select() {
return jpaQueryFactory.selectFrom(get());
}
public <R extends T> JPAQuery<R> select(Expression<R> select) {
return jpaQueryFactory.select(select).from(get());
}
public JPADeleteClause delete() {
return jpaQueryFactory.delete(get());
}
public void persist(T entity) {
entityManager.persist(entity);
}
public void persist(List<T> entity) {
int i = 0;
for (T t : entity) {
entityManager.persist(t);
i++;
if (i % 1000 == 0) {
entityManager.flush();
entityManager.clear();
}
}
if (i % 1000 != 0) {
entityManager.flush();
entityManager.clear();
}
}
public Page<T> page(Page<?> page, Predicate... where) {
if (page == null) {
page = new Page<T>();
}
if (page.getCurrent() == 0) {
page.setCurrent(1);
}
if (page.getPageSize() == 0) {
page.setPageSize(10);
}
long count =
Optional.ofNullable(
jpaQueryFactory.select(get().count()).from(get()).where(where).fetchOne())
.orElse(0L);
var sql =
jpaQueryFactory
.select(get())
.from(get())
.where(where)
.offset((page.getCurrent() - 1) * page.getPageSize())
.limit(page.getPageSize());
return Page.<T>builder()
.current(page.getCurrent())
.pageSize(page.getPageSize())
.total(count)
.records(sql.fetch())
.build();
}
// 还需要什么方法可自行扩展
}
2.编写 UserRepository
以 User 为例,其他表也添加相应 xxxRepository 即可
@Singleton
public class UserRepository extends Repository<User> {
@Override
protected EntityPathBase<User> get() {
return QUser.user;
}
}
3.使用
@Path("/user")
class UserResource {
@Inject
UserRepository userRepository;
@GET
@Path("/all")
@Produces(MediaType.APPLICATION_JSON)
public List<User> all() {
return userRepository.select().fetch();
}
}
博客内容遵循:署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
本文永久链接是:seepine.com/quarkus/que…