加入两个表并作为一条记录发送

时间:2016-05-25 20:18:58

标签: java rest javafx fxml

假设我们有这样的表:

表用户

iduser | password

表标记

id | iduser | mark | idtest

表格测试

idtest | title

查询如下所示:

@GET
@Path("/{id}/marks")
@Produces(MediaType.APPLICATION_JSON)
public Object funkcja(@PathParam("id") Integer iduser) {
    Query query = em.createQuery("select m,t from Marks m, Tests t where m.idusers=:iduser and m.idtest = t.idtests");
    query.setParameter("iduser", id);
    List<Object> results = (List<Object>)query.getResultList();
    return results;
}

我有实体类: 标记用户测试

我要做什么才能在Web服务上连接表和发送JSON类型以及如何将JSON转换为实体类,因为我想在TableView中显示。 也许还有其他简单的方法吗? 也许地图 JsonObject

1 个答案:

答案 0 :(得分:0)

你似乎有多个问题;我认为你需要把它们分解成单独的问题。

对于“主要”问题,即关于JPA以及如何加入实体,我会在实体级别而不是在查询级别执行此操作。即我想我会有实体类,如:

import java.util.Objects;

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

@Entity
@Table(name="Tests")
public class Test {

    @Id
    @Column(name="idtest")
    private int id ;
    private String title ;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof Test) {
            return Objects.equals(title, ((Test)other).title);
        } else return false ;
    }

    @Override
    public int hashCode() {
        return Objects.hash(title);
    }
}

然后Mark实体可以使用@ManyToOne注释来引用实际的Test对象(而不是其ID):

import java.util.Objects;

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

@Entity
@Table(name="Marks")
public class Mark {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id ;

    @ManyToOne
    @JoinColumn(name="idtest")
    private Test test ;

    // You probably don't want a reference to User here, as the User class
    // encapsulates the password, which you don't want to throw back and
    // forward across the network unnecessarily. But if the User class 
    // instead had a user name etc you wanted, you could use the same
    // @ManyToOne technique to reference a User object here if you needed.
    @Column(name="iduser")
    private int userId ;

    private int mark ;

    public int getId() {
        return id;
    }

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

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public Test getTest() {
        return test;
    }

    public void setTest(Test test) {
        this.test = test;
    }

    public int getMark() {
        return mark;
    }

    public void setMark(int mark) {
        this.mark = mark;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Mark) {
            Mark other = (Mark)obj ;
            return Objects.equals(userId, other.userId)
                && Objects.equals(test, other.test)
                && mark == other.mark ;
        } else return false ;
    }

    @Override
    public int hashCode() {
        return Objects.hash(userId, test, mark);
    }
}

现在您的查询看起来像

TypedQuery<Mark> query = em.createQuery("select m from Mark m where m.userId=:userid");
query.setParameter("userid", iduser);
List<Mark> results = query.getResultList();

并且列表中的Mark个实例已经拥有了您需要的所有数据:

for (Mark mark : results) {
    System.out.println(mark.getTest().getTitle() + ": " + mark.getMark());
}

其余问题:

假设您使用JAX-RS实现(例如Jersey)设置了服务器,您显示的代码片段(使用新查询修改)应该生成JSON输出。 (您可以使用Firefox REST客户端等开发人员工具通过指定相应的URL和请求标头以及查看响应来查看JSON输出。)

在客户端(JavaFX)方面,您可以使用Jersey的客户端库(或者可能是Apache HttpComponent库)轻松创建Web请求,并使用GSON或Jackson等库来映射您返回Java对象的JSON内容在TableView中显示。

如果你遇到困难,我建议你尝试这个并询问有关其余部分的具体问题。