在 Spring Boot 中,QueryDSL可以被定义为查询域特定语言,它是一个可以提供类型安全的方式在 Java 中构造查询的框架。它可以让开发人员能够流畅、简洁地编写基于字符串的查询,例如 SQL 注入漏洞和缺乏编译时安全的 QueryDSL 生成基于数据库模式的查询类和实体类。
关键术语
- QueryDSL:这代表查询域特定语言,它是一个可以提供类型安全的方式来在 Java 中构造查询的框架。
- 查询类:它是一个预定义的类,可以表示可以对数据库执行的查询,它根据域模型和数据库模式生成类。
- 查询实体:它可以表示数据库表或视图,并且可以根据JPA实体注释生成实体类。
- 表达式:QueryDSL 中的表达式可以表示可在查询中使用的值或函数。
- Path:可以表示实体的字段属性,可以用来引用查询中的列。它可用于构建谓词和表达式。
Spring Boot应用中QueryDSL的实现
我们可以开发 Spring 应用程序,该应用程序可以将员工 CSV 文件作为输入,该 CSV 文件包含姓名和工资,然后 QueryDSL 可以处理该文件,然后生成可以计算员工奖金的输出 CSV。
步骤1:我们可以使用Spring STS IDE创建spring项目,并将下面提到的依赖项添加到项目中。
依赖:
- Spring Data for JPA
- Spring Web
- Lombok
- Spring Dev Tools
<dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-mongodb</artifactId> </dependency> <dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <scope>provided</scope> <classifier>jakarta</classifier> <version>${querydsl.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/com.mysema.maven/apt-maven-plugin --> <dependency> <groupId>com.mysema.maven</groupId> <artifactId>apt-maven-plugin</artifactId> <version>1.1.3</version> </dependency>
<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>
|
第 2 步:创建 sql 文件,命名为 schema-h2.sql,为 sql 数据库的用户创建表。
进入 src > resources > schema-h2.sql,输入以下代码。
CREATE TABLE user_seq ( id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, -- Adding NOT NULL constraint age INT );
|
步骤 3:创建 SQL 文件,命名为 data-h2.sql,可将数据插入 SQL 数据库的用户表中。
进入 src > resources > data-h2.sql,输入以下代码:
INSERT INTO user_seq (name, age) VALUES ('Mahesh Kadambala', 21); INSERT INTO user_seq (name, age) VALUES ('Eswar Betha', 22); INSERT INTO user_seq (name, age) VALUES ('Jagan Mall', 25); INSERT INTO user_seq (name, age) VALUES ('Ruchitha', 22); INSERT INTO user_seq (name, age) VALUES ('Sirisha', 26); INSERT INTO user_seq (name, age) VALUES ('Hema Nookeswari', 21); INSERT INTO user_seq (name, age) VALUES ('tarun', 25); INSERT INTO user_seq (name, age) VALUES ('Lohith', 28); INSERT INTO user_seq (name, age) VALUES ('Deepthi', 22); INSERT INTO user_seq (name, age) VALUES ('Raju', 29); INSERT INTO user_seq (name, age) VALUES ('Santhosh', 30);
|
第 4 步:打开 application.properties 文件,输入以下代码,为应用程序配置 MongoDb 数据库和分配服务器端口。
spring.datasource.url=jdbc:mysql://localhost:3306/querydsl spring.datasource.username=root spring.datasource.password= server.port=8083 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.main.banner-mode=off spring.jpa.hibernate.ddl-auto=none logging.pattern.console=%d{dd-MM-yyyy HH:mm:ss} %magenta([%thread]) %highlight(%-5level) %logger.%M - %msg%n
|
第 5 步:创建一个新包,命名为 model,在包中创建一个 java 类,命名为 User。
转到 src > com.gfg.querydslcrudapplication > model > User 并输入以下代码
import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Objects;
// User class representing a user in the application @Entity @Data @Table(name = "user_seq") @AllArgsConstructor @NoArgsConstructor public class User {
// Declaring instance variables @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // User ID private Long id;
// User Name private String name; // User Age private Integer age;
// Overriding equals method @Override public boolean equals(Object obj) { // If objects are the same if (this == obj) { return true; } // If object is null if (obj == null) { return false; } // If class types are different if (getClass() != obj.getClass()) { return false; } final User other = (User) obj; // 将对象转换为User类型 // 比较实例变量 if (!Objects.equals(this.id, other.id)) { return false; } if (!Objects.equals(this.name, other.name)) { return false; } return Objects.equals(this.age, other.age); }
// Overriding toString method @Override public String toString() { // StringBuilder for constructing string representation var builder = new StringBuilder(); // Appending instance variables to the builder builder.append("User{id=").append(id).append(", name=").append(name) .append(", age=").append(age).append("}"); // Returning the string representation return builder.toString(); } }
|
第 6 步:创建新软件包,并命名为 repository,在该软件包中创建名为 UserRepository 的 java 接口。
转到 src > com.gfg.querydslcrudapplication > repository > UserRepository 并输入以下代码。
import com.gfg.querydslcrudapplication.model.User; import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository;
// UserRepository interface extending CrudRepository and QuerydslPredicateExecutor @Repository public interface UserRepository extends CrudRepository<User, Long>, QuerydslPredicateExecutor<User> { }
|
第 7 步:创建名为 MyRunner 的 java 类,该类可以实现 CommandLineRunner。
转到 src > com.gfg.querydslcrudapplication > MyRunner 并输入以下代码。
import com.gfg.querydslcrudapplication.model.QUser; import com.gfg.querydslcrudapplication.repository.UserRepository; import com.gfg.querydslcrudapplication.model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.List; import java.util.Random;
// MyRunner class implementing CommandLineRunner interface @Component public class MyRunner implements CommandLineRunner {
// Initializing Logger instance private static final Logger logger = LoggerFactory.getLogger(MyRunner.class);
// Autowiring UserRepository instance @Autowired private UserRepository userRepository;
// Overriding run() method @Override public void run(String... args) throws Exception { // Creating QUser instance var qUser = QUser.user;
// Creating and saving initial user User initialUser = new User(null, "John Doe", 30); initialUser = userRepository.save(initialUser); // Logging initial user insertion logger.info("Initial user inserted: {}", initialUser);
// Generating and saving 25 sample users List<User> sampleUsers = generateSampleUsers(25); sampleUsers = (List<User>) userRepository.saveAll(sampleUsers); // Logging sample users insertion logger.info("25 sample users inserted: {}", sampleUsers);
// 查询年龄小于 29 岁、姓名以 "est "结尾的用户 List<User> users = (List<User>) userRepository.findAll( qUser.name.endsWith("est").and(qUser.age.lt(29)) ); // Logging users query result logger.info("Users with age less than 29 and name ending with 'est': {}", users);
// 查询年龄大于或等于 30 岁的用户 List<User> usersWithAgeAbove30 = (List<User>) userRepository.findAll( qUser.age.goe(30) ); // Logging users query result logger.info("Users with age greater than or equal to 30: {}", usersWithAgeAbove30); }
// Method to generate sample users private List<User> generateSampleUsers(int count) { List<User> users = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < count; i++) { String name = "User" + (i + 1); int age = random.nextInt(100); // Random age between 0 and 99 users.add(new User(null, name, age)); } return users; } }
|
步骤 8:打开主类,输入以下代码。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
// QueryDslCrudApplication class with main method @SpringBootApplication public class QueryDslCrudApplication {
// Main method to run the application public static void main(String[] args) { // Running the application SpringApplication.run(QueryDslCrudApplication.class, args); }
}
|
第 9 步:完成 Spring 项目后,将应用程序作为 Spring 项目运行,然后在 8083 端口上运行,这时你会发现项目的输出,该项目可以生成示例用户,插入的数据可以显示输出。