У меня проблема с получением следующего сценария для работы.Студент может сдавать тесты.Студент со временем прошел несколько тестов и получил оценку за каждый тест.У каждого студента есть список тестов, которые они выполнили, отображенные как @OneToMany
Теперь я хочу выбрать всех студентов, которые прошли тестирование по ряду сгруппированных критериев.Я хочу, например, найти всех студентов, которые имеют:
Группа 1: завершила «Тест 1» и получила оценку «от 75 до 100»
и /или
Группа 2: завершила «Тест 2» и получила оценку «от 50 до 80»
Это то, что у меня есть, но оно не выполняетМне нужно (не могу выполнить поиск по нескольким параметрам, что означает, что я должен выполнить запрос несколько раз):
SELECT s FROM Student s JOIN s.tests t WHERE t.score BETWEEN :minScore AND :maxScore AND t.testName = :testName
Есть ли способ использовать один NamedQuery для достижения того, что я хочу?Чтобы найти всех учащихся, которые прошли тест, который соответствует хотя бы одной из групп параметров выше?Я экспериментировал с соединениями, но продолжаю врезаться в стену.
Я сделал пример скелета кода ниже, чтобы проиллюстрировать, что я пытаюсь сделать.
@Entity
@NamedQueries({
@NamedQuery(name="Student.findStudentByParams", query="????????") // What should this query look like to satisfy the criteria? (see below for more detail)
})
public class Student {
// .. Some other variables that are not relevant for this example
@Id
private String name;
@OneToMany(fetch=FetchType.EAGER, mappedBy = "student")
private List<Test> tests;
// Setters and getters
}
@Entity
public class Test {
private double score;
private String testName;
// .. Some other variables that are not relevant for this example
@ManyToOne(cascade=CascadeType.ALL)
private Student student;
// Setters and getters
}
public class SearchParameters {
private double minScore;
private double maxScore;
private String testName;
public SearchParameters(String minScore, String maxScore, String testName) {
this.minScore = minScore;
this.maxScore = maxScore;
this.testName = testName;
}
// Setters and getters
}
public class MainClass {
public static List<Student> getStudents(List<SearchParameters> searchParams) {
// Database initialization stuff
// What should the query look like to find all students that match any of the combined requirements in the searchParams list?
// Is it possible to do in a single query or should i make multiple ones?
// What parameters should i set? Is it possible to put in the entire array and do some sort of join?
// Retrieve all students which matches any of these search parameters:
// Have either:
// Completed "Test 1" and got a score between 75 and 100
// and/or:
// Completed "Test 2" and got a score between 50 and 80
Query namedQuery = em.createNamedQuery("Student.findStudentByParams");
namedQuery.setParameter(??);
return (List<Student>)namedQuery.getResultList();
}
public static void main() {
List<SearchParams> searchParams = new ArrayList<SearchParams();
searchParams.add(new SearchParameters(75,100, "Test 1"));
searchParams.add(new SearchParameters(50,80, "Test 2"));
// Retrieve all students which matches any of these search parameters:
// Have either:
// Completed "Test 1" and got a score between 75 and 100
// and/or:
// Completed "Test 2" and got a score between 50 and 80
ArrayList<Student> students = getStudents(searchParams);
for(Student s: students) // Print all user that match the criteria
{
System.out.println("Name: " + s.getName());
}
}
}