# querydsl
**Repository Path**: lungyam/querydsl
## Basic Information
- **Project Name**: querydsl
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-11-08
- **Last Updated**: 2021-11-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: ORM框架
## README
## QueryDSL
### 开发准备:
#### 1.修改数据库密码;
```sql
mysql -u root -p
set password for root@localhost = password('123456')
exit
```
#### 2.创建Person表;
```sql
CREATE TABLE `person`
(
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
#### 3.利用Groovy脚本生成person实体类;
```java
// scripts包下的MyGenerate POJOs.groovy
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@FieldNameConstants
@Table(name = "person")
public class Person implements Serializable {...}
```
#### 4.添加QueryDSL依赖、插件包;
```xml
com.querydsl
querydsl-apt
4.4.0
com.querydsl
querydsl-sql
4.4.0
com.querydsl
querydsl-jpa
4.4.0
com.mysema.maven
apt-maven-plugin
1.1.3
process
target/generated-sources/java
com.querydsl.apt.jpa.JPAAnnotationProcessor
```
#### 5.基于Java配置方式的显示装配Bean
(@Configuration 作用于类上,相当于一个xml配置文件,@Bean 作用于方法上,相当于xml配置文件中的标签。能够在编译时就发现错误)
```java
@Configuration
public class QuerydslConfig {
@Bean
public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {
return new JPAQueryFactory(entityManager);
}
@Bean
public SQLQueryFactory sqlQueryFactory(DataSource dataSource){
return new SQLQueryFactory(new com.querydsl.sql.Configuration(SQLTemplates.DEFAULT), dataSource);
}
}
```
#### 6.依赖注入,开始你的开发之旅。
```java
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class QuerydslSubQueryTest {
@Autowired
private JPAQueryFactory jpaQueryFactory;
private final QPerson qPerson = QPerson.person;
@Test
public void jpaQueryTest() {
List list = jpaQueryFactory.select(qPerson.name, qPerson.age)
.from(qPerson)
.where(qPerson.name.like("%小%"))
.fetch();
}
}
```
### 项目讲解:
JPA / Hibernate 的思想是用操作实体对象的方式操作数据表,**方法关键字命名查询**、**@Query、@Modifying 注解**,在单表上 select、update、insert、delete 非常方便。
QueryDSL 对 JPA / Hibernate 的补充:
1.自定义返回对象;2.动态查询;3.关联查询;4.子查询(参考 https://www.jianshu.com/p/0483c6af9da6)
```sql
# 查询:联表、条件过滤、分组、分组过滤、排序、分页
select
from
innerJoin、leftJoin、rightJoin、fullJoin ... on
where
groupBy
having
orderBy
limit、offset、restrict
```
QueryDSL 提供了 JPAQueryFactory 和 SQLQueryFactory 来操作数据库。
JPAQueryFactory 依赖于 JPA,必须要有类似 Hibernate 这种实现了 JPA 的 ORM 框架,使用起来比较方便。
```java
/**
* JPAQueryFactory where子查询:
* 先写成sql语句:
* SELECT
* p.name, p.age
* FROM
* person p
* WHERE
* p.age IN ( SELECT p.age FROM person p WHERE p.NAME LIKE "%小%" );
*/
@Test
public void jpaQueryTest() {
List whereSubQueryResult = jpaQueryFactory.select(qPerson.name, qPerson.age)
.from(qPerson)
.where(qPerson.age.in(
JPAExpressions.select(qPerson.age)
.from(qPerson)
.where(qPerson.name.like("%小%"))
)).fetch();
whereSubQueryResult.forEach(System.out::println);
}
```
JPA 有些限制,from 子句里使用子查询不太好用,这时可以使用 SQLQueryFactory。
注意的是使用 JPAQueryFactory 的表、字段是用插件自动生成的以Q开头的类型,而使用 SQLQueryFactory 的时候字段都需要手动创建。
```java
/**
* SQLQueryFactory from子查询:
* 先写出sql语句:
* SELECT
* t.NAME, t.age
* FROM
* ( SELECT p.NAME, p.age FROM Person p WHERE p.age >= 18 order by p.age) AS t
*/
@Test
public void sqlQueryTest() {
StringExpression entityPath = Expressions.stringPath("person");
StringTemplate name = Expressions.stringTemplate("name", String.class);
NumberTemplate age = Expressions.numberTemplate(Integer.class, "age");
List fromSubQueryResult = sqlQueryFactory.select(name, age)
.from(
SQLExpressions.select(name, age)
.from(entityPath)
.where(age.goe(18))
.orderBy(new OrderSpecifier<>(Order.ASC, age))
// from子查询会派生一张新表,所以需要取一个别名
, Expressions.stringPath("t")
).fetch();
fromSubQueryResult.forEach(System.out::println);
}
```