查询spring数据JPA中的语法问题

时间:2017-10-09 11:48:34

标签: java spring spring-boot spring-data-jpa

我正在尝试使用spring数据JPA实现一对多关联, 我的模型类Users.java是,

@Entity
@Table(name = "users")
public class Users implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
public String username;
public String password;
public Integer privid;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "pid")
private Collection<Privillages> priviJoin;

public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}
@Column(name = "username")
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
@Column(name = "password")
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}

@Column(name = "privid")
public Integer getPrivid() {
    return privid;
}
public void setPrivid(Integer privid) {
    this.privid = privid;
}

public Collection<Privillages> getPriviJoin() {
    return priviJoin;
}
public void setPriviJoin(Privillages priviJoin) {
    this.priviJoin = (Collection<Privillages>) priviJoin;
}

public Users() {
}
@Override
public String toString() {
    return String.format("Users[id=%d, username='%s', password='%s']", id, 
username, password);
}
}

Privillages.java是,

@Entity
@Table(name = "privillages")
public class Privillages implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer id;

public String pname;


@ManyToOne(optional = false)
@JoinColumn(name = "pid", referencedColumnName = "privid")
public Users pid;

public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}

@Column(name = "pname")
public String getPname() {
    return pname;
}
public void setPname(String pname) {
    this.pname = pname;
}

@Column(name = "pid")
public Users getPid() {
    return pid;
}
public void setPid(Users pid) {
    this.pid = pid;
}

public Privillages(){
} 
}

我的观点是,

<div th:each= "user: ${joinData}">

        <span th:text="${user.pname}">
        </span>
        <span th:text="${user.username}">
        </span>
    </div>

我需要从用户获取用户名,从Privillages获取pname。通过组合我需要显示。现在我在我的存储库中使用下面的查询,即

@Query("select u from Users ug inner join ug.priviJoin u")
List<Users> findByUsername();

我需要从另一个表中选择一个用户名和pname,如上所述。我需要如何更改查询?

2 个答案:

答案 0 :(得分:3)

您遇到此问题有两个原因。

  1. JPQL查询无效。
  2. 您尚未在基础JPQL查询可以使用的实体之间创建关联。
  3. 在JPQL中执行连接时,必须确保存在尝试连接的实体之间的基础关联。在您的示例中,您缺少Users和Privillages实体之间的关联。为了创建此关联,我们必须在Users类中添加Privillages字段并建立适当的JPA Mapping。我已在下面附上了用户的来源。

    <强> Users.java

     @Entity
            @Table(name = "users")
            public class Users implements Serializable{
    
            @Id
            @GeneratedValue(strategy = GenerationType.AUTO)
            private Integer id;
            public String username;
            public String password;
            public Integer privid;
    
            @OneToMany(cascade = CascadeType.ALL, mappedBy = "pid")
            private Collection<Privillages> priviJoin;
    
            public Integer getId() {
                return id;
            }
            public void setId(Integer id) {
                this.id = id;
            }
    
            @OneToOne()
            @JoinColumn(name="pname")
            private Privillages privillages;
    
            @Column(name = "username")
            public String getUsername() {
                return username;
            }
            public void setUsername(String username) {
                this.username = username;
            }
            @Column(name = "password")
            public String getPassword() {
                return password;
            }
            public void setPassword(String password) {
                this.password = password;
            }
    
            @Column(name = "privid")
            public Integer getPrivid() {
                return privid;
            }
            public void setPrivid(Integer privid) {
                this.privid = privid;
            }
    
            public Collection<Privillages> getPriviJoin() {
                return priviJoin;
            }
            public void setPriviJoin(Privillages priviJoin) {
                this.priviJoin = (Collection<Privillages>) priviJoin;
            }
    
            public Users() {
            }
            @Override
            public String toString() {
                return String.format("Users[id=%d, username='%s', password='%s']", id, 
            username, password);
            }
            /**
             * @return the pvs
             */
            public Privillages getPvs() {
                return pvs;
            }
            /**
             * @param pvs the pvs to set
             */
            public void setPvs(Privillages pvs) {
                this.pvs = pvs;
            }
        }
    

    <强> Privillages.java

    @Entity
    @Table(name = "privillages")
    public class Privillages implements Serializable {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer id;
    @Column(name="pname")
    public String pname;
    
    
    @ManyToOne(optional = false)
    @JoinColumn(name = "pid", referencedColumnName = "privid")
    public Users pid;
    
    public Integer getId() {
        return id;
    }
    
    
    @OneToOne(fetch=FetchType.LAZY, mappedBy="privillages")
    private Users user;
    
    public void setId(Integer id) {
        this.id = id;
    }
    
    @Column(name = "pname")
    public String getPname() {
        return pname;
    }
    public void setPname(String pname) {
        this.pname = pname;
    }
    
    @Column(name = "pid")
    public Users getPid() {
        return pid;
    }
    public void setPid(Users pid) {
        this.pid = pid;
    }
    
    public Privillages(){
    } 
    }
    

    <强>查询:

    @Query("select u.username from users u inner join u.privillages pr where pr.pname = :pname")
    

答案 1 :(得分:0)

首先,您必须选择是否将注释放在字段或设置器上。规范要求只采用一种方式。

您可以省略@Column注释,有默认值,所以现在让我们保留它:

@Entity
@Table(name = "users")
public class Users implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    public String username;
    public String password;
    public Integer privid;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "pid")
    private Collection<Privillages> privilages;

    //getters setters
}

@Entity
@Table(name = "privillages")
public class Privillages implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Integer id;

    public String pname;


    @ManyToOne(optional = false)
    public Users pid;

}

现在您可以创建以下存储库:

public interface UserRepository extends JpaRepository<User, Integer> {

    List<User> findAllByUsername(String username);
}

方法findAllByUsername将返回具有特定用户名的用户列表。

如果您想坚持@Query,请记住,@Table注释不会更改@Entity名称,因此在您的查询中,引用{ {1}},而不是User