首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JPQL非连接查询

问JPQL非连接查询
EN

Stack Overflow用户
提问于 2014-01-29 18:33:21
回答 2查看 82关注 0票数 0

我使用的是EclipseLink和MySQL。我正在尝试从Room实体中检索一个值,而不是加入它。

以下是我在计划实体上的NamedQuery:

代码语言:javascript
复制
@NamedQuery(name = "Schedule.findUnusedRoomForCourseLectureOnly",
query = "SELECT r FROM Schedule s, Room r WHERE s.day = :sday AND (:stime NOT BETWEEN s.startTime AND s.endTime) AND r.id <> s.room.id")

我从我的JPA控制器得到一个空值。

下面是控制程序的代码:

代码语言:javascript
复制
    public Room findUnusedRoomForCourseLectureOnly(int day, Calendar startTime) {
        EntityManager em = getEntityManager();
        Query q = em.createNamedQuery("Schedule.findUnusedRoomForCourseLectureOnly")

                .setParameter("sday", day)
                .setParameter("stime", startTime);
        q.setMaxResults(1);
        try {
            return (Room) q.getResultList().get(0);
        } catch (IndexOutOfBoundsException e) {
            return null;
        } finally {
            em.close();
        }
    }

下面是我的计划实体:

代码语言:javascript
复制
@Entity    
public class Schedule implements Serializable, Comparable<Schedule> {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "scheduledDay")
    private int day;
    @Temporal(javax.persistence.TemporalType.TIME)
    private Calendar startTime; // 24 hr format
    @Temporal(javax.persistence.TemporalType.TIME)
    private Calendar endTime; // 24 hr format

    @ManyToOne
    private Faculty faculty;

    @ManyToOne
    private Room room;

    @ManyToOne
    private Subject subject;

    private boolean lab;

    @ManyToOne
    private Section section;

    public Schedule() {
        this.startTime = Calendar.getInstance();
        this.endTime = Calendar.getInstance();
    }

    public Schedule(int day, Calendar startTime, Calendar endTime, Faculty faculty, Room room, Subject subject, boolean lab, Section section) {
        this.day = day;
        this.startTime = startTime;
        this.endTime = endTime;
        this.faculty = faculty;
        this.room = room;
        this.subject = subject;
        this.lab = lab;
        this.section = section;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public Calendar getStartTime() {
        return startTime;
    }

    public final void setStartTime(int hour) {
        this.startTime.set(Calendar.HOUR_OF_DAY, hour);
        this.startTime.set(Calendar.MINUTE, 0);
        this.startTime.set(Calendar.SECOND, 0);
    }

    public Calendar getEndTime() {
        return endTime;
    }

    public final void setEndTime(int hour) {
        this.endTime.set(Calendar.HOUR_OF_DAY, hour);
        this.endTime.set(Calendar.MINUTE, 0);
        this.endTime.set(Calendar.SECOND, 0);
    }

    public Faculty getFaculty() {
        return faculty;
    }

    public void setFaculty(Faculty faculty) {
        this.faculty = faculty;
    }

    public Room getRoom() {
        return room;
    }

    public void setRoom(Room room) {
        this.room = room;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public Section getSection() {
        return section;
    }

    public void setSection(Section section) {
        this.section = section;
    }

    public boolean isLab() {
        return lab;
    }

    public void setLab(boolean lab) {
        this.lab = lab;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Schedule)) {
            return false;
        }
        Schedule other = (Schedule) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ph.edu.bulsusc.planner.entity.Schedule[ id=" + id + " ]";
    }

    @Override
    public int compareTo(Schedule schedule) {
        // return
        // -1 ahead
        // 0 overlapping
        // 1 behind
//        int timeComparison = compareTime(schedule);
//        boolean isTimeConflict = timeComparison == 0;
//
//        if (this.room.getId() == schedule.getRoom().getId() && !isTimeConflict) {
//            // if they have same room and time is not conflict
//            return timeComparison;
//        } else {
//            // same room; time conflict
//            return 0;
//        }
        throw new UnsupportedOperationException("Not implemented yet.");
    }

//    private int compareTime(Schedule schedule) {
//        if (this.day.compareTo(schedule.getDay()) < 0) { // ahead/before of scheduled day
//            return -1;
//        } else if (this.day.compareTo(schedule.getDay()) == 0) { // overlapping day
//            if (this.endTime.get(Calendar.HOUR_OF_DAY) < schedule.getStartTime().get(Calendar.HOUR_OF_DAY)) {
//                return -1;
//            } else if (this.startTime.get(Calendar.HOUR_OF_DAY) > schedule.getEndTime().get(Calendar.HOUR_OF_DAY)) {
//                return 1;
//            } else {
//                return 0;
//            }
//        } else { // behind/after of scheduled day
//            return 1;
//        }
//    }

}

下面是我的Room实体:

代码语言:javascript
复制
@Entity
public class Room implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String number;
    private boolean lab;
    @OneToMany
    private List<Course> prioritizedCourses;
    @OneToMany
    private List<Subject> prioritizedSubjects;

    public Room() {
    }

    public Room(String number, boolean lab) {
        this.number = number;
        this.lab = lab;
    }

    public Room(String number, boolean lab, List<Course> prioritizedCourses, List<Subject> prioritizedSubjects) {
        this.number = number;
        this.lab = lab;
        this.prioritizedCourses = prioritizedCourses;
        this.prioritizedSubjects = prioritizedSubjects;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public boolean isLab() {
        return lab;
    }

    public void setLab(boolean lab) {
        this.lab = lab;
    }

    public List<Course> getPrioritizedCourses() {
        return prioritizedCourses;
    }

    public void setPrioritizedCourses(List<Course> prioritizedCourses) {
        this.prioritizedCourses = prioritizedCourses;
    }

    public List<Subject> getPrioritizedSubjects() {
        return prioritizedSubjects;
    }

    public void setPrioritizedSubjects(List<Subject> prioritizedSubjects) {
        this.prioritizedSubjects = prioritizedSubjects;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

//    public List<Schedule> getSchedules() {
//        return schedules;
//    }
//
//    /**
//     * Rewrites schedule with this method
//     * @param schedules
//     */
//    public void setSchedules(List<Schedule> schedules) {
//        this.schedules = schedules;
//    }
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Room)) {
            return false;
        }
        Room other = (Room) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ph.edu.bulsusc.planner.entity.Room[ id=" + id + " ]";
    }

}

我做错了吗?

EN

回答 2

Stack Overflow用户

发布于 2014-01-29 22:15:15

"r.id <> s.room.id“子句的问题是,使用"s.room.id”会导致时间表和房间之间的内部联接。您可能会尝试使用"r <> s.room“来避免连接,但我认为它不会对您想要的东西有所帮助。该查询将在同一查询中取消Room和Schedule的连接,从而导致笛卡尔连接-返回调度中的N行乘以调度中的M行,然后过滤出与r.id <> s.room.id子句匹配的几行。因此,如果您有多个时间表,所有房间都将被退还。

您可能希望在子查询的顶部使用not exist。类似于:

代码语言:javascript
复制
"SELECT r FROM Room r WHERE not exists (SELECT s from Schedule s where :stime NOT BETWEEN s.startTime AND s.endTime) AND r = s.room))"
票数 1
EN

Stack Overflow用户

发布于 2014-01-29 21:34:14

代码语言:javascript
复制
"SELECT r FROM Room r WHERE r.id NOT IN (SELECT s.room.id FROM Schedule s WHERE s.day = :sday AND (:stime BETWEEN s.startTime AND s.endTime))"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21428357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档