# 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); } ```