Querydsl與SpringBoot集成


Querydsl為大多數數據庫提供了一種基於Java的類型安全,類SQL的查詢方式。相比JPA,Querydsl能提供更加強大的查詢方式,比如關聯查詢。相比MyBatis,Querydsl省去了XML文件或者注解SQL的麻煩,直接通過流式API的方式進行調用。

除了支持關系型數據庫之外,Querydsl同樣支持一下存儲

  • MongoDB
  • Lucene
  • Collections
  • Spatial
  • JDO

接下來通過H2+JPA的方式介紹Querydsl的基本使用(為了演示采用H2數據庫)

一、創建項目,添加依賴

本文采用Spring Boot快速搭建項目,並在pom.xml中添加以下依賴

				<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>4.3.1</version>
        </dependency>
        
    <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>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

注意
當在項目中使用的是JPA的注解( javax.persistence.Entity)的時候,需要使用JPAAnnotationProcessor生成相關的查詢類,如果使用的是Hibernate注解的時候,需要將JPAAnnotationProcessor替換成com.querydsl.apt.hibernate.HibernateAnnotationProcessor。

二、創建實體類

@Entity
public class User {
    @Id
    private Integer id;
    private String name;
		// 省略getter, setter等方法
}

@Entity
public class UserInfo {
    @Id
    private Integer userId;
    private Integer sex;
}

實體類創建完成之后,重新編譯項目

mvn clean package

在target/generated-sources/java目錄中可以看到編譯后生成的查詢類(Q開頭的類,例如QUser, QUserInfo)

三、測試

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class QuerydslTests {
    @Autowired
    private EntityManager entityManager;
    private JPAQueryFactory queryFactory;
    private QUser qUser;
    private QUserInfo qUserInfo;

    @BeforeEach
    void setUp() {
        queryFactory = new JPAQueryFactory(entityManager);
        qUser = QUser.user;
        qUserInfo = QUserInfo.userInfo;
    }

    @Test
    void simpleQuery() {
        User user = queryFactory.selectFrom(qUser)
                .where(qUser.name.eq("XiaoMing"))
                .fetchOne();
        Assertions.assertNotNull(user);
        Assertions.assertEquals("XiaoMing", user.getName());
    }

    @Test
    void simpleQueryFields() {
        String name = queryFactory.selectFrom(qUser)
                .select(qUser.name)
                .where(qUser.name.eq("XiaoMing"))
                .fetchOne();
        Assertions.assertNotNull(name);
        Assertions.assertEquals("XiaoMing", name);
    }

    @Test
    void join() {
        Tuple tuple = queryFactory.selectFrom(qUser)
                .select(qUser.id, qUser.name, qUserInfo.sex)
                .innerJoin(qUserInfo).on(qUserInfo.userId.eq(qUser.id))
                .where(qUser.name.eq("XiaoMing"))
                .fetchOne();
        Assertions.assertNotNull(tuple);
        Assertions.assertNotEquals(0, tuple.size());
        Integer userId = tuple.get(0, Integer.class);
        String name = tuple.get(1, String.class);
        Integer sex = tuple.get(2, Integer.class);
        Assertions.assertEquals(1, userId);
        Assertions.assertEquals("XiaoMing", name);
        Assertions.assertEquals(0, sex);
    }
}

最后附上數據庫初始化腳本

insert into `user` (id, name) values (1, 'XiaoMing');
insert into `user` (id, name) values (2, 'XiaoHong');

insert into `user_info` (user_id, sex) values (1, 0);
insert into `user_info` (user_id, sex) values (2, 1);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM