Java 如何为外部联接表字段编写@OrderBy注释,以使用SQL对集合进行排序

Java 如何为外部联接表字段编写@OrderBy注释,以使用SQL对集合进行排序,java,hibernate,annotations,Java,Hibernate,Annotations,有三张桌子。“relatedCameraSet”的变量需要使用SQL按“camera.name”排序,但“camera.name”字段不在“RelatedCamera”的表中,在“camera”的外部联接表中。@OrderBy的以下注释无效 @Entity @Table(name = "MICRO_MAP") public class MicroMap { //main table @Id @GeneratedValue(strategy = GenerationType.AUT

有三张桌子。“relatedCameraSet”的变量需要使用SQL按“camera.name”排序,但“camera.name”字段不在“RelatedCamera”的表中,在“camera”的外部联接表中。@OrderBy的以下注释无效

@Entity
@Table(name = "MICRO_MAP")
public class MicroMap { //main table
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", length = 32, nullable = false)
    private String name;

    @OneToMany(mappedBy="mapId",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @OrderBy("camera.name") //OrderBy the field of "name" in Camera table 
    private Set<RelatedCamera> relatedCameraSet;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<RelatedCamera> getRelatedCameraSet() {
        return relatedCameraSet;
    }

    public void setRelatedCameraSet(Set<RelatedCamera> relatedCameraSet) {
        this.relatedCameraSet = relatedCameraSet;
    }    
}

@Entity
@Table(name = "RELATED_CAMERA")
public class RelatedCamera {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "MAP_ID")
    private String mapId;

    @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name = "CAMERA_ID", referencedColumnName="id",nullable = true)
    private Camera camera;

    public Long getId() {
        return id;
    }

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

    public String getMapId() {
        return mapId;
    }

    public void setMapId(String mapId) {
        this.mapId = mapId;
    }

    public Camera getCamera() {
        return camera;
    }

    public void setCamera(Camera camera) {
        this.camera = camera;
    }    
}

@Entity
@Table(name = "CAMERA")
public class Camera {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }   
}
@实体
@表(name=“MICRO_MAP”)
公共类微地图{//主表
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“ID”)
私人长id;
@列(name=“name”,长度=32,可空=false)
私有字符串名称;
@OneToMany(mappedBy=“mapId”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@OrderBy(“camera.name”)//OrderBy摄像机表中“name”字段
专用集相关摄影机集;
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共集getRelatedCameraSet(){
返回相关摄像机集;
}
public void setRelatedCameraSet(Set relatedCameraSet){
this.relatedCameraSet=relatedCameraSet;
}    
}
@实体
@表(name=“相关摄像机”)
公共类相关摄像机{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“ID”)
私人长id;
@列(name=“MAP\u ID”)
私有字符串mapId;
@manytone(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinColumn(name=“CAMERA\u ID”,referencedColumnName=“ID”,nullable=true)
私人摄像机;
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getMapId(){
返回mapId;
}
公共void setMapId(字符串mapId){
this.mapId=mapId;
}
公共摄像机{
返回摄像机;
}
公共摄像机(摄像机){
这个。照相机=照相机;
}    
}
@实体
@表(name=“摄像头”)
公共级摄像机{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“ID”)
私人长id;
@列(name=“name”)
私有字符串名称;
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}   
}
如何编写@OrderBy注释,以便使用SQL按相机名称对集合进行排序


非常感谢

我研究了您的问题,从API文档中发现:

属性或字段名必须与关联类或其中嵌入类的持久属性或字段名相对应

这就是为什么仅仅通过OrderBy是不可能的,您只能通过MicroMap类中的camera_id列进行订购

您可以通过@Sort和实现Compariable接口或指定比较器来实现:


现在我意识到@OrderBy不可能做到这一点,我认为通过实现可比接口或指定比较器来实现这一点是没有效率的,因为完成这项工作需要两个步骤,第一步是从数据库查询,第二步是在内存中排序。仅通过SQL对集合进行排序是非常有效的

为了获得高效率,我必须将MicroMap的级别更改如下:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "MICRO_MAP")
public class MicroMap {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME", length = 32, nullable = false)
    private String name;

//    @OneToMany(mappedBy="mapId",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
//    @OrderBy("camera.name") //OrderBy the field of "name" in Camera table, But JPA doesn't support
//    private Set<RelatedCamera> relatedCameraSet;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
import javax.persistence.Column;
导入javax.persistence.Entity;
导入javax.persistence.GeneratedValue;
导入javax.persistence.GenerationType;
导入javax.persistence.Id;
导入javax.persistence.Table;
@实体
@表(name=“MICRO_MAP”)
公共类微地图{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“ID”)
私人长id;
@列(name=“name”,长度=32,可空=false)
私有字符串名称;
//@OneToMany(mappedBy=“mapId”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
//@OrderBy(“camera.name”)//OrderBy在camera表中的“name”字段,但JPA不支持
//专用集相关摄影机集;
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
并在DAO或服务类中添加一个方法

public List<RelatedCamera> getRelatedCamera(Long mapId) {
    Session session = sessionFactory.getCurrentSession();
    List<RelatedCamera> list = session.createQuery(" from RelatedCamera where mapId="+mapId+" order by camera.name").list();
    return list;
}
公共列表getRelatedCamera(长mapId){
Session Session=sessionFactory.getCurrentSession();
List List=session.createQuery(“from RelatedCamera where mapId=“+mapId+”order by camera.name”).List();
退货清单;
}

第一个答案似乎是你想要的,祝你好运:)对不起,我的问题与你的完全不同。在这种情况下,主表中要排序的字段。在我的例子中,外部联接表中要排序的字段。是否有可能仅通过SQL对集合进行排序,而不是通过传递比较器实现可比接口?我猜不可能仅通过SQL实现,您已经在RelatedCamera类中实现了可比接口…现在我认为这是Hibernate中的一个错误,因为在“from RelatedCamera,其中mapId=1 order by camera.name”的HQL中使用“camera.name”是可以的,而在@OrderBy annotation中使用“camera.name”是不可以的。非常感谢您为我做的研究。是的,你是对的。@luckysohu不客气!你能接受我的回答作为解决方案吗,谢谢!