我正在尝试在数据库中进行的查询中使用一个线程,该查询可以生成许多记录,我不知道是否有必要,但是当我尝试实现该线程时,它不返回该列表中的值(没有线程,它通常返回值)

我的控制器:在这里,我调用我的方法,该方法将具有我的DAO类数据库的以下列表:

public ObservableList<Requisicao> atualizarTabela() {
    RequisicaoDAO dao = new RequisicaoDAO();
    requisicoes = FXCollections.observableArrayList(dao.getList());
    return requisicoes;
}


我的方法DAO:

public class RequisicaoDAO {

    private Connection con;
    Alerts alerts = new Alerts();
    public RequisicaoDAO() {
        this.con = new ConnectionFactory().getConnection();
    }

    private static RequisicaoDAO aRequisicaoDAO;

    public static RequisicaoDAO getInstancia() {

        if (aRequisicaoDAO == null) {
            aRequisicaoDAO = new RequisicaoDAO();
        }

        return aRequisicaoDAO;
    }
   public List<Requisicao> getList() {
        List<Requisicao> requisicoes = new ArrayList<>();
        new Thread() {
        @Override
        public void run() {
        String sql = "SELECT * FROM equipamento_requisicao equipreq INNER JOIN equipamento_user equipuser ON (equipreq.idequipamento_user = equipuser.id_equipamento_do_usuario)  INNER JOIN usuario user ON (user.id_usuario=equipuser.idusuario) INNER JOIN equipamentos equip ON (equip.id_equipamentos = equipuser.idequipamentos) INNER JOIN detalhe_status dStatus ON (dStatus.idequipamento_requisicao= equipreq.id_equipamento_requisicao) INNER JOIN status_requisicao statusreq on (statusreq.id_status= dStatus.idstatus) INNER JOIN permissao p ON(user.idpermissao= p.id_permissao) INNER JOIN departamentos dp ON(user.iddepartamento = dp.id_departamentos) INNER JOIN chefe_departamento cp ON(dp.id_chefe = cp.id_chefe) where statusreq.categoria='Ativa' ";
        try {
            PreparedStatement stmt = con.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                Usuario usuario = new Usuario();
                usuario.setNome(rs.getString("user.nome"));
                usuario.setId(rs.getLong("user.id_usuario"));
                usuario.setMatricula(rs.getString("user.matricula"));
                // FIM TABELA USUARIO
                //equipamento // equipamento user tabelas
                Equipamentos equipamento = new Equipamentos();
                equipamento.setEquipamento_nome(rs.getString("equip.equipamento_nome"));
                equipamento.setSerial_equipamento(rs.getString("equipuser.serial_equipamento"));
                equipamento.setId_equipamento_do_Usuario(rs.getLong("equipreq.idequipamento_user"));
                //status tabela
                Status status = new Status();
                status.setCategoria(rs.getString("statusreq.categoria"));
                status.setIdstatus(rs.getInt("statusreq.id_status"));
                //status detalhes tabela
                Usuario usuarioStatus = new Usuario();//id do usuaro na tabela detalhes status
                usuarioStatus.setId(rs.getLong("dStatus.idusuario"));
                StatusDetalhes statusDetalhes = new StatusDetalhes();
                statusDetalhes.setId_statusdetalhes(rs.getLong("dStatus.id_statusdetalhes"));
                statusDetalhes.setData_status(rs.getTimestamp("dStatus.data"));
                statusDetalhes.setObservacao_status(rs.getString("dStatus.observacao"));
                statusDetalhes.setIdUsuario(usuarioStatus);
                statusDetalhes.setIdStatus(status);
                // Id da requisicao na tabela detalhes status
                Requisicao requisicaoStatus = new Requisicao();
                requisicaoStatus.setId(rs.getLong("dStatus.idequipamento_requisicao"));
                //requisicao tabela
                Requisicao req = new Requisicao();
                req.setId(rs.getLong("equipreq.id_equipamento_requisicao"));
                req.setNome(rs.getString("equipreq.nome"));
                req.setData_criada(rs.getTimestamp("equipreq.data_requisicao"));
                req.setMotivo(rs.getString("equipreq.observacao"));
                req.setReqEquipamento(equipamento);
                req.setReqStatus(status);
                req.setReqUsuario(usuario);
                req.setReqStatus_Detalhes(statusDetalhes);
                requisicoes.add(req);
            }
            stmt.close();
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(RequisicaoDAO.class.getName()).log(Level.SEVERE, null, ex);
        }

        }
        }.start();
        return requisicoes;
    }
}


不会产生任何错误,但是我的表视图中没有显示此列表
我认为问题出在退货单上。但是我解决不了。

最佳答案

问题是,在线程添加任何内容之前,您要返回requisicoes的值。

因为Thread是异步执行的,所以执行看起来像这样:

java - 在具有数据库数据的列表中使用线程-LMLPHP

因此,查询工作正常(当不使用线程时,您会看到正确的结果),但是由于将(空)列表已复制到新的可观察列表,因此添加了结果,因此将它们添加到列表中较晚。不再影响控制器中的可观察列表。

一种解决方案是在返回列表requisicoes之前等待线程的执行(通过调用线程的join method。但这会导致方法getList()花费很多时间(因为它正在等待线程),这可能是您想通过使用线程避免的。

另一个(可能更好)的解决方案是从方法getList()中删除​​多线程,并使用Task将多线程添加到您的控制器中。

解决方案如下所示:

public ObservableList<Requisicao> atualizarTabela() {
    RequisicaoDAO dao = new RequisicaoDAO();
    //create an empty list first
    requisicoes = FXCollections.observableArrayList();
    //execute the query in the task
    Task<List<Requisicao>> task = new Task<List<Requisicao>>() {

        @Override
        protected List<Requisicao> call() throws Exception {
            //getList has no thread anymore
            return dao.getList();
        }

    };
    //add the list values to the observable list, when the task succeeds
    task.setOnSucceeded(e -> requisicoes.addAll(task.getValue()));
    task.setOnFailed(e -> System.out.println("Task failed"));//better do some execption handling here...

    //start the task in a new thread
    Thread executor = new Thread(task, "get_list_task_thread");
    executor.start();

    //return the (empty) list, which will be filled when the task (that includes the query) has finished
    return requisicoes;
}


如果您以这种方式更改代码(并从方法getList()中删除​​线程,则它应该首先返回一个空的ObservableList,该空值在任务(包括查询)完成后显示并填充。即,它不会在执行查询时停止FX-Thread的执行,因此UI不会停止。

关于java - 在具有数据库数据的列表中使用线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57033066/

10-12 00:34
查看更多